128 lines
2.8 KiB
C++
128 lines
2.8 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;
|
|
int maxPly=50;
|
|
int ply=0;
|
|
|
|
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);
|
|
}
|
|
if(++ply>maxPly)return Rate(0.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(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));
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|