Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

binomialTree.cpp

Go to the documentation of this file.
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         // set root node to initial stock price, dimension claim process but set
00124         // all values to zero
00125         _stockProcess[0].resize(1, _So);
00126         _claimProcess[0].resize(1, 0);
00127 
00128         // iterate forward in time, applying the appropriate multipliers
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         // check payoff at leaf nodes
00197         for (Natural branch = 0; branch <= _n; branch++) {
00198                 _claimProcess[_n][branch] =
00199                         thePayoff.Call(_stockProcess[_n][branch]);
00200         }
00201 
00202         // now work backwards discounting expected values
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     // check payoff at leaf nodes - don't apply call/putprice
00219         for (Natural branch = 0; branch <= _n; branch++) {
00220                 _claimProcess[_n][branch] = 
00221                         thePayoff.Convertible(
00222                                 _stockProcess[_n][branch], ConversionRatio, 100);
00223         }
00224 
00225         // now work back through the tree
00226         for (Integer timestep = _n - 1; timestep >= 0; timestep--) {
00227                 for (Integer branch = 0; branch <= timestep; branch++) {
00228 
00229                         // first calculate bond price as discounted expected value
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                         // now check other possibilities unique to convertibles:
00236                         //  conversion to stock, call, put
00237                         _claimProcess[timestep][branch] = 
00238                                 thePayoff.Convertible(_stockProcess[timestep][branch], 
00239                                         ConversionRatio, 
00240                                         _claimProcess[timestep][branch], 
00241                                         CallPrice, 
00242                                         PutPrice);
00243                 } // for each branch
00244         } // for times from n -1 to 0
00245 }

Note: Generated nightly - reload for latest version
Generated on Thu Dec 22 23:12:35 2005 for terreneuve by doxygen 1.3.6