1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "analysis.hxx"
21 #include "analysishelper.hxx"
22 #include <rtl/math.hxx>
24 using namespace sca::analysis
;
26 double SAL_CALL
AnalysisAddIn::getAmordegrc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
27 double fCost
, sal_Int32 nDate
, sal_Int32 nFirstPer
, double fRestVal
,
28 double fPer
, double fRate
, const css::uno::Any
& rOB
)
30 if( nDate
> nFirstPer
|| fRate
<= 0.0 || fRestVal
> fCost
||
31 fCost
<= 0.0 || fRestVal
< 0 || fPer
< 0 )
32 throw css::lang::IllegalArgumentException();
34 double fRet
= GetAmordegrc( GetNullDate( xOpt
), fCost
, nDate
, nFirstPer
, fRestVal
, fPer
, fRate
, getDateMode( xOpt
, rOB
) );
35 RETURN_FINITE( fRet
);
39 double SAL_CALL
AnalysisAddIn::getAmorlinc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
40 double fCost
, sal_Int32 nDate
, sal_Int32 nFirstPer
, double fRestVal
,
41 double fPer
, double fRate
, const css::uno::Any
& rOB
)
43 if ( nDate
> nFirstPer
|| fRate
<= 0.0 || fRestVal
> fCost
||
44 fCost
<= 0.0 || fRestVal
< 0 || fPer
< 0 )
45 throw css::lang::IllegalArgumentException();
47 double fRet
= GetAmorlinc( GetNullDate( xOpt
), fCost
, nDate
, nFirstPer
, fRestVal
, fPer
, fRate
, getDateMode( xOpt
, rOB
) );
48 RETURN_FINITE( fRet
);
52 double SAL_CALL
AnalysisAddIn::getAccrint( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
53 sal_Int32 nIssue
, sal_Int32
/*nFirstInter*/, sal_Int32 nSettle
, double fRate
,
54 const css::uno::Any
&rVal
, sal_Int32 nFreq
, const css::uno::Any
& rOB
)
56 double fVal
= aAnyConv
.getDouble( xOpt
, rVal
, 1000.0 );
58 if( fRate
<= 0.0 || fVal
<= 0.0 || CHK_Freq
|| nIssue
>= nSettle
)
59 throw css::lang::IllegalArgumentException();
61 double fRet
= fVal
* fRate
* GetYearDiff( GetNullDate( xOpt
), nIssue
, nSettle
, getDateMode( xOpt
, rOB
) );
62 RETURN_FINITE( fRet
);
66 double SAL_CALL
AnalysisAddIn::getAccrintm( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
67 sal_Int32 nIssue
, sal_Int32 nSettle
, double fRate
, const css::uno::Any
& rVal
, const css::uno::Any
& rOB
)
69 double fVal
= aAnyConv
.getDouble( xOpt
, rVal
, 1000.0 );
71 if( fRate
<= 0.0 || fVal
<= 0.0 || nIssue
>= nSettle
)
72 throw css::lang::IllegalArgumentException();
74 double fRet
= fVal
* fRate
* GetYearDiff( GetNullDate( xOpt
), nIssue
, nSettle
, getDateMode( xOpt
, rOB
) );
75 RETURN_FINITE( fRet
);
79 double SAL_CALL
AnalysisAddIn::getReceived( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
80 sal_Int32 nSettle
, sal_Int32 nMat
, double fInvest
, double fDisc
, const css::uno::Any
& rOB
)
82 if( fInvest
<= 0.0 || fDisc
<= 0.0 || nSettle
>= nMat
)
83 throw css::lang::IllegalArgumentException();
85 double fRet
= fInvest
/ ( 1.0 - ( fDisc
* GetYearDiff( GetNullDate( xOpt
), nSettle
, nMat
, getDateMode( xOpt
, rOB
) ) ) );
86 RETURN_FINITE( fRet
);
90 double SAL_CALL
AnalysisAddIn::getDisc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
91 sal_Int32 nSettle
, sal_Int32 nMat
, double fPrice
, double fRedemp
, const css::uno::Any
& rOB
)
93 if( fPrice
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
94 throw css::lang::IllegalArgumentException();
95 double fRet
= ( 1.0 - fPrice
/ fRedemp
) / GetYearFrac( xOpt
, nSettle
, nMat
, getDateMode( xOpt
, rOB
) );
96 RETURN_FINITE( fRet
);
100 double SAL_CALL
AnalysisAddIn::getDuration( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
101 sal_Int32 nSettle
, sal_Int32 nMat
, double fCoup
, double fYield
, sal_Int32 nFreq
, const css::uno::Any
& rOB
)
103 if( fCoup
< 0.0 || fYield
< 0.0 || CHK_Freq
|| nSettle
>= nMat
)
104 throw css::lang::IllegalArgumentException();
106 double fRet
= GetDuration( GetNullDate( xOpt
), nSettle
, nMat
, fCoup
, fYield
, nFreq
, getDateMode( xOpt
, rOB
) );
107 RETURN_FINITE( fRet
);
111 double SAL_CALL
AnalysisAddIn::getEffect( double fNominal
, sal_Int32 nPeriods
)
113 if( nPeriods
< 1 || fNominal
<= 0.0 )
114 throw css::lang::IllegalArgumentException();
116 double fPeriods
= nPeriods
;
118 double fRet
= pow( 1.0 + fNominal
/ fPeriods
, fPeriods
) - 1.0;
119 RETURN_FINITE( fRet
);
123 double SAL_CALL
AnalysisAddIn::getCumprinc( double fRate
, sal_Int32 nNumPeriods
, double fVal
,
124 sal_Int32 nStartPer
, sal_Int32 nEndPer
, sal_Int32 nPayType
)
128 if( nStartPer
< 1 || nEndPer
< nStartPer
|| fRate
<= 0.0 || nEndPer
> nNumPeriods
|| nNumPeriods
<= 0 ||
129 fVal
<= 0.0 || ( nPayType
!= 0 && nPayType
!= 1 ) )
130 throw css::lang::IllegalArgumentException();
132 fPmt
= GetPmt( fRate
, nNumPeriods
, fVal
, 0.0, nPayType
);
136 sal_uInt32 nStart
= sal_uInt32( nStartPer
);
137 sal_uInt32 nEnd
= sal_uInt32( nEndPer
);
142 fPpmt
= fPmt
+ fVal
* fRate
;
149 for( sal_uInt32 i
= nStart
; i
<= nEnd
; i
++ )
152 fPpmt
+= fPmt
- ( GetFv( fRate
, double( i
- 2 ), fPmt
, fVal
, 1 ) - fPmt
) * fRate
;
154 fPpmt
+= fPmt
- GetFv( fRate
, double( i
- 1 ), fPmt
, fVal
, 0 ) * fRate
;
157 RETURN_FINITE( fPpmt
);
161 double SAL_CALL
AnalysisAddIn::getCumipmt( double fRate
, sal_Int32 nNumPeriods
, double fVal
,
162 sal_Int32 nStartPer
, sal_Int32 nEndPer
, sal_Int32 nPayType
)
166 if( nStartPer
< 1 || nEndPer
< nStartPer
|| fRate
<= 0.0 || nEndPer
> nNumPeriods
|| nNumPeriods
<= 0 ||
167 fVal
<= 0.0 || ( nPayType
!= 0 && nPayType
!= 1 ) )
168 throw css::lang::IllegalArgumentException();
170 fPmt
= GetPmt( fRate
, nNumPeriods
, fVal
, 0.0, nPayType
);
174 sal_uInt32 nStart
= sal_uInt32( nStartPer
);
175 sal_uInt32 nEnd
= sal_uInt32( nEndPer
);
185 for( sal_uInt32 i
= nStart
; i
<= nEnd
; i
++ )
188 fIpmt
+= GetFv( fRate
, double( i
- 2 ), fPmt
, fVal
, 1 ) - fPmt
;
190 fIpmt
+= GetFv( fRate
, double( i
- 1 ), fPmt
, fVal
, 0 );
195 RETURN_FINITE( fIpmt
);
199 double SAL_CALL
AnalysisAddIn::getPrice( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
200 sal_Int32 nSettle
, sal_Int32 nMat
, double fRate
, double fYield
, double fRedemp
, sal_Int32 nFreq
,
201 const css::uno::Any
& rOB
)
203 if( fYield
< 0.0 || fRate
< 0.0 || fRedemp
<= 0.0 || CHK_Freq
|| nSettle
>= nMat
)
204 throw css::lang::IllegalArgumentException();
206 double fRet
= getPrice_( GetNullDate( xOpt
), nSettle
, nMat
, fRate
, fYield
, fRedemp
, nFreq
, getDateMode( xOpt
, rOB
) );
207 RETURN_FINITE( fRet
);
211 double SAL_CALL
AnalysisAddIn::getPricedisc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
212 sal_Int32 nSettle
, sal_Int32 nMat
, double fDisc
, double fRedemp
, const css::uno::Any
& rOB
)
214 if( fDisc
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
215 throw css::lang::IllegalArgumentException();
217 double fRet
= fRedemp
* ( 1.0 - fDisc
* GetYearDiff( GetNullDate( xOpt
), nSettle
, nMat
, getDateMode( xOpt
, rOB
) ) );
218 RETURN_FINITE( fRet
);
222 double SAL_CALL
AnalysisAddIn::getPricemat( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
223 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
, double fRate
, double fYield
, const css::uno::Any
& rOB
)
225 if( fRate
< 0.0 || fYield
< 0.0 || nSettle
>= nMat
)
226 throw css::lang::IllegalArgumentException();
228 sal_Int32 nNullDate
= GetNullDate( xOpt
);
229 sal_Int32 nBase
= getDateMode( xOpt
, rOB
);
231 double fIssMat
= GetYearFrac( nNullDate
, nIssue
, nMat
, nBase
);
232 double fIssSet
= GetYearFrac( nNullDate
, nIssue
, nSettle
, nBase
);
233 double fSetMat
= GetYearFrac( nNullDate
, nSettle
, nMat
, nBase
);
235 double fRet
= 1.0 + fIssMat
* fRate
;
236 fRet
/= 1.0 + fSetMat
* fYield
;
237 fRet
-= fIssSet
* fRate
;
240 RETURN_FINITE( fRet
);
244 double SAL_CALL
AnalysisAddIn::getMduration( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
245 sal_Int32 nSettle
, sal_Int32 nMat
, double fCoup
, double fYield
, sal_Int32 nFreq
, const css::uno::Any
& rOB
)
247 if( fCoup
< 0.0 || fYield
< 0.0 || CHK_Freq
)
248 throw css::lang::IllegalArgumentException();
250 double fRet
= GetDuration( GetNullDate( xOpt
), nSettle
, nMat
, fCoup
, fYield
, nFreq
, getDateMode( xOpt
, rOB
) );
251 fRet
/= 1.0 + ( fYield
/ double( nFreq
) );
252 RETURN_FINITE( fRet
);
256 double SAL_CALL
AnalysisAddIn::getNominal( double fRate
, sal_Int32 nPeriods
)
258 if( fRate
<= 0.0 || nPeriods
< 0 )
259 throw css::lang::IllegalArgumentException();
261 double fPeriods
= nPeriods
;
262 double fRet
= ( pow( fRate
+ 1.0, 1.0 / fPeriods
) - 1.0 ) * fPeriods
;
263 RETURN_FINITE( fRet
);
267 double SAL_CALL
AnalysisAddIn::getDollarfr( double fDollarDec
, sal_Int32 nFrac
)
270 throw css::lang::IllegalArgumentException();
273 double fFrac
= nFrac
;
275 double fRet
= modf( fDollarDec
, &fInt
);
279 fRet
*= pow( 10.0, -ceil( log10( fFrac
) ) );
283 RETURN_FINITE( fRet
);
287 double SAL_CALL
AnalysisAddIn::getDollarde( double fDollarFrac
, sal_Int32 nFrac
)
290 throw css::lang::IllegalArgumentException();
293 double fFrac
= nFrac
;
295 double fRet
= modf( fDollarFrac
, &fInt
);
299 fRet
*= pow( 10.0, ceil( log10( fFrac
) ) );
303 RETURN_FINITE( fRet
);
307 double SAL_CALL
AnalysisAddIn::getYield( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
308 sal_Int32 nSettle
, sal_Int32 nMat
, double fCoup
, double fPrice
, double fRedemp
, sal_Int32 nFreq
, const css::uno::Any
& rOB
)
310 if( fCoup
< 0.0 || fPrice
<= 0.0 || fRedemp
<= 0.0 || CHK_Freq
|| nSettle
>= nMat
)
311 throw css::lang::IllegalArgumentException();
313 double fRet
= getYield_( GetNullDate( xOpt
), nSettle
, nMat
, fCoup
, fPrice
, fRedemp
, nFreq
, getDateMode( xOpt
, rOB
) );
314 RETURN_FINITE( fRet
);
318 double SAL_CALL
AnalysisAddIn::getYielddisc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
319 sal_Int32 nSettle
, sal_Int32 nMat
, double fPrice
, double fRedemp
, const css::uno::Any
& rOB
)
321 if( fPrice
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
322 throw css::lang::IllegalArgumentException();
324 sal_Int32 nNullDate
= GetNullDate( xOpt
);
326 double fRet
= ( fRedemp
/ fPrice
) - 1.0;
327 fRet
/= GetYearFrac( nNullDate
, nSettle
, nMat
, getDateMode( xOpt
, rOB
) );
329 RETURN_FINITE( fRet
);
333 double SAL_CALL
AnalysisAddIn::getYieldmat( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
334 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
, double fRate
, double fPrice
, const css::uno::Any
& rOB
)
336 if( fPrice
<= 0.0 || fRate
< 0.0 || nSettle
>= nMat
|| nSettle
< nIssue
)
337 throw css::lang::IllegalArgumentException();
339 double fRet
= GetYieldmat( GetNullDate( xOpt
), nSettle
, nMat
, nIssue
, fRate
, fPrice
, getDateMode( xOpt
, rOB
) );
340 RETURN_FINITE( fRet
);
344 double SAL_CALL
AnalysisAddIn::getTbilleq( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
345 sal_Int32 nSettle
, sal_Int32 nMat
, double fDisc
)
349 sal_Int32 nDiff
= GetDiffDate360( xOpt
, nSettle
, nMat
, true );
351 if( fDisc
<= 0.0 || nSettle
>= nMat
|| nDiff
> 360 )
352 throw css::lang::IllegalArgumentException();
354 double fRet
= ( 365 * fDisc
) / ( 360 - ( fDisc
* double( nDiff
) ) );
355 RETURN_FINITE( fRet
);
359 double SAL_CALL
AnalysisAddIn::getTbillprice( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
360 sal_Int32 nSettle
, sal_Int32 nMat
, double fDisc
)
362 if( fDisc
<= 0.0 || nSettle
> nMat
)
363 throw css::lang::IllegalArgumentException();
367 double fFraction
= GetYearFrac( xOpt
, nSettle
, nMat
, 0 ); // method: USA 30/360
370 if( modf( fFraction
, &fDummy
) == 0.0 )
371 throw css::lang::IllegalArgumentException();
373 double fRet
= 100.0 * ( 1.0 - fDisc
* fFraction
);
374 RETURN_FINITE( fRet
);
378 double SAL_CALL
AnalysisAddIn::getTbillyield( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
, sal_Int32 nSettle
, sal_Int32 nMat
, double fPrice
)
380 sal_Int32 nDiff
= GetDiffDate360( xOpt
, nSettle
, nMat
, true );
383 if( fPrice
<= 0.0 || nSettle
>= nMat
|| nDiff
> 360 )
384 throw css::lang::IllegalArgumentException();
389 fRet
/= double( nDiff
);
392 RETURN_FINITE( fRet
);
395 // Encapsulation violation: We *know* that GetOddfprice() always
398 SAL_WNOUNREACHABLE_CODE_PUSH
400 double 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
)
404 if( fRate
< 0.0 || fYield
< 0.0 || CHK_Freq
|| nMat
<= nFirstCoup
|| nFirstCoup
<= nSettle
|| nSettle
<= nIssue
)
405 throw css::lang::IllegalArgumentException();
407 double fRet
= GetOddfprice( GetNullDate( xOpt
), nSettle
, nMat
, nIssue
, nFirstCoup
, fRate
, fYield
, fRedemp
, nFreq
, getDateMode( xOpt
, rOB
) );
408 RETURN_FINITE( fRet
);
411 SAL_WNOUNREACHABLE_CODE_POP
413 // Encapsulation violation: We *know* that Getoddfyield() always
416 SAL_WNOUNREACHABLE_CODE_PUSH
418 double 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
)
422 if( fRate
< 0.0 || fPrice
<= 0.0 || CHK_Freq
|| nMat
<= nFirstCoup
|| nFirstCoup
<= nSettle
|| nSettle
<= nIssue
)
423 throw css::lang::IllegalArgumentException();
425 double fRet
= GetOddfyield( GetNullDate( xOpt
), nSettle
, nMat
, nIssue
, nFirstCoup
, fRate
, fPrice
, fRedemp
, nFreq
,
426 getDateMode( xOpt
, rOB
) );
427 RETURN_FINITE( fRet
);
430 SAL_WNOUNREACHABLE_CODE_POP
432 double 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
)
436 if( fRate
<= 0.0 || fYield
< 0.0 || fRedemp
<= 0.0 || CHK_Freq
|| nMat
<= nSettle
|| nSettle
<= nLastInterest
)
437 throw css::lang::IllegalArgumentException();
439 double fRet
= GetOddlprice( GetNullDate( xOpt
), nSettle
, nMat
, nLastInterest
, fRate
, fYield
, fRedemp
, nFreq
,
440 getDateMode( xOpt
, rOB
) );
441 RETURN_FINITE( fRet
);
445 double 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
)
449 if( fRate
<= 0.0 || fPrice
<= 0.0 || fRedemp
<= 0.0 || CHK_Freq
|| nMat
<= nSettle
|| nSettle
<= nLastInterest
)
450 throw css::lang::IllegalArgumentException();
452 double fRet
= GetOddlyield( GetNullDate( xOpt
), nSettle
, nMat
, nLastInterest
, fRate
, fPrice
, fRedemp
, nFreq
,
453 getDateMode( xOpt
, rOB
) );
454 RETURN_FINITE( fRet
);
457 // XIRR helper functions
459 #define V_(i) (rValues.Get(i))
460 #define D_(i) (rDates.Get(i))
462 /** Calculates the resulting amount for the passed interest rate and the given XIRR parameters. */
463 static double lcl_sca_XirrResult( const ScaDoubleList
& rValues
, const ScaDoubleList
& rDates
, double fRate
)
465 /* V_0 ... V_n = input values.
466 D_0 ... D_n = input dates.
467 R = input interest rate.
470 E_i := (D_i-D_0) / 365
473 f(R) = SUM ------- = V_0 + SUM ------- .
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 );
484 /** Calculates the first derivation of lcl_sca_XirrResult(). */
485 static double lcl_sca_XirrResult_Deriv1( const ScaDoubleList
& rValues
, const ScaDoubleList
& rDates
, double fRate
)
487 /* V_0 ... V_n = input values.
488 D_0 ... D_n = input dates.
489 R = input interest rate.
492 E_i := (D_i-D_0) / 365
495 f'(R) = [ V_0 + SUM ------- ]'
499 = 0 + SUM -E_i ----------- r' = - SUM ----------- .
500 i=1 r^(E_i+1) i=1 r^(E_i+1)
503 double r
= fRate
+ 1.0;
504 double fResult
= 0.0;
505 for( sal_uInt32 i
= 1, nCount
= rValues
.Count(); i
< nCount
; ++i
)
507 double E_i
= (D_(i
) - D_0
) / 365.0;
508 fResult
-= E_i
* V_(i
) / pow( r
, E_i
+ 1.0 );
518 double SAL_CALL
AnalysisAddIn::getXirr(
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
)
521 ScaDoubleList aValues
, aDates
;
522 aValues
.Append( rValues
);
523 aDates
.Append( rDates
);
525 if( (aValues
.Count() < 2) || (aValues
.Count() != aDates
.Count()) )
526 throw css::lang::IllegalArgumentException();
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();
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;
538 // Newton's method - try to find a fResultRate, so that lcl_sca_XirrResult() returns 0.
541 sal_Int32 nIterScan
= 0;
542 bool bContLoop
= false;
543 bool bResultRateScanEnd
= false;
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
552 fResultRate
= -0.99 + (nIterScan
-1)* 0.01;
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
);
561 while( bContLoop
&& (++nIter
< nMaxIter
) );
563 if ( ::rtl::math::isNan(fResultRate
) || ::rtl::math::isInf(fResultRate
)
564 ||::rtl::math::isNan(fResultValue
) || ::rtl::math::isInf(fResultValue
))
568 bResultRateScanEnd
= (nIterScan
>= 200);
570 while(bContLoop
&& !bResultRateScanEnd
);
573 throw css::lang::IllegalArgumentException();
574 RETURN_FINITE( fResultRate
);
578 double SAL_CALL
AnalysisAddIn::getXnpv(
579 double fRate
, const css::uno::Sequence
< css::uno::Sequence
< double > >& rValues
, const css::uno::Sequence
< css::uno::Sequence
< sal_Int32
> >& rDates
)
581 ScaDoubleList aValList
;
582 ScaDoubleList aDateList
;
584 aValList
.Append( rValues
);
585 aDateList
.Append( rDates
);
587 sal_Int32 nNum
= aValList
.Count();
589 if( nNum
!= sal_Int32( aDateList
.Count() ) || nNum
< 2 )
590 throw css::lang::IllegalArgumentException();
593 double fNull
= aDateList
.Get( 0 );
596 for( sal_Int32 i
= 0 ; i
< nNum
; i
++ )
597 fRet
+= aValList
.Get( i
) / ( pow( fRate
, ( aDateList
.Get( i
) - fNull
) / 365.0 ) );
599 RETURN_FINITE( fRet
);
603 double 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
)
606 if( fInvest
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
607 throw css::lang::IllegalArgumentException();
609 double fRet
= ( ( fRedemp
/ fInvest
) - 1.0 ) / GetYearDiff( GetNullDate( xOpt
), nSettle
, nMat
, getDateMode( xOpt
, rOB
) );
610 RETURN_FINITE( fRet
);
614 double 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
)
617 double fRet
= GetCoupncd( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
618 RETURN_FINITE( fRet
);
622 double 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
)
625 double fRet
= GetCoupdays( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
626 RETURN_FINITE( fRet
);
630 double 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
)
633 double fRet
= GetCoupdaysnc( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
634 RETURN_FINITE( fRet
);
638 double 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
)
641 double fRet
= GetCoupdaybs( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
642 RETURN_FINITE( fRet
);
646 double 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
)
649 double fRet
= GetCouppcd( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
650 RETURN_FINITE( fRet
);
654 double 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
)
657 double fRet
= GetCoupnum( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
658 RETURN_FINITE( fRet
);
662 double SAL_CALL
AnalysisAddIn::getFvschedule( double fPrinc
, const css::uno::Sequence
< css::uno::Sequence
< double > >& rSchedule
)
664 ScaDoubleList aSchedList
;
666 aSchedList
.Append( rSchedule
);
668 for( sal_uInt32 i
= 0; i
< aSchedList
.Count(); ++i
)
669 fPrinc
*= 1.0 + aSchedList
.Get(i
);
671 RETURN_FINITE( fPrinc
);
675 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */