Files
Work/cashflow/irr.cpp
2024-08-07 09:12:07 -04:00

90 lines
1.6 KiB
C++

#include <cashflow/irr.hpp>
double IRR::IRR_ERROR=-1E30;
int IRR::IRR_MAX_ITERATIONS=50;
double IRR::IRR_ACCURACY=1.0E-5;
double IRR::irr(Array<double> &cashflows)
{
double x1=0.00;
double x2=.20;
double dx=0.00;
double f1;
double f2;
double f;
double rtb;
double xmid;
double fmid;
int index;
// create initial bracket with root somewhere between bot,top
f1=pv(cashflows,x1);
f2=pv(cashflows,x2);
for(index=0;index<IRR_MAX_ITERATIONS;index++)
{
if((f1*f2)<0.00)break;
if(fabs(f1)<fabs(f2))
{
f1=pv(cashflows,x1+=1.6*(x1-x2));
}
else
{
f2=pv(cashflows,x2+=1.6*(x2-x1));
}
}
if(f2*f1>0.00)return IRR_ERROR;
f=pv(cashflows,x1);
if(f<0.00)
{
rtb=x1;
dx=x2-x1;
}
else
{
rtb=x2;
dx=x1-x2;
}
for(index=0;index<IRR_MAX_ITERATIONS;index++)
{
dx*=.50;
xmid=rtb+dx;
fmid=pv(cashflows,xmid);
if(fmid<=0.00)rtb=xmid;
if((fabs(fmid)<IRR_ACCURACY)||(fabs(dx)<IRR_ACCURACY))
{
return xmid;
}
}
return IRR_ERROR;
}
double IRR::npv(Array<double> &cashflows,double rate)
{
double npv=0.00;
for(int index=0;index<cashflows.size();index++)
{
npv+=cashflows[index]*pow(1+rate,index); // exp(-rate*(index+1)));
}
return npv;
}
double IRR::pv(Array<double> &cashflows,double rate)
{
double pv=0.00;
for(int index=0;index<cashflows.size();index++)
{
pv+=(cashflows[index]*exp(-rate*(index+1)));
}
return pv;
}
double IRR::pvD(Array<double> &cashflows,double rate)
{
double pv=0.00;
for(int index=0;index<cashflows.size();index++)
{
pv+=cashflows[index]/pow(1+rate,index+1);
}
return pv;
}