Files
Work/analytic/PORTFOLI.CPP
2024-08-07 09:12:07 -04:00

125 lines
2.7 KiB
C++

#include <analytic/portflio.hpp>
#include <common/stdio.hpp>
#include <common/math.hpp>
Portfolio::Portfolio(void)
{
}
Portfolio::Portfolio(const Portfolio &portfolio)
{ // private implementation
*this=portfolio;
}
Portfolio::~Portfolio()
{
}
Portfolio &Portfolio::operator=(const Portfolio &/*portfolio*/)
{ // private implementation
return *this;
}
BOOL Portfolio::operator==(const Portfolio &portfolio)const
{
return FALSE;
}
double Portfolio::discount(Rate yield,GlobalData<double> &cashflows)
{
double price(0.00);
yield.makeSemiAnnual();
for(int index=0;index<cashflows.size();index++)price+=cashflows[index]/::pow(1.00+yield.decimalRate(),index+1);
return price;
}
Rate Portfolio::wac(void)
{
Rate rate;
double weighted(0.00);
double parValue(0.00);
for(int index=0;index<size();index++)
{
rate=operator[](index)->coupon();
rate.makeAnnual();
weighted+=rate.decimalRate()*operator[](index)->par();
parValue+=operator[](index)->par();
}
weighted/=parValue;
return Rate(weighted*100.00,Annual);
}
Rate Portfolio::discount(double market,GlobalData<double> &cashflows)
{
Rate guess(wac());
Rate maxGuess;
Rate minGuess;
double price;
maxGuess=guess;
minGuess=guess;
maxGuess.rate(guess.rate()+12.00);
minGuess.rate(guess.rate()-12.00);
if(minGuess.rate()<0.00)minGuess.rate(1.00);
while(TRUE)
{
price=discount(guess,cashflows);
if(price==market||(price-market<0.00?market-price:price-market)<1.00)break;
if(market>price)
{
maxGuess=guess;
guess.rate((guess.rate()+minGuess.rate())/2.00);
}
else
{
minGuess=guess;
guess.rate((guess.rate()+maxGuess.rate())/2.00);
}
//printf("calculated price:%lf market price:%lf\n",price,market);
}
return guess;
}
int Portfolio::getCashflows(GlobalData<double> &sumCashflows)
{
GlobalData<GlobalData<double> > cashflows;
int maxFlows(0);
cashflows.size(size());
for(int index=0;index<cashflows.size();index++)operator[](index)->cashflows(cashflows[index]);
for(int index=0;index<cashflows.size();index++)
{
if(!index)maxFlows=cashflows[index].size();
else if(cashflows[index].size()>maxFlows)maxFlows=cashflows[index].size();
}
sumCashflows.size(maxFlows);
for(int pIndex=0;pIndex<cashflows.size();pIndex++)
{
GlobalData<double> &cashflow=cashflows[pIndex];
for(int index=0;index<cashflow.size();index++)sumCashflows[index]=sumCashflows[index]+cashflow[index];
}
return sumCashflows.size();
}
Rate Portfolio::yield(void)
{
GlobalData<double> cashflows;
double price(0.00);
getCashflows(cashflows);
for(int index=0;index<size();index++)price+=operator[](index)->price();
return Rate(discount(price,cashflows));
}