00001 #include ".\binomialTree.h"
00002
00003 binomialTree::binomialTree(void) :
00004 _So(BT_DEFAULT_SO),
00005 _sigma(BT_DEFAULT_SIGMA),
00006 _maturity(BT_DEFAULT_MATURITY),
00007 _n(BT_DEFAULT_STEPS),
00008 _stockProcess(BT_DEFAULT_STEPS + 1),
00009 _claimProcess(BT_DEFAULT_STEPS + 1),
00010 _discountFactor(BT_DEFAULT_STEPS),
00011 _q(BT_DEFAULT_STEPS) {
00012 _dt = _maturity/_n;
00013 _u = exp(_sigma * sqrt(_dt));
00014 _d = 1/_u;
00015
00016 setClaimVariables(BT_DEFAULT_RATE);
00017 constructStockProcess();
00018 }
00019
00020 binomialTree::binomialTree(Real So,
00021 Real r,
00022 Real sigma,
00023 Real T,
00024 Natural n) :
00025 _So(So), _sigma(sigma), _maturity(T), _n(n),
00026 _stockProcess(n + 1),
00027 _claimProcess(n + 1),
00028 _discountFactor(n),
00029 _q(n) {
00030 _dt = T/n;
00031 _u = exp(sigma * sqrt(_dt));
00032 _d = 1/_u;
00033
00034 setClaimVariables(r);
00035 constructStockProcess();
00036 }
00037
00038 binomialTree::binomialTree(const asset& theStock,
00039 yieldCurve& yc,
00040 Real T,
00041 Natural n) :
00042 _So(theStock.getPrice()), _sigma(theStock.GetVolatility()),
00043 _maturity(T), _n(n),
00044 _stockProcess(n + 1),
00045 _claimProcess(n + 1),
00046 _discountFactor(n),
00047 _q(n) {
00048 _dt = T/n;
00049 _u = exp(_sigma * sqrt(_dt));
00050 _d = 1/_u;
00051
00052 setClaimVariables(yc);
00053 constructStockProcess();
00054 }
00055
00056 binomialTree::binomialTree(Real So,
00057 Real r,
00058 Real sigma,
00059 Real T,
00060 Natural n,
00061 Real u,
00062 Real d) :
00063 _So(So), _sigma(sigma), _maturity(T), _n(n), _u(u), _d(d),
00064 _stockProcess(n + 1),
00065 _claimProcess(n + 1),
00066 _discountFactor(n),
00067 _q(n) {
00068 _dt = T/n;
00069 setClaimVariables(r);
00070 constructStockProcess();
00071 }
00072
00073 void
00074 binomialTree::setClaimVariables(Real constantRate) {
00075 Real df = exp(-1 * constantRate * _dt);
00076 Real q = (exp(constantRate * _dt) - _d)/(_u - _d);
00077 for (Natural timestep = 0; timestep < _n; timestep++) {
00078 _discountFactor[timestep] = df;
00079 _q[timestep] = q;
00080 }
00081 }
00082
00083 void
00084 binomialTree::setClaimVariables(yieldCurve& yc) {
00085 for (Natural timestep = 0; timestep < _n; timestep++) {
00086 _discountFactor[timestep] = yc.forwardDiscountFactor(timestep * _dt, _dt);
00087 _q[timestep] = ((1/_discountFactor[timestep]) - _d)/(_u - _d);
00088 }
00089 }
00090
00091 binomialTree::binomialTree(const binomialTree &rhs) {
00092 copyObj(rhs);
00093 }
00094
00095 binomialTree &
00096 binomialTree::operator=(const binomialTree &rhs) {
00097 copyObj(rhs);
00098 return *this;
00099 }
00100
00101 void
00102 binomialTree::copyObj(const binomialTree &rhs) {
00103 _So = rhs._So;
00104 _sigma = rhs._sigma;
00105 _maturity = rhs._maturity;
00106 _n = rhs._n;
00107 _dt = rhs._dt;
00108 _u = rhs._u;
00109 _d = rhs._d;
00110 _discountFactor = rhs._discountFactor;
00111 _stockProcess = rhs._stockProcess;
00112 _claimProcess = rhs._claimProcess;
00113 _discountFactor = rhs._discountFactor;
00114 _q = rhs._q;
00115 }
00116
00117 binomialTree::~binomialTree(void) {
00118
00119 }
00120
00121 void
00122 binomialTree::constructStockProcess(void) {
00123
00124
00125 _stockProcess[0].resize(1, _So);
00126 _claimProcess[0].resize(1, 0);
00127
00128
00129 for (Natural i = 1; i <= _n; i++) {
00130 _stockProcess[i].resize(i + 1);
00131 _claimProcess[i].resize(i + 1, 0);
00132
00133 _stockProcess[i][0] = _stockProcess[i - 1][0] * _d;
00134 for (Natural j = 1; j <= i; j++) {
00135 _stockProcess[i][j] = _stockProcess[i - 1][j - 1] * _u;
00136 }
00137 }
00138 }
00139
00140 const valarray<Real>*
00141 binomialTree::getStockProcess(Natural step) {
00142 valarray<Real> *result =
00143 (step <= _n ? &_stockProcess[step] : NULL);
00144
00145 return result;
00146 }
00147
00148 const valarray<Real>*
00149 binomialTree::getClaimProcess(Natural step) {
00150 valarray<Real> *result =
00151 (step <= _n ? &_claimProcess[step] : NULL);
00152
00153 return result;
00154 }
00155
00156 Real
00157 binomialTree::getPrice() {
00158 return (_n > 0 ? _claimProcess[0][0] : 0);
00159 }
00160
00161 ostream&
00162 operator << (ostream &os, const binomialTree &bt) {
00163 os << "binomialtree parameters - " << endl
00164 << " So = " << bt.getSo()
00165 << ", sigma = " << bt.getSigma()
00166 << ", maturity = " << bt.getMaturity() << endl
00167 << " steps = " << bt.getSteps()
00168 << ", u = " << bt._u
00169 << ", d = " << bt._d << endl
00170 << " discountFactors: " << valarrayRealToString(bt._discountFactor) << endl
00171 << " q (up move prob): " << valarrayRealToString(bt._q) << endl << endl;
00172
00173 os << "stock process" << endl;
00174 for (Natural timestep = 0; timestep <= bt._n; timestep++) {
00175 os << bt._stockProcess[timestep][0];
00176 for (Natural branch = 1; branch <= timestep; branch++) {
00177 os << "," << bt._stockProcess[timestep][branch];
00178 }
00179 os << endl;
00180 }
00181
00182 os << "claim process (price at the top)" << endl;
00183 for (Natural timestep = 0; timestep <= bt._n; timestep++) {
00184 os << bt._claimProcess[timestep][0];
00185 for (Natural branch = 1; branch <= timestep; branch++) {
00186 os << "," << bt._claimProcess[timestep][branch];
00187 }
00188 os << endl;
00189 }
00190
00191 return os;
00192 }
00193
00194 void
00195 binomialTree::runEngineCall(PayOff thePayoff) {
00196
00197 for (Natural branch = 0; branch <= _n; branch++) {
00198 _claimProcess[_n][branch] =
00199 thePayoff.Call(_stockProcess[_n][branch]);
00200 }
00201
00202
00203 for (Integer timestep = _n - 1; timestep >= 0; timestep--) {
00204 for (Integer branch = 0; branch <= timestep; branch++) {
00205 _claimProcess[timestep][branch] =
00206 _discountFactor[timestep] *
00207 ((_q[timestep] * _claimProcess[timestep + 1][branch + 1]) +
00208 ((1 - _q[timestep]) * _claimProcess[timestep + 1][branch]));
00209 }
00210 }
00211 }
00212
00213 void
00214 binomialTree::runEngineConvertibleBond(PayOff thePayoff,
00215 Real ConversionRatio,
00216 Real CallPrice,
00217 Real PutPrice) {
00218
00219 for (Natural branch = 0; branch <= _n; branch++) {
00220 _claimProcess[_n][branch] =
00221 thePayoff.Convertible(
00222 _stockProcess[_n][branch], ConversionRatio, 100);
00223 }
00224
00225
00226 for (Integer timestep = _n - 1; timestep >= 0; timestep--) {
00227 for (Integer branch = 0; branch <= timestep; branch++) {
00228
00229
00230 _claimProcess[timestep][branch] =
00231 _discountFactor[timestep] *
00232 ((_q[timestep] * _claimProcess[timestep + 1][branch + 1]) +
00233 ((1 - _q[timestep]) * _claimProcess[timestep + 1][branch]));
00234
00235
00236
00237 _claimProcess[timestep][branch] =
00238 thePayoff.Convertible(_stockProcess[timestep][branch],
00239 ConversionRatio,
00240 _claimProcess[timestep][branch],
00241 CallPrice,
00242 PutPrice);
00243 }
00244 }
00245 }