00001 #include ".\convertiblebond.h"
00002 #include ".\binomialTree.h"
00003 #include "../PartA/MonteCarlo1/PayOff.h"
00004
00005 convertiblebond::convertiblebond(asset Stock,
00006 riskybond Bond,
00007 Real conversionRatio,
00008 Natural nSteps,
00009 Real callPrice,
00010 Real putPrice) :
00011 riskybond(Bond),
00012 _bond(Bond),
00013 _stock(Stock),
00014 _conversionRatio(conversionRatio),
00015 _n(nSteps),
00016 _callPrice(callPrice),
00017 _putPrice(putPrice) {
00018 _priceCached =
00019 _deltaCached =
00020 _interestRateDeltaCached =
00021 _gammaCached =
00022 _btCached =
00023 false;
00024
00025
00026
00027 }
00028
00029 convertiblebond::~convertiblebond(void) {
00030 }
00031
00032 Real
00033 convertiblebond::fairvalue(Date today){
00034 if ((_priceCached) && (_datepriceCached == today)) {
00035 return _price;
00036 }
00037
00038 if (_btCached) {
00039 delete _bt;
00040 }
00041 _bt =
00042 new binomialTree(_stock,
00043 _yc, getMaturityInYears(today), _n);
00044 PayOff *payoff =
00045 new PayOff();
00046
00047 _bt->runEngineConvertibleBond(*payoff,
00048 _conversionRatio / getFaceAmount() * 100,
00049 _callPrice,
00050 _putPrice);
00051
00052 _btCached = true;
00053
00054
00055
00056 const valarray<Real> *prices = _bt->getClaimProcess(0);
00057 _price = (*prices)[0];
00058 _priceCached = true;
00059 _datepriceCached = today;
00060
00061 return _price;
00062 }
00063
00064 Real
00065 convertiblebond::delta(Date today) const {
00066 if ((_deltaCached) && (_datedeltaCached == today)) {
00067 return _delta;
00068 }
00069
00070
00071 Real So = _stock.getPrice();
00072
00073 Real price = const_cast<convertiblebond *>(this)->fairvalue(today);
00074 Real Soplus = So * (1 + 0.01);
00075 asset *stockDelta = new asset(Soplus, _stock.GetVolatility());
00076
00077
00078 convertiblebond *cbDelta =
00079 new convertiblebond(*stockDelta,
00080 _bond,
00081 _conversionRatio,
00082 _n,
00083 _callPrice,
00084 _putPrice);
00085
00086 Real priceplus = cbDelta->fairvalue(today);
00087
00088 _delta = (priceplus - price)/(Soplus - So);
00089 _deltaCached = true;
00090 _datedeltaCached = today;
00091
00092 delete cbDelta;
00093 delete stockDelta;
00094
00095 return _delta;
00096 }
00097
00098 convertiblebond
00099 convertiblebond::shiftedcbond(Real shift) {
00100 riskybond shiftedrbond = _bond.shiftedbond(shift);
00101 convertiblebond shiftedcbond =
00102 convertiblebond(_stock, shiftedrbond, _conversionRatio, _n, _callPrice, _putPrice);
00103 return shiftedcbond;
00104 }
00105
00106 Real
00107 convertiblebond::interestRateDelta(Date today) const {
00108 if ((_interestRateDeltaCached) && (_dateinterestRateDeltaCached == today)) {
00109 return _interestRateDelta;
00110 }
00111
00112 convertiblebond cb =
00113 const_cast<convertiblebond *>(this)->shiftedcbond(0.001);
00114 _interestRateDelta = (cb.fairvalue(today) -
00115 const_cast<convertiblebond *>(this)->fairvalue(today))/0.001;
00116 _interestRateDeltaCached = true;
00117 _dateinterestRateDeltaCached = today;
00118
00119 return _interestRateDelta;
00120 }
00121
00122 Real
00123 convertiblebond::gamma(Date today) const {
00124 if ((_gammaCached) && (_dategammaCached == today)) {
00125 return _gamma;
00126 }
00127
00128
00129 Real So = _stock.getPrice();
00130 Real deltao = delta(today);
00131 Real Soplus = So * (1 + 0.01);
00132 asset *stockDelta = new asset(Soplus, _stock.GetVolatility());
00133
00134
00135 convertiblebond *cbDelta =
00136 new convertiblebond(*stockDelta,
00137 _bond,
00138 _conversionRatio,
00139 _n,
00140 _callPrice,
00141 _putPrice);
00142
00143 Real deltaplus = cbDelta->delta(today);
00144
00145 _gamma = (deltaplus - deltao)/(Soplus - So);
00146 _gammaCached = true;
00147 _dategammaCached = today;
00148
00149 delete cbDelta;
00150 delete stockDelta;
00151
00152 return _gamma;
00153 }
00154
00155 ostream&
00156 operator << (ostream &os, convertiblebond &cb) {
00157 os << "convertible bond - price: " << cb.fairvalue() << endl;
00158 os << " issue: " << cb._issue.toString() << endl;
00159 os << " maturity: " << cb._maturity.toString() << endl;
00160 os << " face: " << cb._faceamount << endl;
00161 os << " stock price: " << cb._stock.getPrice() << endl;
00162 os << " stock vol: " << cb._stock.GetVolatility() << endl;
00163 os << " conversion ratio: " << cb._conversionRatio << endl;
00164 os << " callprice: ";
00165 if (cb._callPrice == CB_DEFAULT_CALLPRICE) {
00166 os << "n/a" << endl;
00167 } else {
00168 os << cb._callPrice << endl;
00169 }
00170 os << " putprice: ";
00171 if (cb._putPrice == CB_DEFAULT_PUTPRICE) {
00172 os << "n/a" << endl;
00173 } else {
00174 os << cb._putPrice << endl;
00175 }
00176 os << " nsteps: " << cb._n << endl;
00177 os << " delta: " << cb.delta() << endl;
00178 os << " paritydelta: " << cb.parityDelta() << endl;
00179 os << " interestratedelta: " << cb.interestRateDelta() << endl;
00180 os << " gamma: " << cb.gamma() << endl;
00181 os << " paritygamma: " << cb.parityGamma() << endl;
00182 if (cb._btCached) {
00183 os << " underlying binomial tree: " << endl;
00184 os << cb._bt << endl;
00185 }
00186
00187 return os;
00188 }