Repo.cpp

This example evaluates a repo on a fixed-coupon bond.

00001 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 
00020 /* a Repo calculation done using the FixedCouponBondForward class
00021    cf. aaBondFwd() repo example at
00022    http://www.fincad.com/support/developerFunc/mathref/BFWD.htm
00023 
00024    This repo is set up to use the repo rate to do all discounting
00025    (including the underlying bond income). Forward delivery price is
00026    also obtained using this repo rate. All this is done by supplying
00027    the FixedCouponBondForward constructor with a flat repo
00028    YieldTermStructure.
00029 */
00030 
00031 // the only header you need to use QuantLib
00032 #define BOOST_LIB_DIAGNOSTIC
00033 #  include <ql/quantlib.hpp>
00034 #undef BOOST_LIB_DIAGNOSTIC
00035 
00036 #ifdef BOOST_MSVC
00037 /* Uncomment the following lines to unmask floating-point
00038    exceptions. Warning: unpredictable results can arise...
00039 
00040    See http://www.wilmott.com/messageview.cfm?catid=10&threadid=9481
00041    Is there anyone with a definitive word about this?
00042 */
00043 // #include <float.h>
00044 // namespace { unsigned int u = _controlfp(_EM_INEXACT, _MCW_EM); }
00045 #endif
00046 
00047 #include <boost/timer.hpp>
00048 #include <iostream>
00049 
00050 using namespace std;
00051 using namespace QuantLib;
00052 
00053 #if defined(QL_ENABLE_SESSIONS)
00054 namespace QuantLib {
00055 
00056     Integer sessionId() { return 0; }
00057 
00058 }
00059 #endif
00060 
00061 int main(int, char* []) {
00062 
00063     try {
00064         QL_IO_INIT
00065 
00066         boost::timer timer;
00067         std::cout << std::endl;
00068 
00069         Date repoSettlementDate(14,February,2000);;
00070         Date repoDeliveryDate(15,August,2000);
00071         Rate repoRate = 0.05;
00072         DayCounter repoDayCountConvention = Actual360();
00073         Integer repoSettlementDays = 0;
00074         Compounding repoCompounding = Simple;
00075         Frequency repoCompoundFreq = Annual;
00076 
00077         // assume a ten year bond- this is irrelevant
00078         Date bondIssueDate(15,September,1995);
00079         Date bondDatedDate(15,September,1995);
00080         Date bondMaturityDate(15,September,2005);
00081         Real bondCoupon = 0.08;
00082         Frequency bondCouponFrequency = Semiannual;
00083         // unknown what calendar fincad is using
00084         Calendar bondCalendar = NullCalendar();
00085         DayCounter bondDayCountConvention = Thirty360(Thirty360::BondBasis);
00086         // unknown what fincad is using. this may affect accrued calculation
00087         Integer bondSettlementDays = 0;
00088         BusinessDayConvention bondBusinessDayConvention = Unadjusted;
00089         Real bondCleanPrice = 89.97693786;
00090         Real bondRedemption = 100.0;
00091         Real faceAmount = 100.0;
00092 
00093 
00094         Settings::instance().evaluationDate() = repoSettlementDate;
00095 
00096         Handle<YieldTermStructure> bondCurve;
00097         bondCurve.linkTo(boost::shared_ptr<YieldTermStructure>(
00098                                        new FlatForward(repoSettlementDate,
00099                                                        .01, // dummy rate
00100                                                        bondDayCountConvention,
00101                                                        Compounded,
00102                                                        bondCouponFrequency)));
00103 
00104 
00105         boost::shared_ptr<FixedCouponBond> bond(
00106                      new FixedCouponBond(faceAmount,
00107                                          bondIssueDate,
00108                                          bondDatedDate,
00109                                          bondMaturityDate,
00110                                          bondSettlementDays,
00111                                          std::vector<Rate>(1,bondCoupon),
00112                                          bondCouponFrequency,
00113                                          bondCalendar,
00114                                          bondDayCountConvention,
00115                                          bondBusinessDayConvention,
00116                                          bondBusinessDayConvention,
00117                                          bondRedemption,
00118                                          bondCurve));
00119 
00120 
00121         bondCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
00122                    new FlatForward(repoSettlementDate,
00123                                    bond->yield(bondCleanPrice,Compounded),
00124                                    bondDayCountConvention,
00125                                    Compounded,
00126                                    bondCouponFrequency)));
00127 
00128         Position::Type fwdType = Position::Long;
00129         double dummyStrike = 91.5745;
00130 
00131         Handle<YieldTermStructure> repoCurve;
00132         repoCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
00133                                        new FlatForward(repoSettlementDate,
00134                                                        repoRate,
00135                                                        repoDayCountConvention,
00136                                                        repoCompounding,
00137                                                        repoCompoundFreq)));
00138 
00139 
00140         FixedCouponBondForward bondFwd(repoSettlementDate,
00141                                        repoDeliveryDate,
00142                                        fwdType,
00143                                        dummyStrike,
00144                                        repoSettlementDays,
00145                                        repoDayCountConvention,
00146                                        bondCalendar,
00147                                        bondBusinessDayConvention,
00148                                        bond,
00149                                        repoCurve,
00150                                        repoCurve);
00151 
00152 
00153         cout << "Underlying bond clean price: "
00154              << bond->cleanPrice()
00155              << endl;
00156         cout << "Underlying bond dirty price: "
00157              << bond->dirtyPrice()
00158              << endl;
00159         cout << "Underlying bond accrued at settlement: "
00160              << bond->accruedAmount(repoSettlementDate)
00161              << endl;
00162         cout << "Underlying bond accrued at delivery:   "
00163              << bond->accruedAmount(repoDeliveryDate)
00164              << endl;
00165         cout << "Underlying bond spot income: "
00166              << bondFwd.spotIncome(repoCurve)
00167              << endl;
00168         cout << "Underlying bond fwd income:  "
00169              << bondFwd.spotIncome(repoCurve)/
00170                 repoCurve->discount(repoDeliveryDate)
00171              << endl;
00172         cout << "Repo strike: "
00173              << dummyStrike
00174              << endl;
00175         cout << "Repo NPV:    "
00176              << bondFwd.NPV()
00177              << endl;
00178         cout << "Repo clean forward price: "
00179              << bondFwd.cleanForwardPrice()
00180              << endl;
00181         cout << "Repo dirty forward price: "
00182              << bondFwd.forwardPrice()
00183              << endl;
00184         cout << "Repo implied yield: "
00185              << bondFwd.impliedYield(bond->dirtyPrice(),
00186                                      dummyStrike,
00187                                      repoSettlementDate,
00188                                      repoCompounding,
00189                                      repoDayCountConvention)
00190              << endl;
00191         cout << "Market repo rate:   "
00192              << repoCurve->zeroRate(repoDeliveryDate,
00193                                     repoDayCountConvention,
00194                                     repoCompounding,
00195                                     repoCompoundFreq)
00196              << endl
00197              << endl;
00198 
00199         cout << "Compare with example given at \n"
00200              << "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm"
00201              <<  endl;
00202         cout << "Clean forward price = 88.2408"
00203              <<  endl
00204              <<  endl;
00205         cout << "In that example, it is unknown what bond calendar they are\n"
00206              << "using, as well as settlement Days. For that reason, I have\n"
00207              << "made the simplest possible assumptions here: NullCalendar\n"
00208              << "and 0 settlement days."
00209              << endl;
00210 
00211 
00212         Real seconds = timer.elapsed();
00213         Integer hours = int(seconds/3600);
00214         seconds -= hours * 3600;
00215         Integer minutes = int(seconds/60);
00216         seconds -= minutes * 60;
00217         cout << " \nRun completed in ";
00218         if (hours > 0)
00219             cout << hours << " h ";
00220         if (hours > 0 || minutes > 0)
00221             cout << minutes << " m ";
00222         cout << fixed << setprecision(0)
00223              << seconds << " s\n" << endl;
00224 
00225         return 0;
00226 
00227     } catch (exception& e) {
00228         cout << e.what() << endl;
00229         return 1;
00230     } catch (...) {
00231         cout << "unknown error" << endl;
00232         return 1;
00233     }
00234 }
00235