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
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
30 if( nDate
> nFirstPer
|| fRate
<= 0.0 || fRestVal
> fCost
)
31 throw css::lang::IllegalArgumentException();
33 double fRet
= GetAmordegrc( GetNullDate( xOpt
), fCost
, nDate
, nFirstPer
, fRestVal
, fPer
, fRate
, getDateMode( xOpt
, rOB
) );
34 RETURN_FINITE( fRet
);
38 double SAL_CALL
AnalysisAddIn::getAmorlinc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
39 double fCost
, sal_Int32 nDate
, sal_Int32 nFirstPer
, double fRestVal
,
40 double fPer
, double fRate
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
42 if( nDate
> nFirstPer
|| fRate
<= 0.0 || fRestVal
> fCost
)
43 throw css::lang::IllegalArgumentException();
45 double fRet
= GetAmorlinc( GetNullDate( xOpt
), fCost
, nDate
, nFirstPer
, fRestVal
, fPer
, fRate
, getDateMode( xOpt
, rOB
) );
46 RETURN_FINITE( fRet
);
50 double SAL_CALL
AnalysisAddIn::getAccrint( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
51 sal_Int32 nIssue
, sal_Int32
/*nFirstInter*/, sal_Int32 nSettle
, double fRate
,
52 const css::uno::Any
&rVal
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
54 double fVal
= aAnyConv
.getDouble( xOpt
, rVal
, 1000.0 );
56 if( fRate
<= 0.0 || fVal
<= 0.0 || CHK_Freq
|| nIssue
>= nSettle
)
57 throw css::lang::IllegalArgumentException();
59 double fRet
= fVal
* fRate
* GetYearDiff( GetNullDate( xOpt
), nIssue
, nSettle
, getDateMode( xOpt
, rOB
) );
60 RETURN_FINITE( fRet
);
64 double SAL_CALL
AnalysisAddIn::getAccrintm( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
65 sal_Int32 nIssue
, sal_Int32 nSettle
, double fRate
, const css::uno::Any
& rVal
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
67 double fVal
= aAnyConv
.getDouble( xOpt
, rVal
, 1000.0 );
69 if( fRate
<= 0.0 || fVal
<= 0.0 || nIssue
>= nSettle
)
70 throw css::lang::IllegalArgumentException();
72 double fRet
= fVal
* fRate
* GetYearDiff( GetNullDate( xOpt
), nIssue
, nSettle
, getDateMode( xOpt
, rOB
) );
73 RETURN_FINITE( fRet
);
77 double SAL_CALL
AnalysisAddIn::getReceived( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
78 sal_Int32 nSettle
, sal_Int32 nMat
, double fInvest
, double fDisc
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
80 if( fInvest
<= 0.0 || fDisc
<= 0.0 )
81 throw css::lang::IllegalArgumentException();
83 double fRet
= fInvest
/ ( 1.0 - ( fDisc
* GetYearDiff( GetNullDate( xOpt
), nSettle
, nMat
, getDateMode( xOpt
, rOB
) ) ) );
84 RETURN_FINITE( fRet
);
88 double SAL_CALL
AnalysisAddIn::getDisc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
89 sal_Int32 nSettle
, sal_Int32 nMat
, double fPrice
, double fRedemp
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
91 if( fPrice
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
92 throw css::lang::IllegalArgumentException();
93 double fRet
= ( 1.0 - fPrice
/ fRedemp
) / GetYearFrac( xOpt
, nSettle
, nMat
, getDateMode( xOpt
, rOB
) );
94 RETURN_FINITE( fRet
);
98 double SAL_CALL
AnalysisAddIn::getDuration( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
99 sal_Int32 nSettle
, sal_Int32 nMat
, double fCoup
, double fYield
, sal_Int32 nFreq
, const css::uno::Any
& rOB
)
100 throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
102 if( fCoup
< 0.0 || fYield
< 0.0 || CHK_Freq
|| nSettle
>= nMat
)
103 throw css::lang::IllegalArgumentException();
105 double fRet
= GetDuration( GetNullDate( xOpt
), nSettle
, nMat
, fCoup
, fYield
, nFreq
, getDateMode( xOpt
, rOB
) );
106 RETURN_FINITE( fRet
);
110 double SAL_CALL
AnalysisAddIn::getEffect( double fNominal
, sal_Int32 nPeriods
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
112 if( nPeriods
< 1 || fNominal
<= 0.0 )
113 throw css::lang::IllegalArgumentException();
115 double fPeriods
= nPeriods
;
117 double fRet
= pow( 1.0 + fNominal
/ fPeriods
, fPeriods
) - 1.0;
118 RETURN_FINITE( fRet
);
122 double SAL_CALL
AnalysisAddIn::getCumprinc( double fRate
, sal_Int32 nNumPeriods
, double fVal
,
123 sal_Int32 nStartPer
, sal_Int32 nEndPer
, sal_Int32 nPayType
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
127 if( nStartPer
< 1 || nEndPer
< nStartPer
|| fRate
<= 0.0 || nEndPer
> nNumPeriods
|| nNumPeriods
<= 0 ||
128 fVal
<= 0.0 || ( nPayType
!= 0 && nPayType
!= 1 ) )
129 throw css::lang::IllegalArgumentException();
131 fRmz
= GetRmz( fRate
, nNumPeriods
, fVal
, 0.0, nPayType
);
135 sal_uInt32 nStart
= sal_uInt32( nStartPer
);
136 sal_uInt32 nEnd
= sal_uInt32( nEndPer
);
141 fKapZ
= fRmz
+ fVal
* fRate
;
148 for( sal_uInt32 i
= nStart
; i
<= nEnd
; i
++ )
151 fKapZ
+= fRmz
- ( GetZw( fRate
, double( i
- 2 ), fRmz
, fVal
, 1 ) - fRmz
) * fRate
;
153 fKapZ
+= fRmz
- GetZw( fRate
, double( i
- 1 ), fRmz
, fVal
, 0 ) * fRate
;
156 RETURN_FINITE( fKapZ
);
160 double SAL_CALL
AnalysisAddIn::getCumipmt( double fRate
, sal_Int32 nNumPeriods
, double fVal
,
161 sal_Int32 nStartPer
, sal_Int32 nEndPer
, sal_Int32 nPayType
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
165 if( nStartPer
< 1 || nEndPer
< nStartPer
|| fRate
<= 0.0 || nEndPer
> nNumPeriods
|| nNumPeriods
<= 0 ||
166 fVal
<= 0.0 || ( nPayType
!= 0 && nPayType
!= 1 ) )
167 throw css::lang::IllegalArgumentException();
169 fRmz
= GetRmz( fRate
, nNumPeriods
, fVal
, 0.0, nPayType
);
173 sal_uInt32 nStart
= sal_uInt32( nStartPer
);
174 sal_uInt32 nEnd
= sal_uInt32( nEndPer
);
184 for( sal_uInt32 i
= nStart
; i
<= nEnd
; i
++ )
187 fZinsZ
+= GetZw( fRate
, double( i
- 2 ), fRmz
, fVal
, 1 ) - fRmz
;
189 fZinsZ
+= GetZw( fRate
, double( i
- 1 ), fRmz
, fVal
, 0 );
194 RETURN_FINITE( fZinsZ
);
198 double SAL_CALL
AnalysisAddIn::getPrice( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
199 sal_Int32 nSettle
, sal_Int32 nMat
, double fRate
, double fYield
, double fRedemp
, sal_Int32 nFreq
,
200 const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
202 if( fYield
< 0.0 || fRate
< 0.0 || fRedemp
<= 0.0 || CHK_Freq
|| nSettle
>= nMat
)
203 throw css::lang::IllegalArgumentException();
205 double fRet
= getPrice_( GetNullDate( xOpt
), nSettle
, nMat
, fRate
, fYield
, fRedemp
, nFreq
, getDateMode( xOpt
, rOB
) );
206 RETURN_FINITE( fRet
);
210 double SAL_CALL
AnalysisAddIn::getPricedisc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
211 sal_Int32 nSettle
, sal_Int32 nMat
, double fDisc
, double fRedemp
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
213 if( fDisc
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
214 throw css::lang::IllegalArgumentException();
216 double fRet
= fRedemp
* ( 1.0 - fDisc
* GetYearDiff( GetNullDate( xOpt
), nSettle
, nMat
, getDateMode( xOpt
, rOB
) ) );
217 RETURN_FINITE( fRet
);
221 double SAL_CALL
AnalysisAddIn::getPricemat( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
222 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
, double fRate
, double fYield
, const css::uno::Any
& rOB
)
223 throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
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
)
246 throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
248 if( fCoup
< 0.0 || fYield
< 0.0 || CHK_Freq
)
249 throw css::lang::IllegalArgumentException();
251 double fRet
= GetDuration( GetNullDate( xOpt
), nSettle
, nMat
, fCoup
, fYield
, nFreq
, getDateMode( xOpt
, rOB
) );
252 fRet
/= 1.0 + ( fYield
/ double( nFreq
) );
253 RETURN_FINITE( fRet
);
257 double SAL_CALL
AnalysisAddIn::getNominal( double fRate
, sal_Int32 nPeriods
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
259 if( fRate
<= 0.0 || nPeriods
< 0 )
260 throw css::lang::IllegalArgumentException();
262 double fPeriods
= nPeriods
;
263 double fRet
= ( pow( fRate
+ 1.0, 1.0 / fPeriods
) - 1.0 ) * fPeriods
;
264 RETURN_FINITE( fRet
);
268 double SAL_CALL
AnalysisAddIn::getDollarfr( double fDollarDec
, sal_Int32 nFrac
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
271 throw css::lang::IllegalArgumentException();
274 double fFrac
= nFrac
;
276 double fRet
= modf( fDollarDec
, &fInt
);
280 fRet
*= pow( 10.0, -ceil( log10( fFrac
) ) );
284 RETURN_FINITE( fRet
);
288 double SAL_CALL
AnalysisAddIn::getDollarde( double fDollarFrac
, sal_Int32 nFrac
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
291 throw css::lang::IllegalArgumentException();
294 double fFrac
= nFrac
;
296 double fRet
= modf( fDollarFrac
, &fInt
);
300 fRet
*= pow( 10.0, ceil( log10( fFrac
) ) );
304 RETURN_FINITE( fRet
);
308 double 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 throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
312 if( fCoup
< 0.0 || fPrice
<= 0.0 || fRedemp
<= 0.0 || CHK_Freq
|| nSettle
>= nMat
)
313 throw css::lang::IllegalArgumentException();
315 double fRet
= getYield_( GetNullDate( xOpt
), nSettle
, nMat
, fCoup
, fPrice
, fRedemp
, nFreq
, getDateMode( xOpt
, rOB
) );
316 RETURN_FINITE( fRet
);
320 double SAL_CALL
AnalysisAddIn::getYielddisc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
321 sal_Int32 nSettle
, sal_Int32 nMat
, double fPrice
, double fRedemp
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
323 if( fPrice
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
324 throw css::lang::IllegalArgumentException();
326 sal_Int32 nNullDate
= GetNullDate( xOpt
);
328 double fRet
= ( fRedemp
/ fPrice
) - 1.0;
329 fRet
/= GetYearFrac( nNullDate
, nSettle
, nMat
, getDateMode( xOpt
, rOB
) );
331 RETURN_FINITE( fRet
);
335 double SAL_CALL
AnalysisAddIn::getYieldmat( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
336 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
, double fRate
, double fPrice
, const css::uno::Any
& rOB
)
337 throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
339 if( fPrice
<= 0.0 || fRate
<= 0.0 || nSettle
>= nMat
)
340 throw css::lang::IllegalArgumentException();
342 double fRet
= GetYieldmat( GetNullDate( xOpt
), nSettle
, nMat
, nIssue
, fRate
, fPrice
, getDateMode( xOpt
, rOB
) );
343 RETURN_FINITE( fRet
);
347 double SAL_CALL
AnalysisAddIn::getTbilleq( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
348 sal_Int32 nSettle
, sal_Int32 nMat
, double fDisc
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
352 sal_Int32 nDiff
= GetDiffDate360( xOpt
, nSettle
, nMat
, true );
354 if( fDisc
<= 0.0 || nSettle
>= nMat
|| nDiff
> 360 )
355 throw css::lang::IllegalArgumentException();
357 double fRet
= ( 365 * fDisc
) / ( 360 - ( fDisc
* double( nDiff
) ) );
358 RETURN_FINITE( fRet
);
362 double SAL_CALL
AnalysisAddIn::getTbillprice( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
363 sal_Int32 nSettle
, sal_Int32 nMat
, double fDisc
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
365 if( fDisc
<= 0.0 || nSettle
> nMat
)
366 throw css::lang::IllegalArgumentException();
370 double fFraction
= GetYearFrac( xOpt
, nSettle
, nMat
, 0 ); // method: USA 30/360
373 if( modf( fFraction
, &fDummy
) == 0.0 )
374 throw css::lang::IllegalArgumentException();
376 double fRet
= 100.0 * ( 1.0 - fDisc
* fFraction
);
377 RETURN_FINITE( fRet
);
381 double SAL_CALL
AnalysisAddIn::getTbillyield( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
, sal_Int32 nSettle
, sal_Int32 nMat
, double fPrice
)
382 throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
384 sal_Int32 nDiff
= GetDiffDate360( xOpt
, nSettle
, nMat
, true );
387 if( fPrice
<= 0.0 || nSettle
>= nMat
|| nDiff
> 360 )
388 throw css::lang::IllegalArgumentException();
393 fRet
/= double( nDiff
);
396 RETURN_FINITE( fRet
);
399 // Encapsulation violation: We *know* that GetOddfprice() always
402 SAL_WNOUNREACHABLE_CODE_PUSH
404 double SAL_CALL
AnalysisAddIn::getOddfprice( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
405 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
, sal_Int32 nFirstCoup
,
406 double fRate
, double fYield
, double fRedemp
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
408 if( fRate
< 0.0 || fYield
< 0.0 || CHK_Freq
|| nMat
<= nFirstCoup
|| nFirstCoup
<= nSettle
|| nSettle
<= nIssue
)
409 throw css::lang::IllegalArgumentException();
411 double fRet
= GetOddfprice( GetNullDate( xOpt
), nSettle
, nMat
, nIssue
, nFirstCoup
, fRate
, fYield
, fRedemp
, nFreq
, getDateMode( xOpt
, rOB
) );
412 RETURN_FINITE( fRet
);
415 SAL_WNOUNREACHABLE_CODE_POP
417 // Encapsulation violation: We *know* that Getoddfyield() always
420 SAL_WNOUNREACHABLE_CODE_PUSH
422 double SAL_CALL
AnalysisAddIn::getOddfyield( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
423 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nIssue
, sal_Int32 nFirstCoup
,
424 double fRate
, double fPrice
, double fRedemp
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
426 if( fRate
< 0.0 || fPrice
<= 0.0 || CHK_Freq
|| nMat
<= nFirstCoup
|| nFirstCoup
<= nSettle
|| nSettle
<= nIssue
)
427 throw css::lang::IllegalArgumentException();
429 double fRet
= GetOddfyield( GetNullDate( xOpt
), nSettle
, nMat
, nIssue
, nFirstCoup
, fRate
, fPrice
, fRedemp
, nFreq
,
430 getDateMode( xOpt
, rOB
) );
431 RETURN_FINITE( fRet
);
434 SAL_WNOUNREACHABLE_CODE_POP
436 double SAL_CALL
AnalysisAddIn::getOddlprice( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
437 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nLastInterest
,
438 double fRate
, double fYield
, double fRedemp
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
440 if( fRate
< 0.0 || fYield
< 0.0 || CHK_Freq
|| nMat
<= nSettle
|| nSettle
<= nLastInterest
)
441 throw css::lang::IllegalArgumentException();
443 double fRet
= GetOddlprice( GetNullDate( xOpt
), nSettle
, nMat
, nLastInterest
, fRate
, fYield
, fRedemp
, nFreq
,
444 getDateMode( xOpt
, rOB
) );
445 RETURN_FINITE( fRet
);
449 double SAL_CALL
AnalysisAddIn::getOddlyield( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
450 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nLastInterest
,
451 double fRate
, double fPrice
, double fRedemp
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
453 if( fRate
< 0.0 || fPrice
<= 0.0 || CHK_Freq
|| nMat
<= nSettle
|| nSettle
<= nLastInterest
)
454 throw css::lang::IllegalArgumentException();
456 double fRet
= GetOddlyield( GetNullDate( xOpt
), nSettle
, nMat
, nLastInterest
, fRate
, fPrice
, fRedemp
, nFreq
,
457 getDateMode( xOpt
, rOB
) );
458 RETURN_FINITE( fRet
);
461 // XIRR helper functions
463 #define V_(i) (rValues.Get(i))
464 #define D_(i) (rDates.Get(i))
466 /** Calculates the resulting amount for the passed interest rate and the given XIRR parameters. */
467 static double lcl_sca_XirrResult( const ScaDoubleList
& rValues
, const ScaDoubleList
& rDates
, double fRate
)
469 /* V_0 ... V_n = input values.
470 D_0 ... D_n = input dates.
471 R = input interest rate.
474 E_i := (D_i-D_0) / 365
477 f(R) = SUM ------- = V_0 + SUM ------- .
481 double r
= fRate
+ 1.0;
482 double fResult
= V_(0);
483 for( sal_uInt32 i
= 1, nCount
= rValues
.Count(); i
< nCount
; ++i
)
484 fResult
+= V_(i
) / pow( r
, (D_(i
) - D_0
) / 365.0 );
488 /** Calculates the first derivation of lcl_sca_XirrResult(). */
489 static double lcl_sca_XirrResult_Deriv1( const ScaDoubleList
& rValues
, const ScaDoubleList
& rDates
, double fRate
)
491 /* V_0 ... V_n = input values.
492 D_0 ... D_n = input dates.
493 R = input interest rate.
496 E_i := (D_i-D_0) / 365
499 f'(R) = [ V_0 + SUM ------- ]'
503 = 0 + SUM -E_i ----------- r' = - SUM ----------- .
504 i=1 r^(E_i+1) i=1 r^(E_i+1)
507 double r
= fRate
+ 1.0;
508 double fResult
= 0.0;
509 for( sal_uInt32 i
= 1, nCount
= rValues
.Count(); i
< nCount
; ++i
)
511 double E_i
= (D_(i
) - D_0
) / 365.0;
512 fResult
-= E_i
* V_(i
) / pow( r
, E_i
+ 1.0 );
522 double SAL_CALL
AnalysisAddIn::getXirr(
523 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
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
525 ScaDoubleList aValues
, aDates
;
526 aValues
.Append( rValues
);
527 aDates
.Append( rDates
);
529 if( (aValues
.Count() < 2) || (aValues
.Count() != aDates
.Count()) )
530 throw css::lang::IllegalArgumentException();
532 // result interest rate, initialized with passed guessed rate, or 10%
533 double fResultRate
= aAnyConv
.getDouble( xOpt
, rGuessRate
, 0.1 );
534 if( fResultRate
<= -1 )
535 throw css::lang::IllegalArgumentException();
537 // maximum epsilon for end of iteration
538 static const double fMaxEps
= 1e-10;
539 // maximum number of iterations
540 static const sal_Int32 nMaxIter
= 50;
542 // Newton's method - try to find a fResultRate, so that lcl_sca_XirrResult() returns 0.
545 sal_Int32 nIterScan
= 0;
546 bool bContLoop
= false;
547 bool bResultRateScanEnd
= false;
549 // First the inner while-loop will be executed using the default Value fResultRate
550 // or the user guessed fResultRate if those do not deliver a solution for the
551 // Newton's method then the range from -0.99 to +0.99 will be scanned with a
552 // step size of 0.01 to find fResultRate's value which can deliver a solution
556 fResultRate
= -0.99 + (nIterScan
-1)* 0.01;
559 fResultValue
= lcl_sca_XirrResult( aValues
, aDates
, fResultRate
);
560 double fNewRate
= fResultRate
- fResultValue
/ lcl_sca_XirrResult_Deriv1( aValues
, aDates
, fResultRate
);
561 double fRateEps
= fabs( fNewRate
- fResultRate
);
562 fResultRate
= fNewRate
;
563 bContLoop
= (fRateEps
> fMaxEps
) && (fabs( fResultValue
) > fMaxEps
);
565 while( bContLoop
&& (++nIter
< nMaxIter
) );
567 if ( ::rtl::math::isNan(fResultRate
) || ::rtl::math::isInf(fResultRate
)
568 ||::rtl::math::isNan(fResultValue
) || ::rtl::math::isInf(fResultValue
))
572 bResultRateScanEnd
= (nIterScan
>= 200);
574 while(bContLoop
&& !bResultRateScanEnd
);
577 throw css::lang::IllegalArgumentException();
578 RETURN_FINITE( fResultRate
);
582 double SAL_CALL
AnalysisAddIn::getXnpv(
583 double fRate
, const css::uno::Sequence
< css::uno::Sequence
< double > >& rValues
, const css::uno::Sequence
< css::uno::Sequence
< sal_Int32
> >& rDates
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
585 ScaDoubleList aValList
;
586 ScaDoubleList aDateList
;
588 aValList
.Append( rValues
);
589 aDateList
.Append( rDates
);
591 sal_Int32 nNum
= aValList
.Count();
593 if( nNum
!= sal_Int32( aDateList
.Count() ) || nNum
< 2 )
594 throw css::lang::IllegalArgumentException();
597 double fNull
= aDateList
.Get( 0 );
600 for( sal_Int32 i
= 0 ; i
< nNum
; i
++ )
601 fRet
+= aValList
.Get( i
) / ( pow( fRate
, ( aDateList
.Get( i
) - fNull
) / 365.0 ) );
603 RETURN_FINITE( fRet
);
607 double SAL_CALL
AnalysisAddIn::getIntrate( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
608 sal_Int32 nSettle
, sal_Int32 nMat
, double fInvest
, double fRedemp
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
610 if( fInvest
<= 0.0 || fRedemp
<= 0.0 || nSettle
>= nMat
)
611 throw css::lang::IllegalArgumentException();
613 double fRet
= ( ( fRedemp
/ fInvest
) - 1.0 ) / GetYearDiff( GetNullDate( xOpt
), nSettle
, nMat
, getDateMode( xOpt
, rOB
) );
614 RETURN_FINITE( fRet
);
618 double SAL_CALL
AnalysisAddIn::getCoupncd( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
619 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
621 double fRet
= GetCoupncd( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
622 RETURN_FINITE( fRet
);
626 double SAL_CALL
AnalysisAddIn::getCoupdays( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
627 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
629 double fRet
= GetCoupdays( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
630 RETURN_FINITE( fRet
);
634 double SAL_CALL
AnalysisAddIn::getCoupdaysnc( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
635 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
637 double fRet
= GetCoupdaysnc( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
638 RETURN_FINITE( fRet
);
642 double SAL_CALL
AnalysisAddIn::getCoupdaybs( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
643 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
645 double fRet
= GetCoupdaybs( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
646 RETURN_FINITE( fRet
);
650 double SAL_CALL
AnalysisAddIn::getCouppcd( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
651 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
653 double fRet
= GetCouppcd( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
654 RETURN_FINITE( fRet
);
658 double SAL_CALL
AnalysisAddIn::getCoupnum( const css::uno::Reference
< css::beans::XPropertySet
>& xOpt
,
659 sal_Int32 nSettle
, sal_Int32 nMat
, sal_Int32 nFreq
, const css::uno::Any
& rOB
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
661 double fRet
= GetCoupnum( GetNullDate( xOpt
), nSettle
, nMat
, nFreq
, getDateMode( xOpt
, rOB
) );
662 RETURN_FINITE( fRet
);
666 double SAL_CALL
AnalysisAddIn::getFvschedule( double fPrinc
, const css::uno::Sequence
< css::uno::Sequence
< double > >& rSchedule
) throw( css::uno::RuntimeException
, css::lang::IllegalArgumentException
, std::exception
)
668 ScaDoubleList aSchedList
;
670 aSchedList
.Append( rSchedule
);
672 for( sal_uInt32 i
= 0; i
< aSchedList
.Count(); ++i
)
673 fPrinc
*= 1.0 + aSchedList
.Get(i
);
675 RETURN_FINITE( fPrinc
);
679 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */