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

148 lines
2.8 KiB
C++

#include <analytic/bond.hpp>
#include <analytic/rate.hpp>
#include <analytic/coupon.hpp>
#include <common/gdata.hpp>
#include <common/math.hpp>
#include <common/stdio.hpp>
Bond::Bond(void)
: Instrument(StraightBond), mPar(0.00), mYTM(0), mYield(0.00)
{
}
Bond::Bond(const Bond &bond)
{
*this=bond;
}
Bond::Bond(double par,const Coupon &coupon,int ytm,double price)
{
Instrument::price(price);
Instrument::coupon(coupon);
Instrument::type(StraightBond);
Bond::par(par);
Bond::ytm(ytm);
Bond::yield(0.00);
}
Bond::~Bond()
{
}
Bond &Bond::operator=(const Bond &bond)
{
par(bond.par());
ytm(bond.ytm());
price(bond.price());
coupon(bond.coupon());
yield(bond.yield());
type(StraightBond);
return *this;
}
BOOL Bond::operator==(const Bond &bond)const
{
return (par()==bond.par()&&
ytm()==bond.ytm()&&
price()==bond.price()&&
coupon()==bond.coupon()&&
yield()==bond.yield()&&
type()==bond.type());
}
double Bond::par(void)const
{
return mPar;
}
void Bond::par(double par)
{
mPar=par;
}
const Rate &Bond::yield(void)const
{
return mYield;
}
void Bond::yield(const Rate &yield)
{
mYield=yield;
}
int Bond::ytm(void)const
{
return mYTM;
}
void Bond::ytm(int ytm)
{
mYTM=ytm;
}
// virtuals
BOOL Bond::cashflows(GlobalData<double> &cashflows)
{
double semiAnnualPmt;
int periods;
Coupon coupon(coupon());
coupon.makeSemiAnnual();
periods=coupon.frequency()*ytm();
semiAnnualPmt=par()*coupon.decimalRate();
cashflows.size(periods);
for(int period=0;period<cashflows.size();period++)cashflows[period]=semiAnnualPmt;
cashflows[periods-1]=cashflows[periods-1]+par();
return TRUE;
}
double Bond::discount(Rate yield)
{
double semiAnnualPmt;
double bondPrice;
int periods;
Coupon coupon(coupon());
Bond::yield(yield);
yield.makeSemiAnnual();
coupon.makeSemiAnnual();
periods=yield.frequency()*ytm();
semiAnnualPmt=par()*coupon.decimalRate();
bondPrice=semiAnnualPmt*((1.00-(1.00/::pow(1.00+yield.decimalRate(),periods)))/yield.decimalRate());
bondPrice+=par()/::pow(1.00+yield.decimalRate(),periods);
price(bondPrice);
return price();
}
Rate Bond::discount(double market)
{
Rate guess(coupon());
Rate maxGuess;
Rate minGuess;
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)
{
discount(guess);
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);
}
yield(guess);
return yield();
}