LCOV - code coverage report
Current view: top level - libreoffice/scaddins/source/analysis - financial.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 271 0.0 %
Date: 2012-12-27 Functions: 0 39 0.0 %
Legend: Lines: hit not hit

          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             : 
      25             : 
      26           0 : double SAL_CALL AnalysisAddIn::getAmordegrc( constREFXPS& xOpt,
      27             :     double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal,
      28             :     double fPer, double fRate, const ANY& rOB ) THROWDEF_RTE_IAE
      29             : {
      30           0 :     if( nDate > nFirstPer || fRate <= 0.0 || fRestVal > fCost )
      31           0 :         THROW_IAE;
      32             : 
      33           0 :     double fRet = GetAmordegrc( GetNullDate( xOpt ), fCost, nDate, nFirstPer, fRestVal, fPer, fRate, getDateMode( xOpt, rOB ) );
      34           0 :     RETURN_FINITE( fRet );
      35             : }
      36             : 
      37             : 
      38           0 : double SAL_CALL AnalysisAddIn::getAmorlinc( constREFXPS& xOpt,
      39             :     double fCost, sal_Int32 nDate, sal_Int32 nFirstPer, double fRestVal,
      40             :     double fPer, double fRate, const ANY& rOB ) THROWDEF_RTE_IAE
      41             : {
      42           0 :     if( nDate > nFirstPer || fRate <= 0.0 || fRestVal > fCost )
      43           0 :         THROW_IAE;
      44             : 
      45           0 :     double fRet = GetAmorlinc( GetNullDate( xOpt ), fCost, nDate, nFirstPer, fRestVal, fPer, fRate, getDateMode( xOpt, rOB ) );
      46           0 :     RETURN_FINITE( fRet );
      47             : }
      48             : 
      49             : 
      50           0 : double SAL_CALL AnalysisAddIn::getAccrint( constREFXPS& xOpt,
      51             :     sal_Int32 nIssue, sal_Int32 /*nFirstInter*/, sal_Int32 nSettle, double fRate,
      52             :     const ANY &rVal, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
      53             : {
      54           0 :     double      fVal = aAnyConv.getDouble( xOpt, rVal, 1000.0 );
      55             : 
      56           0 :     if( fRate <= 0.0 || fVal <= 0.0 || CHK_Freq || nIssue >= nSettle )
      57           0 :         THROW_IAE;
      58             : 
      59           0 :     double fRet = fVal * fRate * GetYearDiff( GetNullDate( xOpt ), nIssue, nSettle, getDateMode( xOpt, rOB ) );
      60           0 :     RETURN_FINITE( fRet );
      61             : }
      62             : 
      63             : 
      64           0 : double SAL_CALL AnalysisAddIn::getAccrintm( constREFXPS& xOpt,
      65             :     sal_Int32 nIssue, sal_Int32 nSettle, double fRate, const ANY& rVal, const ANY& rOB ) THROWDEF_RTE_IAE
      66             : {
      67           0 :     double      fVal = aAnyConv.getDouble( xOpt, rVal, 1000.0 );
      68             : 
      69           0 :     if( fRate <= 0.0 || fVal <= 0.0 || nIssue >= nSettle )
      70           0 :         THROW_IAE;
      71             : 
      72           0 :     double fRet = fVal * fRate * GetYearDiff( GetNullDate( xOpt ), nIssue, nSettle, getDateMode( xOpt, rOB ) );
      73           0 :     RETURN_FINITE( fRet );
      74             : }
      75             : 
      76             : 
      77           0 : double SAL_CALL AnalysisAddIn::getReceived( constREFXPS& xOpt,
      78             :     sal_Int32 nSettle, sal_Int32 nMat, double fInvest, double fDisc, const ANY& rOB ) THROWDEF_RTE_IAE
      79             : {
      80           0 :     if( fInvest <= 0.0 || fDisc <= 0.0 )
      81           0 :         THROW_IAE;
      82             : 
      83           0 :     double fRet = fInvest / ( 1.0 - ( fDisc * GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) ) ) );
      84           0 :     RETURN_FINITE( fRet );
      85             : }
      86             : 
      87             : 
      88           0 : double SAL_CALL AnalysisAddIn::getDisc( constREFXPS& xOpt,
      89             :     sal_Int32 nSettle, sal_Int32 nMat, double fPrice, double fRedemp, const ANY& rOB ) THROWDEF_RTE_IAE
      90             : {
      91           0 :     if( fPrice <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
      92           0 :         THROW_IAE;
      93           0 :     double fRet = ( 1.0 - fPrice / fRedemp ) / GetYearFrac( xOpt, nSettle, nMat, getDateMode( xOpt, rOB ) );
      94           0 :     RETURN_FINITE( fRet );
      95             : }
      96             : 
      97             : 
      98           0 : double SAL_CALL AnalysisAddIn::getDuration( constREFXPS& xOpt,
      99             :     sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fYield, sal_Int32 nFreq, const ANY& rOB )
     100             :     THROWDEF_RTE_IAE
     101             : {
     102           0 :     if( fCoup < 0.0 || fYield < 0.0 || CHK_Freq || nSettle >= nMat )
     103           0 :         THROW_IAE;
     104             : 
     105           0 :     double fRet = GetDuration( GetNullDate( xOpt ),  nSettle, nMat, fCoup, fYield, nFreq, getDateMode( xOpt, rOB ) );
     106           0 :     RETURN_FINITE( fRet );
     107             : }
     108             : 
     109             : 
     110           0 : double SAL_CALL AnalysisAddIn::getEffect( double fNominal, sal_Int32 nPeriods ) THROWDEF_RTE_IAE
     111             : {
     112           0 :     if( nPeriods < 1 || fNominal <= 0.0 )
     113           0 :         THROW_IAE;
     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 ) THROWDEF_RTE_IAE
     124             : {
     125             :     double fRmz, fKapZ;
     126             : 
     127           0 :     if( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0.0 || nEndPer > nNumPeriods  || nNumPeriods <= 0 ||
     128             :         fVal <= 0.0 || ( nPayType != 0 && nPayType != 1 ) )
     129           0 :         THROW_IAE;
     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 ) THROWDEF_RTE_IAE
     162             : {
     163             :     double fRmz, fZinsZ;
     164             : 
     165           0 :     if( nStartPer < 1 || nEndPer < nStartPer || fRate <= 0.0 || nEndPer > nNumPeriods  || nNumPeriods <= 0 ||
     166             :         fVal <= 0.0 || ( nPayType != 0 && nPayType != 1 ) )
     167           0 :         THROW_IAE;
     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           0 : double SAL_CALL AnalysisAddIn::getPrice( constREFXPS& xOpt,
     199             :     sal_Int32 nSettle, sal_Int32 nMat, double fRate, double fYield, double fRedemp, sal_Int32 nFreq,
     200             :     const ANY& rOB ) THROWDEF_RTE_IAE
     201             : {
     202           0 :     if( fYield < 0.0 || fRate < 0.0 || fRedemp <= 0.0 || CHK_Freq || nSettle >= nMat )
     203           0 :         THROW_IAE;
     204             : 
     205           0 :     double fRet = getPrice_( GetNullDate( xOpt ), nSettle, nMat, fRate, fYield, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
     206           0 :     RETURN_FINITE( fRet );
     207             : }
     208             : 
     209             : 
     210           0 : double SAL_CALL AnalysisAddIn::getPricedisc( constREFXPS& xOpt,
     211             :     sal_Int32 nSettle, sal_Int32 nMat, double fDisc, double fRedemp, const ANY& rOB ) THROWDEF_RTE_IAE
     212             : {
     213           0 :     if( fDisc <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
     214           0 :         THROW_IAE;
     215             : 
     216           0 :     double fRet = fRedemp * ( 1.0 - fDisc * GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) ) );
     217           0 :     RETURN_FINITE( fRet );
     218             : }
     219             : 
     220             : 
     221           0 : double SAL_CALL AnalysisAddIn::getPricemat( constREFXPS& xOpt,
     222             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, double fRate, double fYield, const ANY& rOB )
     223             :     THROWDEF_RTE_IAE
     224             : {
     225           0 :     if( fRate < 0.0 || fYield < 0.0 || nSettle >= nMat )
     226           0 :         THROW_IAE;
     227             : 
     228           0 :     sal_Int32   nNullDate = GetNullDate( xOpt );
     229           0 :     sal_Int32   nBase = getDateMode( xOpt, rOB );
     230             : 
     231           0 :     double      fIssMat = GetYearFrac( nNullDate, nIssue, nMat, nBase );
     232           0 :     double      fIssSet = GetYearFrac( nNullDate, nIssue, nSettle, nBase );
     233           0 :     double      fSetMat = GetYearFrac( nNullDate, nSettle, nMat, nBase );
     234             : 
     235           0 :     double      fRet = 1.0 + fIssMat * fRate;
     236           0 :     fRet /= 1.0 + fSetMat * fYield;
     237           0 :     fRet -= fIssSet * fRate;
     238           0 :     fRet *= 100.0;
     239             : 
     240           0 :     RETURN_FINITE( fRet );
     241             : }
     242             : 
     243             : 
     244           0 : double SAL_CALL AnalysisAddIn::getMduration( constREFXPS& xOpt,
     245             :     sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fYield, sal_Int32 nFreq, const ANY& rOB )
     246             :     THROWDEF_RTE_IAE
     247             : {
     248           0 :     if( fCoup < 0.0 || fYield < 0.0 || CHK_Freq )
     249           0 :         THROW_IAE;
     250             : 
     251           0 :     double      fRet = GetDuration( GetNullDate( xOpt ),  nSettle, nMat, fCoup, fYield, nFreq, getDateMode( xOpt, rOB ) );
     252           0 :     fRet /= 1.0 + ( fYield / double( nFreq ) );
     253           0 :     RETURN_FINITE( fRet );
     254             : }
     255             : 
     256             : 
     257           0 : double SAL_CALL AnalysisAddIn::getNominal( double fRate, sal_Int32 nPeriods ) THROWDEF_RTE_IAE
     258             : {
     259           0 :     if( fRate <= 0.0 || nPeriods < 0 )
     260           0 :         THROW_IAE;
     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           0 : double SAL_CALL AnalysisAddIn::getDollarfr( double fDollarDec, sal_Int32 nFrac ) THROWDEF_RTE_IAE
     269             : {
     270           0 :     if( nFrac <= 0 )
     271           0 :         THROW_IAE;
     272             : 
     273             :     double  fInt;
     274           0 :     double  fFrac = nFrac;
     275             : 
     276           0 :     double  fRet = modf( fDollarDec, &fInt );
     277             : 
     278           0 :     fRet *= fFrac;
     279             : 
     280           0 :     fRet *= pow( 10.0, -ceil( log10( fFrac ) ) );
     281             : 
     282           0 :     fRet += fInt;
     283             : 
     284           0 :     RETURN_FINITE( fRet );
     285             : }
     286             : 
     287             : 
     288           0 : double SAL_CALL AnalysisAddIn::getDollarde( double fDollarFrac, sal_Int32 nFrac ) THROWDEF_RTE_IAE
     289             : {
     290           0 :     if( nFrac <= 0 )
     291           0 :         THROW_IAE;
     292             : 
     293             :     double  fInt;
     294           0 :     double  fFrac = nFrac;
     295             : 
     296           0 :     double  fRet = modf( fDollarFrac, &fInt );
     297             : 
     298           0 :     fRet /= fFrac;
     299             : 
     300           0 :     fRet *= pow( 10.0, ceil( log10( fFrac ) ) );
     301             : 
     302           0 :     fRet += fInt;
     303             : 
     304           0 :     RETURN_FINITE( fRet );
     305             : }
     306             : 
     307             : 
     308           0 : double SAL_CALL AnalysisAddIn::getYield( constREFXPS& xOpt,
     309             :     sal_Int32 nSettle, sal_Int32 nMat, double fCoup, double fPrice, double fRedemp, sal_Int32 nFreq, const ANY& rOB )
     310             :     THROWDEF_RTE_IAE
     311             : {
     312           0 :     if( fCoup < 0.0 || fPrice <= 0.0 || fRedemp <= 0.0 || CHK_Freq || nSettle >= nMat )
     313           0 :         THROW_IAE;
     314             : 
     315           0 :     double fRet = getYield_( GetNullDate( xOpt ), nSettle, nMat, fCoup, fPrice, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
     316           0 :     RETURN_FINITE( fRet );
     317             : }
     318             : 
     319             : 
     320           0 : double SAL_CALL AnalysisAddIn::getYielddisc( constREFXPS& xOpt,
     321             :     sal_Int32 nSettle, sal_Int32 nMat, double fPrice, double fRedemp, const ANY& rOB ) THROWDEF_RTE_IAE
     322             : {
     323           0 :     if( fPrice <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
     324           0 :         THROW_IAE;
     325             : 
     326           0 :     sal_Int32   nNullDate = GetNullDate( xOpt );
     327             : 
     328           0 :     double fRet = ( fRedemp / fPrice ) - 1.0;
     329           0 :     fRet /= GetYearFrac( nNullDate, nSettle, nMat, getDateMode( xOpt, rOB ) );
     330             : 
     331           0 :     RETURN_FINITE( fRet );
     332             : }
     333             : 
     334             : 
     335           0 : double SAL_CALL AnalysisAddIn::getYieldmat( constREFXPS& xOpt,
     336             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, double fRate, double fPrice, const ANY& rOB )
     337             :     THROWDEF_RTE_IAE
     338             : {
     339           0 :     if( fPrice <= 0.0 || fRate <= 0.0 || nSettle >= nMat )
     340           0 :         THROW_IAE;
     341             : 
     342           0 :     double fRet = GetYieldmat( GetNullDate( xOpt ),  nSettle, nMat, nIssue, fRate, fPrice, getDateMode( xOpt, rOB ) );
     343           0 :     RETURN_FINITE( fRet );
     344             : }
     345             : 
     346             : 
     347           0 : double SAL_CALL AnalysisAddIn::getTbilleq( constREFXPS& xOpt,
     348             :     sal_Int32 nSettle, sal_Int32 nMat, double fDisc ) THROWDEF_RTE_IAE
     349             : {
     350           0 :     nMat++;
     351             : 
     352           0 :     sal_Int32   nDiff = GetDiffDate360( xOpt, nSettle, nMat, sal_True );
     353             : 
     354           0 :     if( fDisc <= 0.0 || nSettle >= nMat || nDiff > 360 )
     355           0 :         THROW_IAE;
     356             : 
     357           0 :     double fRet = ( 365 * fDisc ) / ( 360 - ( fDisc * double( nDiff ) ) );
     358           0 :     RETURN_FINITE( fRet );
     359             : }
     360             : 
     361             : 
     362           0 : double SAL_CALL AnalysisAddIn::getTbillprice( constREFXPS& xOpt,
     363             :     sal_Int32 nSettle, sal_Int32 nMat, double fDisc ) THROWDEF_RTE_IAE
     364             : {
     365           0 :     if( fDisc <= 0.0 || nSettle > nMat )
     366           0 :         THROW_IAE;
     367             : 
     368           0 :     nMat++;
     369             : 
     370           0 :     double  fFraction = GetYearFrac( xOpt, nSettle, nMat, 0 );  // method: USA 30/360
     371             : 
     372             :     double  fDummy;
     373           0 :     if( modf( fFraction, &fDummy ) == 0.0 )
     374           0 :         THROW_IAE;
     375             : 
     376           0 :     double fRet = 100.0 * ( 1.0 - fDisc * fFraction );
     377           0 :     RETURN_FINITE( fRet );
     378             : }
     379             : 
     380             : 
     381           0 : double SAL_CALL AnalysisAddIn::getTbillyield( constREFXPS& xOpt, sal_Int32 nSettle, sal_Int32 nMat, double fPrice )
     382             :     THROWDEF_RTE_IAE
     383             : {
     384           0 :     sal_Int32   nDiff = GetDiffDate360( xOpt, nSettle, nMat, sal_True );
     385           0 :     nDiff++;
     386             : 
     387           0 :     if( fPrice <= 0.0 || nSettle >= nMat || nDiff > 360 )
     388           0 :         THROW_IAE;
     389             : 
     390           0 :     double      fRet = 100.0;
     391           0 :     fRet /= fPrice;
     392           0 :     fRet--;
     393           0 :     fRet /= double( nDiff );
     394           0 :     fRet *= 360.0;
     395             : 
     396           0 :     RETURN_FINITE( fRet );
     397             : }
     398             : 
     399             : 
     400           0 : double SAL_CALL AnalysisAddIn::getOddfprice( constREFXPS& 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 ANY& rOB ) THROWDEF_RTE_IAE
     403             : {
     404           0 :     if( fRate < 0.0 || fYield < 0.0 || CHK_Freq || nMat <= nFirstCoup || nFirstCoup <= nSettle || nSettle <= nIssue )
     405           0 :         THROW_IAE;
     406             : 
     407           0 :     double fRet = GetOddfprice( GetNullDate( xOpt ), nSettle, nMat, nIssue, nFirstCoup, fRate, fYield, fRedemp, nFreq, getDateMode( xOpt, rOB ) );
     408           0 :     RETURN_FINITE( fRet );
     409             : }
     410             : 
     411             : 
     412           0 : double SAL_CALL AnalysisAddIn::getOddfyield( constREFXPS& xOpt,
     413             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nIssue, sal_Int32 nFirstCoup,
     414             :     double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     415             : {
     416           0 :     if( fRate < 0.0 || fPrice <= 0.0 || CHK_Freq || nMat <= nFirstCoup || nFirstCoup <= nSettle || nSettle <= nIssue )
     417           0 :         THROW_IAE;
     418             : 
     419             :     double fRet = GetOddfyield( GetNullDate( xOpt ), nSettle, nMat, nIssue, nFirstCoup, fRate, fPrice, fRedemp, nFreq,
     420           0 :                         getDateMode( xOpt, rOB ) );
     421           0 :     RETURN_FINITE( fRet );
     422             : }
     423             : 
     424             : 
     425           0 : double SAL_CALL AnalysisAddIn::getOddlprice( constREFXPS& xOpt,
     426             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
     427             :     double fRate, double fYield, double fRedemp, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     428             : {
     429           0 :     if( fRate < 0.0 || fYield < 0.0 || CHK_Freq || nMat <= nSettle || nSettle <= nLastInterest )
     430           0 :         THROW_IAE;
     431             : 
     432             :     double fRet = GetOddlprice( GetNullDate( xOpt ), nSettle, nMat, nLastInterest, fRate, fYield, fRedemp, nFreq,
     433           0 :                         getDateMode( xOpt, rOB ) );
     434           0 :     RETURN_FINITE( fRet );
     435             : }
     436             : 
     437             : 
     438           0 : double SAL_CALL AnalysisAddIn::getOddlyield( constREFXPS& xOpt,
     439             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nLastInterest,
     440             :     double fRate, double fPrice, double fRedemp, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     441             : {
     442           0 :     if( fRate < 0.0 || fPrice <= 0.0 || CHK_Freq || nMat <= nSettle || nSettle <= nLastInterest )
     443           0 :         THROW_IAE;
     444             : 
     445             :     double fRet = GetOddlyield( GetNullDate( xOpt ), nSettle, nMat, nLastInterest, fRate, fPrice, fRedemp, nFreq,
     446           0 :                         getDateMode( xOpt, rOB ) );
     447           0 :     RETURN_FINITE( fRet );
     448             : }
     449             : 
     450             : 
     451             : // ============================================================================
     452             : // XIRR helper functions
     453             : 
     454             : #define V_(i) (*rValues.Get(i))
     455             : #define D_(i) (*rDates.Get(i))
     456             : 
     457             : /** Calculates the resulting amount for the passed interest rate and the given XIRR parameters. */
     458           0 : static double lcl_sca_XirrResult( const ScaDoubleList& rValues, const ScaDoubleList& rDates, double fRate )
     459             : {
     460             :     /*  V_0 ... V_n = input values.
     461             :         D_0 ... D_n = input dates.
     462             :         R           = input interest rate.
     463             : 
     464             :         r   := R+1
     465             :         E_i := (D_i-D_0) / 365
     466             : 
     467             :                     n    V_i                n    V_i
     468             :         f(R)  =  SUM   -------  =  V_0 + SUM   ------- .
     469             :                    i=0  r^E_i              i=1  r^E_i
     470             :     */
     471           0 :     double D_0 = D_(0);
     472           0 :     double r = fRate + 1.0;
     473           0 :     double fResult = V_(0);
     474           0 :     for( sal_uInt32 i = 1, nCount = rValues.Count(); i < nCount; ++i )
     475           0 :         fResult += V_(i) / pow( r, (D_(i) - D_0) / 365.0 );
     476           0 :     return fResult;
     477             : }
     478             : 
     479             : /** Calculates the first derivation of lcl_sca_XirrResult(). */
     480           0 : static double lcl_sca_XirrResult_Deriv1( const ScaDoubleList& rValues, const ScaDoubleList& rDates, double fRate )
     481             : {
     482             :     /*  V_0 ... V_n = input values.
     483             :         D_0 ... D_n = input dates.
     484             :         R           = input interest rate.
     485             : 
     486             :         r   := R+1
     487             :         E_i := (D_i-D_0) / 365
     488             : 
     489             :                              n    V_i
     490             :         f'(R)  =  [ V_0 + SUM   ------- ]'
     491             :                             i=1  r^E_i
     492             : 
     493             :                          n           V_i                 n    E_i V_i
     494             :                =  0 + SUM   -E_i ----------- r'  =  - SUM   ----------- .
     495             :                         i=1       r^(E_i+1)             i=1  r^(E_i+1)
     496             :     */
     497           0 :     double D_0 = D_(0);
     498           0 :     double r = fRate + 1.0;
     499           0 :     double fResult = 0.0;
     500           0 :     for( sal_uInt32 i = 1, nCount = rValues.Count(); i < nCount; ++i )
     501             :     {
     502           0 :         double E_i = (D_(i) - D_0) / 365.0;
     503           0 :         fResult -= E_i * V_(i) / pow( r, E_i + 1.0 );
     504             :     }
     505           0 :     return fResult;
     506             : }
     507             : 
     508             : #undef V_
     509             : #undef D_
     510             : 
     511             : 
     512             : // ----------------------------------------------------------------------------
     513             : // XIRR calculation
     514             : 
     515           0 : double SAL_CALL AnalysisAddIn::getXirr(
     516             :     constREFXPS& xOpt, const SEQSEQ( double )& rValues, const SEQSEQ( sal_Int32 )& rDates, const ANY& rGuessRate ) THROWDEF_RTE_IAE
     517             : {
     518           0 :     ScaDoubleList aValues, aDates;
     519           0 :     aValues.Append( rValues );
     520           0 :     aDates.Append( rDates );
     521             : 
     522           0 :     if( (aValues.Count() < 2) || (aValues.Count() != aDates.Count()) )
     523           0 :         THROW_IAE;
     524             : 
     525             :     // result interest rate, initialized with passed guessed rate, or 10%
     526           0 :     double fResultRate = aAnyConv.getDouble( xOpt, rGuessRate, 0.1 );
     527           0 :     if( fResultRate <= -1 )
     528           0 :         THROW_IAE;
     529             : 
     530             :     // maximum epsilon for end of iteration
     531             :     static const double fMaxEps = 1e-10;
     532             :     // maximum number of iterations
     533             :     static const sal_Int32 nMaxIter = 50;
     534             : 
     535             :     // Newton's method - try to find a fResultRate, so that lcl_sca_XirrResult() returns 0.
     536             :     double fNewRate, fRateEps, fResultValue;
     537           0 :     sal_Int32 nIter = 0;
     538             :     bool bContLoop;
     539           0 :     do
     540             :     {
     541           0 :         fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
     542           0 :         fNewRate = fResultRate - fResultValue / lcl_sca_XirrResult_Deriv1( aValues, aDates, fResultRate );
     543           0 :         fRateEps = fabs( fNewRate - fResultRate );
     544           0 :         fResultRate = fNewRate;
     545           0 :         bContLoop = (fRateEps > fMaxEps) && (fabs( fResultValue ) > fMaxEps);
     546             :     }
     547             :     while( bContLoop && (++nIter < nMaxIter) );
     548             : 
     549           0 :     if( bContLoop )
     550           0 :         THROW_IAE;
     551           0 :     RETURN_FINITE( fResultRate );
     552             : }
     553             : 
     554             : 
     555             : // ============================================================================
     556             : 
     557           0 : double SAL_CALL AnalysisAddIn::getXnpv(
     558             :     double fRate, const SEQSEQ( double )& rValues, const SEQSEQ( sal_Int32 )& rDates ) THROWDEF_RTE_IAE
     559             : {
     560           0 :     ScaDoubleList aValList;
     561           0 :     ScaDoubleList aDateList;
     562             : 
     563           0 :     aValList.Append( rValues );
     564           0 :     aDateList.Append( rDates );
     565             : 
     566           0 :     sal_Int32           nNum = aValList.Count();
     567             : 
     568           0 :     if( nNum != sal_Int32( aDateList.Count() ) || nNum < 2 )
     569           0 :         THROW_IAE;
     570             : 
     571           0 :     double              fRet = 0.0;
     572           0 :     double              fNull = *aDateList.Get( 0 );
     573           0 :     fRate++;
     574             : 
     575           0 :     for( sal_Int32 i = 0 ; i < nNum ; i++ )
     576           0 :         fRet += *aValList.Get( i ) / ( pow( fRate, ( *aDateList.Get( i ) - fNull ) / 365.0 ) );
     577             : 
     578           0 :     RETURN_FINITE( fRet );
     579             : }
     580             : 
     581             : 
     582           0 : double SAL_CALL AnalysisAddIn::getIntrate( constREFXPS& xOpt,
     583             :     sal_Int32 nSettle, sal_Int32 nMat, double fInvest, double fRedemp, const ANY& rOB ) THROWDEF_RTE_IAE
     584             : {
     585           0 :     if( fInvest <= 0.0 || fRedemp <= 0.0 || nSettle >= nMat )
     586           0 :         THROW_IAE;
     587             : 
     588           0 :     double fRet = ( ( fRedemp / fInvest ) - 1.0 ) / GetYearDiff( GetNullDate( xOpt ), nSettle, nMat, getDateMode( xOpt, rOB ) );
     589           0 :     RETURN_FINITE( fRet );
     590             : }
     591             : 
     592             : 
     593           0 : double SAL_CALL AnalysisAddIn::getCoupncd( constREFXPS& xOpt,
     594             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     595             : {
     596           0 :     double fRet = GetCoupncd( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
     597           0 :     RETURN_FINITE( fRet );
     598             : }
     599             : 
     600             : 
     601           0 : double SAL_CALL AnalysisAddIn::getCoupdays( constREFXPS& xOpt,
     602             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     603             : {
     604           0 :     double fRet = GetCoupdays( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
     605           0 :     RETURN_FINITE( fRet );
     606             : }
     607             : 
     608             : 
     609           0 : double SAL_CALL AnalysisAddIn::getCoupdaysnc( constREFXPS& xOpt,
     610             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     611             : {
     612           0 :     double fRet = GetCoupdaysnc( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
     613           0 :     RETURN_FINITE( fRet );
     614             : }
     615             : 
     616             : 
     617           0 : double SAL_CALL AnalysisAddIn::getCoupdaybs( constREFXPS& xOpt,
     618             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     619             : {
     620           0 :     double fRet = GetCoupdaybs( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
     621           0 :     RETURN_FINITE( fRet );
     622             : }
     623             : 
     624             : 
     625           0 : double SAL_CALL AnalysisAddIn::getCouppcd( constREFXPS& xOpt,
     626             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     627             : {
     628           0 :     double fRet = GetCouppcd( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
     629           0 :     RETURN_FINITE( fRet );
     630             : }
     631             : 
     632             : 
     633           0 : double SAL_CALL AnalysisAddIn::getCoupnum( constREFXPS& xOpt,
     634             :     sal_Int32 nSettle, sal_Int32 nMat, sal_Int32 nFreq, const ANY& rOB ) THROWDEF_RTE_IAE
     635             : {
     636           0 :     double fRet = GetCoupnum( GetNullDate( xOpt ), nSettle, nMat, nFreq, getDateMode( xOpt, rOB ) );
     637           0 :     RETURN_FINITE( fRet );
     638             : }
     639             : 
     640             : 
     641           0 : double SAL_CALL AnalysisAddIn::getFvschedule( double fPrinc, const SEQSEQ( double )& rSchedule ) THROWDEF_RTE_IAE
     642             : {
     643           0 :     ScaDoubleList aSchedList;
     644             : 
     645           0 :     aSchedList.Append( rSchedule );
     646             : 
     647           0 :     for( const double* p = aSchedList.First() ; p ; p = aSchedList.Next() )
     648           0 :         fPrinc *= 1.0 + *p;
     649             : 
     650           0 :     RETURN_FINITE( fPrinc );
     651             : }
     652             : 
     653             : 
     654             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10