LibreOffice Module scaddins (master) 1
financial.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "analysisdefs.hxx"
21#include "analysis.hxx"
22#include "analysishelper.hxx"
23#include <o3tl/temporary.hxx>
24
25using namespace sca::analysis;
26
27double SAL_CALL AnalysisAddIn::getAmordegrc( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
28 double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal,
29 double fPer, double fRate, const css::uno::Any& rOB )
30{
31 if( nDate > nFirstPer || fRate <= 0.0 || fRestVal > fCost ||
32 fCost <= 0.0 || fRestVal < 0 || fPer < 0 )
33 throw css::lang::IllegalArgumentException();
34
35 double fRet = GetAmordegrc( GetNullDate( xOpt ), fCost, nDate, nFirstPer, fRestVal, fPer, fRate, getDateMode( xOpt, rOB ) );
36 return finiteOrThrow( fRet );
37}
38
39
40double SAL_CALL AnalysisAddIn::getAmorlinc( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
41 double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal,
42 double fPer, double fRate, const css::uno::Any& rOB )
43{
44 if ( nDate > nFirstPer || fRate <= 0.0 || fRestVal > fCost ||
45 fCost <= 0.0 || fRestVal < 0 || fPer < 0 )
46 throw css::lang::IllegalArgumentException();
47
48 double fRet = GetAmorlinc( GetNullDate( xOpt ), fCost, nDate, nFirstPer, fRestVal, fPer, fRate, getDateMode( xOpt, rOB ) );
49 return finiteOrThrow( fRet );
50}
51
52
53double SAL_CALL AnalysisAddIn::getAccrint( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
54 sal_Int32 nIssue, sal_Int32 /*nFirstInter*/, sal_Int32 nSettle, double fRate,
55 const css::uno::Any &rVal, sal_Int32 nFreq, const css::uno::Any& rOB )
56{
57 double fVal = aAnyConv.getDouble( xOpt, rVal, 1000.0 );
58
59 if( fRate <= 0.0 || fVal <= 0.0 || isFreqInvalid(nFreq) || nIssue >= nSettle)
60 throw css::lang::IllegalArgumentException();
61
62 double fRet = fVal * fRate * GetYearDiff( GetNullDate( xOpt ), nIssue, nSettle, getDateMode( xOpt, rOB ) );
63 return finiteOrThrow( fRet );
64}
65
66
67double SAL_CALL AnalysisAddIn::getAccrintm( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
68 sal_Int32 nIssue, sal_Int32 nSettle, double fRate, const css::uno::Any& rVal, const css::uno::Any& rOB )
69{
70 double fVal = aAnyConv.getDouble( xOpt, rVal, 1000.0 );
71
72 if( fRate <= 0.0 || fVal <= 0.0 || nIssue >= nSettle )
73 throw css::lang::IllegalArgumentException();
74
75 double fRet = fVal * fRate * GetYearDiff( GetNullDate( xOpt ), nIssue, nSettle, getDateMode( xOpt, rOB ) );
76 return finiteOrThrow( fRet );
77}
78
79
80double SAL_CALL AnalysisAddIn::getReceived( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
81 sal_Int32 nSettle, sal_Int32 nMat, double fInvest, double fDisc, const css::uno::Any& rOB )
82{
83 if( fInvest <= 0.0 || fDisc <= 0.0 || nSettle >= nMat )
84 throw css::lang::IllegalArgumentException();
85
86 double fRet = fInvest / ( 1.0 - ( fDisc * GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) ) ) );
87 return finiteOrThrow( fRet );
88}
89
90
91double SAL_CALL AnalysisAddIn::getDisc( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
92 sal_Int32 nSettle, sal_Int32 nMat, double fPrice, double fRedemp, const css::uno::Any& rOB )
93{
94 if( fPrice <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
95 throw css::lang::IllegalArgumentException();
96 double fRet = ( 1.0 - fPrice / fRedemp ) / GetYearFrac( xOpt, nSettle, nMat, getDateMode( xOpt, rOB ) );
97 return finiteOrThrow( fRet );
98}
99
100
101double SAL_CALL AnalysisAddIn::getDuration( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
102 sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fYield, sal_Int32 nFreq, const css::uno::Any& rOB )
103{
104 if( fCoup < 0.0 || fYield < 0.0 || isFreqInvalid(nFreq) || nSettle >= nMat )
105 throw css::lang::IllegalArgumentException();
106
107 double fRet = GetDuration( GetNullDate( xOpt ), nSettle, nMat, fCoup, fYield, nFreq, getDateMode( xOpt, rOB ) );
108 return finiteOrThrow( fRet );
109}
110
111
112double SAL_CALL AnalysisAddIn::getEffect( double fNominal, sal_Int32 nPeriods )
113{
114 if( nPeriods < 1 || fNominal <= 0.0 )
115 throw css::lang::IllegalArgumentException();
116
117 double fPeriods = nPeriods;
118
119 double fRet = pow( 1.0 + fNominal / fPeriods, fPeriods ) - 1.0;
120 return finiteOrThrow( fRet );
121}
122
123
124double SAL_CALL AnalysisAddIn::getCumprinc( double fRate, sal_Int32 nNumPeriods, double fVal,
125 sal_Int32 nStartPer, sal_Int32 nEndPer, sal_Int32 nPayType )
126{
127 double fPmt, fPpmt;
128
129 if( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0.0 || nEndPer > nNumPeriods ||
130 fVal <= 0.0 || ( nPayType != 0 && nPayType != 1 ) )
131 throw css::lang::IllegalArgumentException();
132
133 fPmt = GetPmt( fRate, nNumPeriods, fVal, 0.0, nPayType );
134
135 fPpmt = 0.0;
136
137 sal_uInt32 nStart = sal_uInt32( nStartPer );
138 sal_uInt32 nEnd = sal_uInt32( nEndPer );
139
140 if( nStart == 1 )
141 {
142 if( nPayType <= 0 )
143 fPpmt = fPmt + fVal * fRate;
144 else
145 fPpmt = fPmt;
146
147 nStart++;
148 }
149
150 for( sal_uInt32 i = nStart ; i <= nEnd ; i++ )
151 {
152 if( nPayType > 0 )
153 fPpmt += fPmt - ( GetFv( fRate, double( i - 2 ), fPmt, fVal, 1 ) - fPmt ) * fRate;
154 else
155 fPpmt += fPmt - GetFv( fRate, double( i - 1 ), fPmt, fVal, 0 ) * fRate;
156 }
157
158 return finiteOrThrow( fPpmt );
159}
160
161
162double SAL_CALL AnalysisAddIn::getCumipmt( double fRate, sal_Int32 nNumPeriods, double fVal,
163 sal_Int32 nStartPer, sal_Int32 nEndPer, sal_Int32 nPayType )
164{
165 double fPmt, fIpmt;
166
167 if( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0.0 || nEndPer > nNumPeriods ||
168 fVal <= 0.0 || ( nPayType != 0 && nPayType != 1 ) )
169 throw css::lang::IllegalArgumentException();
170
171 fPmt = GetPmt( fRate, nNumPeriods, fVal, 0.0, nPayType );
172
173 fIpmt = 0.0;
174
175 sal_uInt32 nStart = sal_uInt32( nStartPer );
176 sal_uInt32 nEnd = sal_uInt32( nEndPer );
177
178 if( nStart == 1 )
179 {
180 if( nPayType <= 0 )
181 fIpmt = -fVal;
182
183 nStart++;
184 }
185
186 for( sal_uInt32 i = nStart ; i <= nEnd ; i++ )
187 {
188 if( nPayType > 0 )
189 fIpmt += GetFv( fRate, double( i - 2 ), fPmt, fVal, 1 ) - fPmt;
190 else
191 fIpmt += GetFv( fRate, double( i - 1 ), fPmt, fVal, 0 );
192 }
193
194 fIpmt *= fRate;
195
196 return finiteOrThrow( fIpmt );
197}
198
199
200double SAL_CALL AnalysisAddIn::getPrice( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
201 sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield, double fRedemp, sal_Int32 nFreq,
202 const css::uno::Any& rOB )
203{
204 if( fYield < 0.0 || fRate < 0.0 || fRedemp <= 0.0 || isFreqInvalid(nFreq) || nSettle >= nMat )
205 throw css::lang::IllegalArgumentException();
206
207 double fRet = getPrice_( GetNullDate( xOpt ), nSettle, nMat, fRate, fYield, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
208 return finiteOrThrow( fRet );
209}
210
211
212double SAL_CALL AnalysisAddIn::getPricedisc( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
213 sal_Int32 nSettle, sal_Int32 nMat, double fDisc, double fRedemp, const css::uno::Any& rOB )
214{
215 if( fDisc <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
216 throw css::lang::IllegalArgumentException();
217
218 double fRet = fRedemp * ( 1.0 - fDisc * GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) ) );
219 return finiteOrThrow( fRet );
220}
221
222
223double SAL_CALL AnalysisAddIn::getPricemat( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
224 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, double fRate, double fYield, const css::uno::Any& rOB )
225{
226 if( fRate < 0.0 || fYield < 0.0 || nSettle >= nMat )
227 throw css::lang::IllegalArgumentException();
228
229 sal_Int32 nNullDate = GetNullDate( xOpt );
230 sal_Int32 nBase = getDateMode( xOpt, rOB );
231
232 double fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
233 double fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
234 double fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
235
236 double fRet = 1.0 + fIssMat * fRate;
237 fRet /= 1.0 + fSetMat * fYield;
238 fRet -= fIssSet * fRate;
239 fRet *= 100.0;
240
241 return finiteOrThrow( fRet );
242}
243
244
245double SAL_CALL AnalysisAddIn::getMduration( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
246 sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fYield, sal_Int32 nFreq, const css::uno::Any& rOB )
247{
248 if( fCoup < 0.0 || fYield < 0.0 || isFreqInvalid(nFreq) )
249 throw css::lang::IllegalArgumentException();
250
251 double fRet = GetDuration( GetNullDate( xOpt ), nSettle, nMat, fCoup, fYield, nFreq, getDateMode( xOpt, rOB ) );
252 fRet /= 1.0 + ( fYield / double( nFreq ) );
253 return finiteOrThrow( fRet );
254}
255
256
257double SAL_CALL AnalysisAddIn::getNominal( double fRate, sal_Int32 nPeriods )
258{
259 if( fRate <= 0.0 || nPeriods < 0 )
260 throw css::lang::IllegalArgumentException();
261
262 double fPeriods = nPeriods;
263 double fRet = ( pow( fRate + 1.0, 1.0 / fPeriods ) - 1.0 ) * fPeriods;
264 return finiteOrThrow( fRet );
265}
266
267
268double SAL_CALL AnalysisAddIn::getDollarfr( double fDollarDec, sal_Int32 nFrac )
269{
270 if( nFrac <= 0 )
271 throw css::lang::IllegalArgumentException();
272
273 double fInt;
274 double fFrac = nFrac;
275
276 double fRet = modf( fDollarDec, &fInt );
277
278 fRet *= fFrac;
279
280 fRet *= pow( 10.0, -ceil( log10( fFrac ) ) );
281
282 fRet += fInt;
283
284 return finiteOrThrow( fRet );
285}
286
287
288double SAL_CALL AnalysisAddIn::getDollarde( double fDollarFrac, sal_Int32 nFrac )
289{
290 if( nFrac <= 0 )
291 throw css::lang::IllegalArgumentException();
292
293 double fInt;
294 double fFrac = nFrac;
295
296 double fRet = modf( fDollarFrac, &fInt );
297
298 fRet /= fFrac;
299
300 fRet *= pow( 10.0, ceil( log10( fFrac ) ) );
301
302 fRet += fInt;
303
304 return finiteOrThrow( fRet );
305}
306
307
308double SAL_CALL AnalysisAddIn::getYield( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
309 sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice, double fRedemp, sal_Int32 nFreq, const css::uno::Any& rOB )
310{
311 if( fCoup < 0.0 || fPrice <= 0.0 || fRedemp <= 0.0 || isFreqInvalid(nFreq) || nSettle >= nMat )
312 throw css::lang::IllegalArgumentException();
313
314 double fRet = getYield_( GetNullDate( xOpt ), nSettle, nMat, fCoup, fPrice, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
315 return finiteOrThrow( fRet );
316}
317
318
319double SAL_CALL AnalysisAddIn::getYielddisc( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
320 sal_Int32 nSettle, sal_Int32 nMat, double fPrice, double fRedemp, const css::uno::Any& rOB )
321{
322 if( fPrice <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
323 throw css::lang::IllegalArgumentException();
324
325 sal_Int32 nNullDate = GetNullDate( xOpt );
326
327 double fRet = ( fRedemp / fPrice ) - 1.0;
328 fRet /= GetYearFrac( nNullDate, nSettle, nMat, getDateMode( xOpt, rOB ) );
329
330 return finiteOrThrow( fRet );
331}
332
333
334double SAL_CALL AnalysisAddIn::getYieldmat( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
335 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, double fRate, double fPrice, const css::uno::Any& rOB )
336{
337 if( fPrice <= 0.0 || fRate < 0.0 || nSettle >= nMat || nSettle < nIssue)
338 throw css::lang::IllegalArgumentException();
339
340 double fRet = GetYieldmat( GetNullDate( xOpt ), nSettle, nMat, nIssue, fRate, fPrice, getDateMode( xOpt, rOB ) );
341 return finiteOrThrow( fRet );
342}
343
344
345double SAL_CALL AnalysisAddIn::getTbilleq( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
346 sal_Int32 nSettle, sal_Int32 nMat, double fDisc )
347{
348 nMat++;
349
350 sal_Int32 nDiff = GetDiffDate360( xOpt, nSettle, nMat, true );
351
352 if( fDisc <= 0.0 || nSettle >= nMat || nDiff > 360 )
353 throw css::lang::IllegalArgumentException();
354
355 double fRet = ( 365 * fDisc ) / ( 360 - ( fDisc * double( nDiff ) ) );
356 return finiteOrThrow( fRet );
357}
358
359
360double SAL_CALL AnalysisAddIn::getTbillprice( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
361 sal_Int32 nSettle, sal_Int32 nMat, double fDisc )
362{
363 if( fDisc <= 0.0 || nSettle > nMat )
364 throw css::lang::IllegalArgumentException();
365
366 nMat++;
367
368 double fFraction = GetYearFrac( xOpt, nSettle, nMat, 0 ); // method: USA 30/360
369
370 if( modf( fFraction, &o3tl::temporary(double()) ) == 0.0 )
371 throw css::lang::IllegalArgumentException();
372
373 double fRet = 100.0 * ( 1.0 - fDisc * fFraction );
374 return finiteOrThrow( fRet );
375}
376
377
378double SAL_CALL AnalysisAddIn::getTbillyield( const css::uno::Reference< css::beans::XPropertySet >& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice )
379{
380 sal_Int32 nDiff = GetDiffDate360( xOpt, nSettle, nMat, true );
381 nDiff++;
382
383 if( fPrice <= 0.0 || nSettle >= nMat || nDiff > 360 )
384 throw css::lang::IllegalArgumentException();
385
386 double fRet = 100.0;
387 fRet /= fPrice;
388 fRet--;
389 fRet /= double( nDiff );
390 fRet *= 360.0;
391
392 return finiteOrThrow( fRet );
393}
394
395// Encapsulation violation: We *know* that GetOddfprice() always
396// throws.
397
399
400double SAL_CALL AnalysisAddIn::getOddfprice( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
401 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, sal_Int32 nFirstCoup,
402 double fRate, double fYield, double fRedemp, sal_Int32 nFreq, const css::uno::Any& rOB )
403{
404 if( fRate < 0.0 || fYield < 0.0 || isFreqInvalid(nFreq) || nMat <= nFirstCoup || nFirstCoup <= nSettle || nSettle <= nIssue )
405 throw css::lang::IllegalArgumentException();
406
407 double fRet = GetOddfprice( GetNullDate( xOpt ), nSettle, nMat, nIssue, nFirstCoup, fRate, fYield, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
408 return finiteOrThrow( fRet );
409}
410
412
413// Encapsulation violation: We *know* that Getoddfyield() always
414// throws.
415
417
418double SAL_CALL AnalysisAddIn::getOddfyield( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
419 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, sal_Int32 nFirstCoup,
420 double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, const css::uno::Any& rOB )
421{
422 if( fRate < 0.0 || fPrice <= 0.0 || isFreqInvalid(nFreq) || nMat <= nFirstCoup || nFirstCoup <= nSettle || nSettle <= nIssue )
423 throw css::lang::IllegalArgumentException();
424
425 double fRet = GetOddfyield( GetNullDate( xOpt ), nSettle, nMat, nIssue, nFirstCoup, fRate, fPrice, fRedemp, nFreq,
426 getDateMode( xOpt, rOB ) );
427 return finiteOrThrow( fRet );
428}
429
431
432double SAL_CALL AnalysisAddIn::getOddlprice( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
433 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
434 double fRate, double fYield, double fRedemp, sal_Int32 nFreq, const css::uno::Any& rOB )
435{
436 if( fRate <= 0.0 || fYield < 0.0 || fRedemp <= 0.0 || isFreqInvalid(nFreq) || nMat <= nSettle || nSettle <= nLastInterest )
437 throw css::lang::IllegalArgumentException();
438
439 double fRet = GetOddlprice( GetNullDate( xOpt ), nSettle, nMat, nLastInterest, fRate, fYield, fRedemp, nFreq,
440 getDateMode( xOpt, rOB ) );
441 return finiteOrThrow( fRet );
442}
443
444
445double SAL_CALL AnalysisAddIn::getOddlyield( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
446 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
447 double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, const css::uno::Any& rOB )
448{
449 if( fRate <= 0.0 || fPrice <= 0.0 || fRedemp <= 0.0 || isFreqInvalid(nFreq) || nMat <= nSettle || nSettle <= nLastInterest )
450 throw css::lang::IllegalArgumentException();
451
452 double fRet = GetOddlyield( GetNullDate( xOpt ), nSettle, nMat, nLastInterest, fRate, fPrice, fRedemp, nFreq,
453 getDateMode( xOpt, rOB ) );
454 return finiteOrThrow( fRet );
455}
456
457// XIRR helper functions
458
459#define V_(i) (rValues.Get(i))
460#define D_(i) (rDates.Get(i))
461
463static double lcl_sca_XirrResult( const ScaDoubleList& rValues, const ScaDoubleList& rDates, double fRate )
464{
465 /* V_0 ... V_n = input values.
466 D_0 ... D_n = input dates.
467 R = input interest rate.
468
469 r := R+1
470 E_i := (D_i-D_0) / 365
471
472 n V_i n V_i
473 f(R) = SUM ------- = V_0 + SUM ------- .
474 i=0 r^E_i i=1 r^E_i
475 */
476 double D_0 = D_(0);
477 double r = fRate + 1.0;
478 double fResult = V_(0);
479 for( sal_uInt32 i = 1, nCount = rValues.Count(); i < nCount; ++i )
480 fResult += V_(i) / pow( r, (D_(i) - D_0) / 365.0 );
481 return fResult;
482}
483
485static double lcl_sca_XirrResult_Deriv1( const ScaDoubleList& rValues, const ScaDoubleList& rDates, double fRate )
486{
487 /* V_0 ... V_n = input values.
488 D_0 ... D_n = input dates.
489 R = input interest rate.
490
491 r := R+1
492 E_i := (D_i-D_0) / 365
493
494 n V_i
495 f'(R) = [ V_0 + SUM ------- ]'
496 i=1 r^E_i
497
498 n V_i n E_i V_i
499 = 0 + SUM -E_i ----------- r' = - SUM ----------- .
500 i=1 r^(E_i+1) i=1 r^(E_i+1)
501 */
502 double D_0 = D_(0);
503 double r = fRate + 1.0;
504 double fResult = 0.0;
505 for( sal_uInt32 i = 1, nCount = rValues.Count(); i < nCount; ++i )
506 {
507 double E_i = (D_(i) - D_0) / 365.0;
508 fResult -= E_i * V_(i) / pow( r, E_i + 1.0 );
509 }
510 return fResult;
511}
512
513#undef V_
514#undef D_
515
516// XIRR calculation
517
519 const css::uno::Reference< css::beans::XPropertySet >& xOpt, const css::uno::Sequence< css::uno::Sequence< double > >& rValues, const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rDates, const css::uno::Any& rGuessRate )
520{
521 ScaDoubleList aValues, aDates;
522 aValues.Append( rValues );
523 aDates.Append( rDates );
524
525 if( (aValues.Count() < 2) || (aValues.Count() != aDates.Count()) )
526 throw css::lang::IllegalArgumentException();
527
528 // result interest rate, initialized with passed guessed rate, or 10%
529 double fResultRate = aAnyConv.getDouble( xOpt, rGuessRate, 0.1 );
530 if( fResultRate <= -1 )
531 throw css::lang::IllegalArgumentException();
532
533 // maximum epsilon for end of iteration
534 static const double fMaxEps = 1e-10;
535 // maximum number of iterations
536 static const sal_Int32 nMaxIter = 50;
537
538 // Newton's method - try to find a fResultRate, so that lcl_sca_XirrResult() returns 0.
539 sal_Int32 nIter = 0;
540 double fResultValue;
541 sal_Int32 nIterScan = 0;
542 bool bContLoop = false;
543 bool bResultRateScanEnd = false;
544
545 // First the inner while-loop will be executed using the default Value fResultRate
546 // or the user guessed fResultRate if those do not deliver a solution for the
547 // Newton's method then the range from -0.99 to +0.99 will be scanned with a
548 // step size of 0.01 to find fResultRate's value which can deliver a solution
549 do
550 {
551 if (nIterScan >=1)
552 fResultRate = -0.99 + (nIterScan -1)* 0.01;
553 do
554 {
555 fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
556 double fNewRate = fResultRate - fResultValue / lcl_sca_XirrResult_Deriv1( aValues, aDates, fResultRate );
557 double fRateEps = fabs( fNewRate - fResultRate );
558 fResultRate = fNewRate;
559 bContLoop = (fRateEps > fMaxEps) && (fabs( fResultValue ) > fMaxEps);
560 }
561 while( bContLoop && (++nIter < nMaxIter) );
562 nIter = 0;
563 if ( std::isnan(fResultRate) || std::isinf(fResultRate)
564 ||std::isnan(fResultValue) || std::isinf(fResultValue))
565 bContLoop = true;
566
567 ++nIterScan;
568 bResultRateScanEnd = (nIterScan >= 200);
569 }
570 while(bContLoop && !bResultRateScanEnd);
571
572 if( bContLoop )
573 throw css::lang::IllegalArgumentException();
574 return finiteOrThrow( fResultRate );
575}
576
577
579 double fRate, const css::uno::Sequence< css::uno::Sequence< double > >& rValues, const css::uno::Sequence< css::uno::Sequence< sal_Int32 > >& rDates )
580{
581 ScaDoubleList aValList;
582 ScaDoubleList aDateList;
583
584 aValList.Append( rValues );
585 aDateList.Append( rDates );
586
587 sal_uInt32 nNum = aValList.Count();
588
589 if( nNum != aDateList.Count() || nNum < 2 )
590 throw css::lang::IllegalArgumentException();
591
592 double fRet = 0.0;
593 double fNull = aDateList.Get( 0 );
594 fRate++;
595
596 for( sal_uInt32 i = 0 ; i < nNum ; i++ )
597 fRet += aValList.Get( i ) / ( pow( fRate, ( aDateList.Get( i ) - fNull ) / 365.0 ) );
598
599 return finiteOrThrow( fRet );
600}
601
602
603double SAL_CALL AnalysisAddIn::getIntrate( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
604 sal_Int32 nSettle, sal_Int32 nMat, double fInvest, double fRedemp, const css::uno::Any& rOB )
605{
606 if( fInvest <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
607 throw css::lang::IllegalArgumentException();
608
609 double fRet = ( ( fRedemp / fInvest ) - 1.0 ) / GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) );
610 return finiteOrThrow( fRet );
611}
612
613
614double SAL_CALL AnalysisAddIn::getCoupncd( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
615 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any& rOB )
616{
617 double fRet = GetCoupncd( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
618 return finiteOrThrow( fRet );
619}
620
621
622double SAL_CALL AnalysisAddIn::getCoupdays( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
623 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any& rOB )
624{
625 double fRet = GetCoupdays( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
626 return finiteOrThrow( fRet );
627}
628
629
630double SAL_CALL AnalysisAddIn::getCoupdaysnc( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
631 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any& rOB )
632{
633 double fRet = GetCoupdaysnc( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
634 return finiteOrThrow( fRet );
635}
636
637
638double SAL_CALL AnalysisAddIn::getCoupdaybs( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
639 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any& rOB )
640{
641 double fRet = GetCoupdaybs( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
642 return finiteOrThrow( fRet );
643}
644
645
646double SAL_CALL AnalysisAddIn::getCouppcd( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
647 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any& rOB )
648{
649 double fRet = GetCouppcd( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
650 return finiteOrThrow( fRet );
651}
652
653
654double SAL_CALL AnalysisAddIn::getCoupnum( const css::uno::Reference< css::beans::XPropertySet >& xOpt,
655 sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any& rOB )
656{
657 double fRet = GetCoupnum( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
658 return finiteOrThrow( fRet );
659}
660
661
662double SAL_CALL AnalysisAddIn::getFvschedule( double fPrinc, const css::uno::Sequence< css::uno::Sequence< double > >& rSchedule )
663{
664 ScaDoubleList aSchedList;
665
666 aSchedList.Append( rSchedule );
667
668 for( sal_uInt32 i = 0; i < aSchedList.Count(); ++i )
669 fPrinc *= 1.0 + aSchedList.Get(i);
670
671 return finiteOrThrow( fPrinc );
672}
673
674
675/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool isFreqInvalid(sal_Int32 nFreq)
double finiteOrThrow(double d)
virtual double SAL_CALL getAccrintm(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nIssue, sal_Int32 nSettle, double fRate, const css::uno::Any &rVal, const css::uno::Any &rOptBase) override
Definition: financial.cxx:67
virtual double SAL_CALL getMduration(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fYield, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:245
virtual double SAL_CALL getXnpv(double fRate, const css::uno::Sequence< css::uno::Sequence< double > > &rValues, const css::uno::Sequence< css::uno::Sequence< sal_Int32 > > &rDates) override
Definition: financial.cxx:578
virtual double SAL_CALL getYielddisc(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice, double fRedemp, const css::uno::Any &rOptBase) override
Definition: financial.cxx:319
virtual double SAL_CALL getAmordegrc(const css::uno::Reference< css::beans::XPropertySet > &, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal, double fPer, double fRate, const css::uno::Any &rOptBase) override
Definition: financial.cxx:27
virtual double SAL_CALL getCumprinc(double fRate, sal_Int32 nNumPeriods, double fVal, sal_Int32 nStartPer, sal_Int32 nEndPer, sal_Int32 nPayType) override
Definition: financial.cxx:124
virtual double SAL_CALL getPricemat(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, double fRate, double fYield, const css::uno::Any &rOptBase) override
Definition: financial.cxx:223
virtual double SAL_CALL getDollarfr(double fDollarDec, sal_Int32 nFrac) override
Definition: financial.cxx:268
virtual double SAL_CALL getCoupnum(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:654
virtual double SAL_CALL getFvschedule(double fPrinc, const css::uno::Sequence< css::uno::Sequence< double > > &rSchedule) override
Definition: financial.cxx:662
virtual double SAL_CALL getAmorlinc(const css::uno::Reference< css::beans::XPropertySet > &, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal, double fPer, double fRate, const css::uno::Any &rOptBase) override
Definition: financial.cxx:40
virtual double SAL_CALL getDollarde(double fDollarFrac, sal_Int32 nFrac) override
Definition: financial.cxx:288
virtual double SAL_CALL getDuration(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fYield, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:101
virtual double SAL_CALL getCoupncd(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:614
virtual double SAL_CALL getPricedisc(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fDisc, double fRedemp, const css::uno::Any &rOptBase) override
Definition: financial.cxx:212
virtual double SAL_CALL getYieldmat(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, double fRate, double fPrice, const css::uno::Any &rOptBase) override
Definition: financial.cxx:334
virtual double SAL_CALL getReceived(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fInvest, double fDisc, const css::uno::Any &rOptBase) override
Definition: financial.cxx:80
virtual double SAL_CALL getYield(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice, double fRedemp, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:308
virtual double SAL_CALL getCoupdaybs(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:638
virtual double SAL_CALL getEffect(double fNominal, sal_Int32 nPeriods) override
Definition: financial.cxx:112
virtual double SAL_CALL getOddfprice(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, sal_Int32 nFirstCoup, double fRate, double fYield, double fRedemp, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:400
virtual double SAL_CALL getXirr(const css::uno::Reference< css::beans::XPropertySet > &xOpt, const css::uno::Sequence< css::uno::Sequence< double > > &rValues, const css::uno::Sequence< css::uno::Sequence< sal_Int32 > > &rDates, const css::uno::Any &rGuess) override
Definition: financial.cxx:518
virtual double SAL_CALL getPrice(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield, double fRedemp, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:200
virtual double SAL_CALL getNominal(double fRate, sal_Int32 nPeriods) override
Definition: financial.cxx:257
virtual double SAL_CALL getDisc(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice, double fRedemp, const css::uno::Any &rOptBase) override
Definition: financial.cxx:91
virtual double SAL_CALL getCouppcd(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:646
virtual double SAL_CALL getAccrint(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nIssue, sal_Int32 nFirstInter, sal_Int32 nSettle, double fRate, const css::uno::Any &rVal, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:53
virtual double SAL_CALL getOddlyield(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest, double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:445
virtual double SAL_CALL getTbillprice(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fDisc) override
Definition: financial.cxx:360
virtual double SAL_CALL getCoupdays(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:622
virtual double SAL_CALL getCoupdaysnc(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:630
virtual double SAL_CALL getIntrate(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fInvest, double fRedemp, const css::uno::Any &rOptBase) override
Definition: financial.cxx:603
virtual double SAL_CALL getOddlprice(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest, double fRate, double fYield, double fRedemp, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:432
virtual double SAL_CALL getTbilleq(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fDisc) override
Definition: financial.cxx:345
sca::analysis::ScaAnyConverter aAnyConv
Definition: analysis.hxx:57
sal_Int32 getDateMode(const css::uno::Reference< css::beans::XPropertySet > &xPropSet, const css::uno::Any &rAny)
Converts an Any to sal_Int32 in the range from 0 to 4 (date calculation mode).
Definition: analysis.cxx:67
virtual double SAL_CALL getTbillyield(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice) override
Definition: financial.cxx:378
virtual double SAL_CALL getCumipmt(double fRate, sal_Int32 nNumPeriods, double fVal, sal_Int32 nStartPer, sal_Int32 nEndPer, sal_Int32 nPayType) override
Definition: financial.cxx:162
virtual double SAL_CALL getOddfyield(const css::uno::Reference< css::beans::XPropertySet > &xOpt, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, sal_Int32 nFirstCoup, double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, const css::uno::Any &rOptBase) override
Definition: financial.cxx:418
bool getDouble(double &rfResult, const css::uno::Any &rAny) const
Converts an Any to double (without initialization).
double Get(sal_uInt32 n) const
int nCount
static double lcl_sca_XirrResult(const ScaDoubleList &rValues, const ScaDoubleList &rDates, double fRate)
Calculates the resulting amount for the passed interest rate and the given XIRR parameters.
Definition: financial.cxx:463
#define V_(i)
Definition: financial.cxx:459
static double lcl_sca_XirrResult_Deriv1(const ScaDoubleList &rValues, const ScaDoubleList &rDates, double fRate)
Calculates the first derivation of lcl_sca_XirrResult().
Definition: financial.cxx:485
#define D_(i)
Definition: financial.cxx:460
int i
constexpr T & temporary(T &&x)
double GetOddfprice(sal_Int32, sal_Int32, sal_Int32, sal_Int32, sal_Int32, double, double, double, sal_Int32, sal_Int32)
double GetOddfyield(sal_Int32, sal_Int32, sal_Int32, sal_Int32, sal_Int32, double, double, double, sal_Int32, sal_Int32)
double GetPmt(double fRate, double fNper, double fPv, double fFv, sal_Int32 nPayType)
double GetCoupdaysnc(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase)
double GetCouppcd(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase)
double GetAmordegrc(sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal, double fPer, double fRate, sal_Int32 nBase)
double GetCoupnum(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase)
double getPrice_(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield, double fRedemp, sal_Int32 nFreq, sal_Int32 nBase)
double GetCoupdays(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase)
double GetCoupdaybs(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase)
double GetFv(double fRate, double fNper, double fPmt, double fPv, sal_Int32 nPayType)
double GetAmorlinc(sal_Int32 nNullDate, double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal, double fPer, double fRate, sal_Int32 nBase)
double GetCoupncd(sal_Int32 nNullDate, sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, sal_Int32 nBase)
const char GetDuration[]
const char GetYearDiff[]
const char GetYearFrac[]
const char getYield_[]
const char GetYieldmat[]
const char GetDiffDate360[]
const char GetOddlyield[]
const char GetOddlprice[]
const char GetNullDate[]
#define SAL_WNOUNREACHABLE_CODE_POP
#define SAL_WNOUNREACHABLE_CODE_PUSH