sorry it was the false code!!
here ist the code:
2015-04-02 20:28 GMT+02:00 Driss Ben Zoubeir <[email protected]>:
> Hi,
> I am trying to correct a bug in the XIRR function (it is rather improve
> than correct). The idea behind the correction is the following:
>
> 1- try to find a solution (XIRR) using the guess value given by the user
> or using the default value
> 2-if the try with those values does not lead to a solution so begin to
> scan for a guess value from -0.99 to +0.99 with 0.01 step until one get a
> Guess Value which leads to Solution.
>
> first to experiments I have written a code but It seems that I have a
> problem with the outer while loop. Can someone give me a hint where is the
> problem?
>
> regards
> Driss
>
#include <iostream>
#include <math.h>
using namespace std;
double getXirr(double *aValues, double *aDates, double fRate);
/** Calculates the resulting amount for the passed interest rate and the given XIRR parameters. */
double lcl_sca_XirrResult( double *rValues, double *rDates, double fRate );
/** Calculates the first derivation of lcl_sca_XirrResult(). */
double lcl_sca_XirrResult_Deriv1( double *rValues, double *rDates, double fRate );
int arrSize = 13;
int main()
{
double xirr;
double Dates[13] = {39356, 39387, 39417, 39448, 39479, 39508,
39539, 39569, 39600, 39630, 39661, 39692, 39722};
double Values[13] = {100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100,
-800};
// double Dates[5] = {39448,39508,39751,39859,39904};
// double Values[5] = {-10000, 2750, 4250, 3250,2750};
//double* ptrDates = Dates;
//double* ptrValues = Values;
xirr = getXirr(Values, Dates, 0.1);
cout <<"XIRR =" << xirr;
return 0;
}
// XIRR calculation
double getXirr(double *aValues, double *aDates, double fRate)
{
// maximum epsilon for end of iteration
static const double fMaxEps = 1e-10;
// maximum number of iterations
static const int nMaxIter = 50;
// Newton's method - try to find a fResultRate, so that lcl_sca_XirrResult() returns 0.
double fNewRate, fRateEps, fResultValue;
int nIter = 0;
int nIterScan = 0;
double fResultRate = fRate;
bool bContLoop = false;
bool fResultRateScanEnd = false;
// First the inner while-loop will be executed using the default Value fResultRate or the user guessed fResultRate
// if that does not deliver a solution for the Newton's method then the range from -0.99 to +0.99 will be scanned with
// step size of 0.01 to find fResultRate's value which can deliver a solution
do{
if (nIterScan >=1)
fResultRate = -0.99 + (nIterScan -1)* 0.01;
do
{
fResultValue = lcl_sca_XirrResult( aValues, aDates, fResultRate );
fNewRate = fResultRate - fResultValue / lcl_sca_XirrResult_Deriv1( aValues, aDates, fResultRate );
fRateEps = fabs(fNewRate - fResultRate );
fResultRate = fNewRate;
bContLoop = (fRateEps > fMaxEps) && (fabs( fResultValue ) > fMaxEps);
}
while (bContLoop && (++nIter < nMaxIter));
nIter = 0;
++nIterScan;
fResultRateScanEnd = (nIterScan == 199);
}
while (bContLoop && !fResultRateScanEnd);
cout << "bCount = "<<bContLoop<<endl;
cout << "nIterScan = "<< nIterScan<<endl;
cout << "fResultRateScanEnd = "<< fResultRateScanEnd<<endl;
//if( bContLoop )
// cout<< "if condition";
return fResultRate;
}
/** Calculates the resulting amount for the passed interest rate and the given XIRR parameters. */
double lcl_sca_XirrResult( double *rValues, double *rDates, double fRate )
{
/* V_0 ... V_n = input values.
D_0 ... D_n = input dates.
R = input interest rate.
r := R+1
E_i := (D_i-D_0) / 365
n V_i n V_i
f(R) = SUM ------- = V_0 + SUM ------- .
i=0 r^E_i i=1 r^E_i
*/
double D_0 = *rDates;
double r = fRate + 1.0;
double fResult = *rValues;
for( int i = 1; i < arrSize; ++i )
fResult += rValues[i] / pow( r, (rDates[i] - D_0) / 365.0 );
return fResult;
}
/** Calculates the first derivation of lcl_sca_XirrResult(). */
double lcl_sca_XirrResult_Deriv1( double *rValues, double *rDates, double fRate )
{
/* V_0 ... V_n = input values.
D_0 ... D_n = input dates.
R = input interest rate.
r := R+1
E_i := (D_i-D_0) / 365
n V_i
f'(R) = [ V_0 + SUM ------- ]'
i=1 r^E_i
n V_i n E_i V_i
= 0 + SUM -E_i ----------- r' = - SUM ----------- .
i=1 r^(E_i+1) i=1 r^(E_i+1)
*/
double D_0 = rDates[0];
double r = fRate + 1.0;
double fResult = 0;
for( int i = 1; i < arrSize; ++i )
{
double E_i = (rDates[i] - D_0) / 365.0;
fResult -= E_i * rValues[i] / pow( r, E_i + 1.0 );
}
return fResult;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]