Line data Source code
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 "analysis.hxx"
21 : #include "analysishelper.hxx"
22 : #include <rtl/math.hxx>
23 :
24 : using namespace sca::analysis;
25 :
26 3 : 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 )
29 : {
30 3 : if( nDate > nFirstPer || fRate <= 0.0 || fRestVal > fCost )
31 0 : throw css::lang::IllegalArgumentException();
32 :
33 3 : double fRet = GetAmordegrc( GetNullDate( xOpt ), fCost, nDate, nFirstPer, fRestVal, fPer, fRate, getDateMode( xOpt, rOB ) );
34 3 : RETURN_FINITE( fRet );
35 : }
36 :
37 :
38 3 : 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 )
41 : {
42 3 : if( nDate > nFirstPer || fRate <= 0.0 || fRestVal > fCost )
43 0 : throw css::lang::IllegalArgumentException();
44 :
45 3 : double fRet = GetAmorlinc( GetNullDate( xOpt ), fCost, nDate, nFirstPer, fRestVal, fPer, fRate, getDateMode( xOpt, rOB ) );
46 3 : RETURN_FINITE( fRet );
47 : }
48 :
49 :
50 3 : 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 )
53 : {
54 3 : double fVal = aAnyConv.getDouble( xOpt, rVal, 1000.0 );
55 :
56 3 : if( fRate <= 0.0 || fVal <= 0.0 || CHK_Freq || nIssue >= nSettle )
57 0 : throw css::lang::IllegalArgumentException();
58 :
59 3 : double fRet = fVal * fRate * GetYearDiff( GetNullDate( xOpt ), nIssue, nSettle, getDateMode( xOpt, rOB ) );
60 3 : RETURN_FINITE( fRet );
61 : }
62 :
63 :
64 3 : 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 )
66 : {
67 3 : double fVal = aAnyConv.getDouble( xOpt, rVal, 1000.0 );
68 :
69 3 : if( fRate <= 0.0 || fVal <= 0.0 || nIssue >= nSettle )
70 0 : throw css::lang::IllegalArgumentException();
71 :
72 3 : double fRet = fVal * fRate * GetYearDiff( GetNullDate( xOpt ), nIssue, nSettle, getDateMode( xOpt, rOB ) );
73 3 : RETURN_FINITE( fRet );
74 : }
75 :
76 :
77 3 : 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 )
79 : {
80 3 : if( fInvest <= 0.0 || fDisc <= 0.0 )
81 0 : throw css::lang::IllegalArgumentException();
82 :
83 3 : double fRet = fInvest / ( 1.0 - ( fDisc * GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) ) ) );
84 3 : RETURN_FINITE( fRet );
85 : }
86 :
87 :
88 3 : 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 )
90 : {
91 3 : if( fPrice <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
92 0 : throw css::lang::IllegalArgumentException();
93 3 : double fRet = ( 1.0 - fPrice / fRedemp ) / GetYearFrac( xOpt, nSettle, nMat, getDateMode( xOpt, rOB ) );
94 3 : RETURN_FINITE( fRet );
95 : }
96 :
97 :
98 3 : 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 )
101 : {
102 3 : if( fCoup < 0.0 || fYield < 0.0 || CHK_Freq || nSettle >= nMat )
103 0 : throw css::lang::IllegalArgumentException();
104 :
105 3 : double fRet = GetDuration( GetNullDate( xOpt ), nSettle, nMat, fCoup, fYield, nFreq, getDateMode( xOpt, rOB ) );
106 3 : RETURN_FINITE( fRet );
107 : }
108 :
109 :
110 0 : double SAL_CALL AnalysisAddIn::getEffect( double fNominal, sal_Int32 nPeriods ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception )
111 : {
112 0 : if( nPeriods < 1 || fNominal <= 0.0 )
113 0 : throw css::lang::IllegalArgumentException();
114 :
115 0 : double fPeriods = nPeriods;
116 :
117 0 : double fRet = pow( 1.0 + fNominal / fPeriods, fPeriods ) - 1.0;
118 0 : RETURN_FINITE( fRet );
119 : }
120 :
121 :
122 0 : 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 )
124 : {
125 : double fRmz, fKapZ;
126 :
127 0 : if( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0.0 || nEndPer > nNumPeriods || nNumPeriods <= 0 ||
128 0 : fVal <= 0.0 || ( nPayType != 0 && nPayType != 1 ) )
129 0 : throw css::lang::IllegalArgumentException();
130 :
131 0 : fRmz = GetRmz( fRate, nNumPeriods, fVal, 0.0, nPayType );
132 :
133 0 : fKapZ = 0.0;
134 :
135 0 : sal_uInt32 nStart = sal_uInt32( nStartPer );
136 0 : sal_uInt32 nEnd = sal_uInt32( nEndPer );
137 :
138 0 : if( nStart == 1 )
139 : {
140 0 : if( nPayType <= 0 )
141 0 : fKapZ = fRmz + fVal * fRate;
142 : else
143 0 : fKapZ = fRmz;
144 :
145 0 : nStart++;
146 : }
147 :
148 0 : for( sal_uInt32 i = nStart ; i <= nEnd ; i++ )
149 : {
150 0 : if( nPayType > 0 )
151 0 : fKapZ += fRmz - ( GetZw( fRate, double( i - 2 ), fRmz, fVal, 1 ) - fRmz ) * fRate;
152 : else
153 0 : fKapZ += fRmz - GetZw( fRate, double( i - 1 ), fRmz, fVal, 0 ) * fRate;
154 : }
155 :
156 0 : RETURN_FINITE( fKapZ );
157 : }
158 :
159 :
160 0 : 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 )
162 : {
163 : double fRmz, fZinsZ;
164 :
165 0 : if( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0.0 || nEndPer > nNumPeriods || nNumPeriods <= 0 ||
166 0 : fVal <= 0.0 || ( nPayType != 0 && nPayType != 1 ) )
167 0 : throw css::lang::IllegalArgumentException();
168 :
169 0 : fRmz = GetRmz( fRate, nNumPeriods, fVal, 0.0, nPayType );
170 :
171 0 : fZinsZ = 0.0;
172 :
173 0 : sal_uInt32 nStart = sal_uInt32( nStartPer );
174 0 : sal_uInt32 nEnd = sal_uInt32( nEndPer );
175 :
176 0 : if( nStart == 1 )
177 : {
178 0 : if( nPayType <= 0 )
179 0 : fZinsZ = -fVal;
180 :
181 0 : nStart++;
182 : }
183 :
184 0 : for( sal_uInt32 i = nStart ; i <= nEnd ; i++ )
185 : {
186 0 : if( nPayType > 0 )
187 0 : fZinsZ += GetZw( fRate, double( i - 2 ), fRmz, fVal, 1 ) - fRmz;
188 : else
189 0 : fZinsZ += GetZw( fRate, double( i - 1 ), fRmz, fVal, 0 );
190 : }
191 :
192 0 : fZinsZ *= fRate;
193 :
194 0 : RETURN_FINITE( fZinsZ );
195 : }
196 :
197 :
198 3 : 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 )
201 : {
202 3 : if( fYield < 0.0 || fRate < 0.0 || fRedemp <= 0.0 || CHK_Freq || nSettle >= nMat )
203 0 : throw css::lang::IllegalArgumentException();
204 :
205 3 : double fRet = getPrice_( GetNullDate( xOpt ), nSettle, nMat, fRate, fYield, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
206 3 : RETURN_FINITE( fRet );
207 : }
208 :
209 :
210 3 : 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 )
212 : {
213 3 : if( fDisc <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
214 0 : throw css::lang::IllegalArgumentException();
215 :
216 3 : double fRet = fRedemp * ( 1.0 - fDisc * GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) ) );
217 3 : RETURN_FINITE( fRet );
218 : }
219 :
220 :
221 3 : 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 )
224 : {
225 3 : if( fRate < 0.0 || fYield < 0.0 || nSettle >= nMat )
226 0 : throw css::lang::IllegalArgumentException();
227 :
228 3 : sal_Int32 nNullDate = GetNullDate( xOpt );
229 3 : sal_Int32 nBase = getDateMode( xOpt, rOB );
230 :
231 3 : double fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
232 3 : double fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
233 3 : double fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
234 :
235 3 : double fRet = 1.0 + fIssMat * fRate;
236 3 : fRet /= 1.0 + fSetMat * fYield;
237 3 : fRet -= fIssSet * fRate;
238 3 : fRet *= 100.0;
239 :
240 3 : RETURN_FINITE( fRet );
241 : }
242 :
243 :
244 3 : 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 )
247 : {
248 3 : if( fCoup < 0.0 || fYield < 0.0 || CHK_Freq )
249 0 : throw css::lang::IllegalArgumentException();
250 :
251 3 : double fRet = GetDuration( GetNullDate( xOpt ), nSettle, nMat, fCoup, fYield, nFreq, getDateMode( xOpt, rOB ) );
252 3 : fRet /= 1.0 + ( fYield / double( nFreq ) );
253 3 : RETURN_FINITE( fRet );
254 : }
255 :
256 :
257 0 : double SAL_CALL AnalysisAddIn::getNominal( double fRate, sal_Int32 nPeriods ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception )
258 : {
259 0 : if( fRate <= 0.0 || nPeriods < 0 )
260 0 : throw css::lang::IllegalArgumentException();
261 :
262 0 : double fPeriods = nPeriods;
263 0 : double fRet = ( pow( fRate + 1.0, 1.0 / fPeriods ) - 1.0 ) * fPeriods;
264 0 : RETURN_FINITE( fRet );
265 : }
266 :
267 :
268 6 : double SAL_CALL AnalysisAddIn::getDollarfr( double fDollarDec, sal_Int32 nFrac ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception )
269 : {
270 6 : if( nFrac <= 0 )
271 0 : throw css::lang::IllegalArgumentException();
272 :
273 : double fInt;
274 6 : double fFrac = nFrac;
275 :
276 6 : double fRet = modf( fDollarDec, &fInt );
277 :
278 6 : fRet *= fFrac;
279 :
280 6 : fRet *= pow( 10.0, -ceil( log10( fFrac ) ) );
281 :
282 6 : fRet += fInt;
283 :
284 6 : RETURN_FINITE( fRet );
285 : }
286 :
287 :
288 6 : double SAL_CALL AnalysisAddIn::getDollarde( double fDollarFrac, sal_Int32 nFrac ) throw( css::uno::RuntimeException, css::lang::IllegalArgumentException, std::exception )
289 : {
290 6 : if( nFrac <= 0 )
291 0 : throw css::lang::IllegalArgumentException();
292 :
293 : double fInt;
294 6 : double fFrac = nFrac;
295 :
296 6 : double fRet = modf( fDollarFrac, &fInt );
297 :
298 6 : fRet /= fFrac;
299 :
300 6 : fRet *= pow( 10.0, ceil( log10( fFrac ) ) );
301 :
302 6 : fRet += fInt;
303 :
304 6 : RETURN_FINITE( fRet );
305 : }
306 :
307 :
308 3 : 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 )
311 : {
312 3 : if( fCoup < 0.0 || fPrice <= 0.0 || fRedemp <= 0.0 || CHK_Freq || nSettle >= nMat )
313 0 : throw css::lang::IllegalArgumentException();
314 :
315 3 : double fRet = getYield_( GetNullDate( xOpt ), nSettle, nMat, fCoup, fPrice, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
316 3 : RETURN_FINITE( fRet );
317 : }
318 :
319 :
320 3 : 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 )
322 : {
323 3 : if( fPrice <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
324 0 : throw css::lang::IllegalArgumentException();
325 :
326 3 : sal_Int32 nNullDate = GetNullDate( xOpt );
327 :
328 3 : double fRet = ( fRedemp / fPrice ) - 1.0;
329 3 : fRet /= GetYearFrac( nNullDate, nSettle, nMat, getDateMode( xOpt, rOB ) );
330 :
331 3 : RETURN_FINITE( fRet );
332 : }
333 :
334 :
335 3 : 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 )
338 : {
339 3 : if( fPrice <= 0.0 || fRate <= 0.0 || nSettle >= nMat )
340 0 : throw css::lang::IllegalArgumentException();
341 :
342 3 : double fRet = GetYieldmat( GetNullDate( xOpt ), nSettle, nMat, nIssue, fRate, fPrice, getDateMode( xOpt, rOB ) );
343 3 : RETURN_FINITE( fRet );
344 : }
345 :
346 :
347 3 : 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 )
349 : {
350 3 : nMat++;
351 :
352 3 : sal_Int32 nDiff = GetDiffDate360( xOpt, nSettle, nMat, true );
353 :
354 3 : if( fDisc <= 0.0 || nSettle >= nMat || nDiff > 360 )
355 0 : throw css::lang::IllegalArgumentException();
356 :
357 3 : double fRet = ( 365 * fDisc ) / ( 360 - ( fDisc * double( nDiff ) ) );
358 3 : RETURN_FINITE( fRet );
359 : }
360 :
361 :
362 3 : 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 )
364 : {
365 3 : if( fDisc <= 0.0 || nSettle > nMat )
366 0 : throw css::lang::IllegalArgumentException();
367 :
368 3 : nMat++;
369 :
370 3 : double fFraction = GetYearFrac( xOpt, nSettle, nMat, 0 ); // method: USA 30/360
371 :
372 : double fDummy;
373 3 : if( modf( fFraction, &fDummy ) == 0.0 )
374 0 : throw css::lang::IllegalArgumentException();
375 :
376 3 : double fRet = 100.0 * ( 1.0 - fDisc * fFraction );
377 3 : RETURN_FINITE( fRet );
378 : }
379 :
380 :
381 3 : 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 )
383 : {
384 3 : sal_Int32 nDiff = GetDiffDate360( xOpt, nSettle, nMat, true );
385 3 : nDiff++;
386 :
387 3 : if( fPrice <= 0.0 || nSettle >= nMat || nDiff > 360 )
388 0 : throw css::lang::IllegalArgumentException();
389 :
390 3 : double fRet = 100.0;
391 3 : fRet /= fPrice;
392 3 : fRet--;
393 3 : fRet /= double( nDiff );
394 3 : fRet *= 360.0;
395 :
396 3 : RETURN_FINITE( fRet );
397 : }
398 :
399 : // Encapsulation violation: We *know* that GetOddfprice() always
400 : // throws.
401 :
402 : SAL_WNOUNREACHABLE_CODE_PUSH
403 :
404 0 : 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 )
407 : {
408 0 : if( fRate < 0.0 || fYield < 0.0 || CHK_Freq || nMat <= nFirstCoup || nFirstCoup <= nSettle || nSettle <= nIssue )
409 0 : throw css::lang::IllegalArgumentException();
410 :
411 0 : double fRet = GetOddfprice( GetNullDate( xOpt ), nSettle, nMat, nIssue, nFirstCoup, fRate, fYield, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
412 0 : RETURN_FINITE( fRet );
413 : }
414 :
415 : SAL_WNOUNREACHABLE_CODE_POP
416 :
417 : // Encapsulation violation: We *know* that Getoddfyield() always
418 : // throws.
419 :
420 : SAL_WNOUNREACHABLE_CODE_PUSH
421 :
422 0 : 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 )
425 : {
426 0 : if( fRate < 0.0 || fPrice <= 0.0 || CHK_Freq || nMat <= nFirstCoup || nFirstCoup <= nSettle || nSettle <= nIssue )
427 0 : throw css::lang::IllegalArgumentException();
428 :
429 : double fRet = GetOddfyield( GetNullDate( xOpt ), nSettle, nMat, nIssue, nFirstCoup, fRate, fPrice, fRedemp, nFreq,
430 0 : getDateMode( xOpt, rOB ) );
431 0 : RETURN_FINITE( fRet );
432 : }
433 :
434 : SAL_WNOUNREACHABLE_CODE_POP
435 :
436 6 : 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 )
439 : {
440 6 : if( fRate < 0.0 || fYield < 0.0 || CHK_Freq || nMat <= nSettle || nSettle <= nLastInterest )
441 0 : throw css::lang::IllegalArgumentException();
442 :
443 : double fRet = GetOddlprice( GetNullDate( xOpt ), nSettle, nMat, nLastInterest, fRate, fYield, fRedemp, nFreq,
444 6 : getDateMode( xOpt, rOB ) );
445 6 : RETURN_FINITE( fRet );
446 : }
447 :
448 :
449 3 : 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 )
452 : {
453 3 : if( fRate < 0.0 || fPrice <= 0.0 || CHK_Freq || nMat <= nSettle || nSettle <= nLastInterest )
454 0 : throw css::lang::IllegalArgumentException();
455 :
456 : double fRet = GetOddlyield( GetNullDate( xOpt ), nSettle, nMat, nLastInterest, fRate, fPrice, fRedemp, nFreq,
457 3 : getDateMode( xOpt, rOB ) );
458 3 : RETURN_FINITE( fRet );
459 : }
460 :
461 : // XIRR helper functions
462 :
463 : #define V_(i) (rValues.Get(i))
464 : #define D_(i) (rDates.Get(i))
465 :
466 : /** Calculates the resulting amount for the passed interest rate and the given XIRR parameters. */
467 15 : static double lcl_sca_XirrResult( const ScaDoubleList& rValues, const ScaDoubleList& rDates, double fRate )
468 : {
469 : /* V_0 ... V_n = input values.
470 : D_0 ... D_n = input dates.
471 : R = input interest rate.
472 :
473 : r := R+1
474 : E_i := (D_i-D_0) / 365
475 :
476 : n V_i n V_i
477 : f(R) = SUM ------- = V_0 + SUM ------- .
478 : i=0 r^E_i i=1 r^E_i
479 : */
480 15 : double D_0 = D_(0);
481 15 : double r = fRate + 1.0;
482 15 : double fResult = V_(0);
483 75 : for( sal_uInt32 i = 1, nCount = rValues.Count(); i < nCount; ++i )
484 60 : fResult += V_(i) / pow( r, (D_(i) - D_0) / 365.0 );
485 15 : return fResult;
486 : }
487 :
488 : /** Calculates the first derivation of lcl_sca_XirrResult(). */
489 15 : static double lcl_sca_XirrResult_Deriv1( const ScaDoubleList& rValues, const ScaDoubleList& rDates, double fRate )
490 : {
491 : /* V_0 ... V_n = input values.
492 : D_0 ... D_n = input dates.
493 : R = input interest rate.
494 :
495 : r := R+1
496 : E_i := (D_i-D_0) / 365
497 :
498 : n V_i
499 : f'(R) = [ V_0 + SUM ------- ]'
500 : i=1 r^E_i
501 :
502 : n V_i n E_i V_i
503 : = 0 + SUM -E_i ----------- r' = - SUM ----------- .
504 : i=1 r^(E_i+1) i=1 r^(E_i+1)
505 : */
506 15 : double D_0 = D_(0);
507 15 : double r = fRate + 1.0;
508 15 : double fResult = 0.0;
509 75 : for( sal_uInt32 i = 1, nCount = rValues.Count(); i < nCount; ++i )
510 : {
511 60 : double E_i = (D_(i) - D_0) / 365.0;
512 60 : fResult -= E_i * V_(i) / pow( r, E_i + 1.0 );
513 : }
514 15 : return fResult;
515 : }
516 :
517 : #undef V_
518 : #undef D_
519 :
520 : // XIRR calculation
521 :
522 3 : 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 )
524 : {
525 6 : ScaDoubleList aValues, aDates;
526 3 : aValues.Append( rValues );
527 3 : aDates.Append( rDates );
528 :
529 3 : if( (aValues.Count() < 2) || (aValues.Count() != aDates.Count()) )
530 0 : throw css::lang::IllegalArgumentException();
531 :
532 : // result interest rate, initialized with passed guessed rate, or 10%
533 3 : double fResultRate = aAnyConv.getDouble( xOpt, rGuessRate, 0.1 );
534 3 : if( fResultRate <= -1 )
535 0 : throw css::lang::IllegalArgumentException();
536 :
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;
541 :
542 : // Newton's method - try to find a fResultRate, so that lcl_sca_XirrResult() returns 0.
543 3 : sal_Int32 nIter = 0;
544 : double fResultValue;
545 3 : sal_Int32 nIterScan = 0;
546 3 : bool bContLoop = false;
547 3 : bool bResultRateScanEnd = false;
548 :
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
553 3 : do
554 : {
555 3 : if (nIterScan >=1)
556 0 : fResultRate = -0.99 + (nIterScan -1)* 0.01;
557 15 : do
558 : {
559 15 : fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
560 15 : double fNewRate = fResultRate - fResultValue / lcl_sca_XirrResult_Deriv1( aValues, aDates, fResultRate );
561 15 : double fRateEps = fabs( fNewRate - fResultRate );
562 15 : fResultRate = fNewRate;
563 15 : bContLoop = (fRateEps > fMaxEps) && (fabs( fResultValue ) > fMaxEps);
564 : }
565 15 : while( bContLoop && (++nIter < nMaxIter) );
566 3 : nIter = 0;
567 9 : if ( ::rtl::math::isNan(fResultRate) || ::rtl::math::isInf(fResultRate)
568 6 : ||::rtl::math::isNan(fResultValue) || ::rtl::math::isInf(fResultValue))
569 0 : bContLoop = true;
570 :
571 3 : ++nIterScan;
572 3 : bResultRateScanEnd = (nIterScan >= 200);
573 : }
574 0 : while(bContLoop && !bResultRateScanEnd);
575 :
576 3 : if( bContLoop )
577 0 : throw css::lang::IllegalArgumentException();
578 6 : RETURN_FINITE( fResultRate );
579 : }
580 :
581 :
582 3 : 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 )
584 : {
585 3 : ScaDoubleList aValList;
586 6 : ScaDoubleList aDateList;
587 :
588 3 : aValList.Append( rValues );
589 3 : aDateList.Append( rDates );
590 :
591 3 : sal_Int32 nNum = aValList.Count();
592 :
593 3 : if( nNum != sal_Int32( aDateList.Count() ) || nNum < 2 )
594 0 : throw css::lang::IllegalArgumentException();
595 :
596 3 : double fRet = 0.0;
597 3 : double fNull = aDateList.Get( 0 );
598 3 : fRate++;
599 :
600 18 : for( sal_Int32 i = 0 ; i < nNum ; i++ )
601 15 : fRet += aValList.Get( i ) / ( pow( fRate, ( aDateList.Get( i ) - fNull ) / 365.0 ) );
602 :
603 6 : RETURN_FINITE( fRet );
604 : }
605 :
606 :
607 3 : 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 )
609 : {
610 3 : if( fInvest <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
611 0 : throw css::lang::IllegalArgumentException();
612 :
613 3 : double fRet = ( ( fRedemp / fInvest ) - 1.0 ) / GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) );
614 3 : RETURN_FINITE( fRet );
615 : }
616 :
617 :
618 3 : 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 )
620 : {
621 3 : double fRet = GetCoupncd( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
622 3 : RETURN_FINITE( fRet );
623 : }
624 :
625 :
626 3 : 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 )
628 : {
629 3 : double fRet = GetCoupdays( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
630 3 : RETURN_FINITE( fRet );
631 : }
632 :
633 :
634 3 : 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 )
636 : {
637 3 : double fRet = GetCoupdaysnc( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
638 3 : RETURN_FINITE( fRet );
639 : }
640 :
641 :
642 3 : 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 )
644 : {
645 3 : double fRet = GetCoupdaybs( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
646 3 : RETURN_FINITE( fRet );
647 : }
648 :
649 :
650 0 : 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 )
652 : {
653 0 : double fRet = GetCouppcd( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
654 0 : RETURN_FINITE( fRet );
655 : }
656 :
657 :
658 6 : 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 )
660 : {
661 6 : double fRet = GetCoupnum( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
662 6 : RETURN_FINITE( fRet );
663 : }
664 :
665 :
666 3 : 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 )
667 : {
668 3 : ScaDoubleList aSchedList;
669 :
670 3 : aSchedList.Append( rSchedule );
671 :
672 12 : for( sal_uInt32 i = 0; i < aSchedList.Count(); ++i )
673 9 : fPrinc *= 1.0 + aSchedList.Get(i);
674 :
675 3 : RETURN_FINITE( fPrinc );
676 : }
677 :
678 :
679 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|