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 FixedRateBondForward 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 FixedRateBondForward 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 
00065         boost::timer timer;
00066         std::cout << std::endl;
00067 
00068         Date repoSettlementDate(14,February,2000);;
00069         Date repoDeliveryDate(15,August,2000);
00070         Rate repoRate = 0.05;
00071         DayCounter repoDayCountConvention = Actual360();
00072         Integer repoSettlementDays = 0;
00073         Compounding repoCompounding = Simple;
00074         Frequency repoCompoundFreq = Annual;
00075 
00076         // assume a ten year bond- this is irrelevant
00077         Date bondIssueDate(15,September,1995);
00078         Date bondDatedDate(15,September,1995);
00079         Date bondMaturityDate(15,September,2005);
00080         Real bondCoupon = 0.08;
00081         Frequency bondCouponFrequency = Semiannual;
00082         // unknown what calendar fincad is using
00083         Calendar bondCalendar = NullCalendar();
00084         DayCounter bondDayCountConvention = Thirty360(Thirty360::BondBasis);
00085         // unknown what fincad is using. this may affect accrued calculation
00086         Integer bondSettlementDays = 0;
00087         BusinessDayConvention bondBusinessDayConvention = Unadjusted;
00088         Real bondCleanPrice = 89.97693786;
00089         Real bondRedemption = 100.0;
00090         Real faceAmount = 100.0;
00091 
00092 
00093         Settings::instance().evaluationDate() = repoSettlementDate;
00094 
00095         RelinkableHandle<YieldTermStructure> bondCurve;
00096         bondCurve.linkTo(boost::shared_ptr<YieldTermStructure>(
00097                                        new FlatForward(repoSettlementDate,
00098                                                        .01, // dummy rate
00099                                                        bondDayCountConvention,
00100                                                        Compounded,
00101                                                        bondCouponFrequency)));
00102 
00103         /*
00104         boost::shared_ptr<FixedRateBond> bond(
00105                        new FixedRateBond(faceAmount,
00106                                          bondIssueDate,
00107                                          bondDatedDate,
00108                                          bondMaturityDate,
00109                                          bondSettlementDays,
00110                                          std::vector<Rate>(1,bondCoupon),
00111                                          bondCouponFrequency,
00112                                          bondCalendar,
00113                                          bondDayCountConvention,
00114                                          bondBusinessDayConvention,
00115                                          bondBusinessDayConvention,
00116                                          bondRedemption,
00117                                          bondCurve));
00118         */
00119 
00120         Schedule bondSchedule(bondDatedDate, bondMaturityDate,
00121                               Period(bondCouponFrequency),
00122                               bondCalendar,bondBusinessDayConvention,
00123                               bondBusinessDayConvention,true,false);
00124         boost::shared_ptr<FixedRateBond> bond(
00125                        new FixedRateBond(bondSettlementDays,
00126                                          faceAmount,
00127                                          bondSchedule,
00128                                          std::vector<Rate>(1,bondCoupon),
00129                                          bondDayCountConvention,
00130                                          bondBusinessDayConvention,
00131                                          bondRedemption,
00132                                          bondIssueDate,
00133                                          bondCurve));
00134 
00135         bondCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
00136                    new FlatForward(repoSettlementDate,
00137                                    bond->yield(bondCleanPrice,Compounded),
00138                                    bondDayCountConvention,
00139                                    Compounded,
00140                                    bondCouponFrequency)));
00141 
00142         Position::Type fwdType = Position::Long;
00143         double dummyStrike = 91.5745;
00144 
00145         RelinkableHandle<YieldTermStructure> repoCurve;
00146         repoCurve.linkTo(boost::shared_ptr<YieldTermStructure> (
00147                                        new FlatForward(repoSettlementDate,
00148                                                        repoRate,
00149                                                        repoDayCountConvention,
00150                                                        repoCompounding,
00151                                                        repoCompoundFreq)));
00152 
00153 
00154         FixedRateBondForward bondFwd(repoSettlementDate,
00155                                      repoDeliveryDate,
00156                                      fwdType,
00157                                      dummyStrike,
00158                                      repoSettlementDays,
00159                                      repoDayCountConvention,
00160                                      bondCalendar,
00161                                      bondBusinessDayConvention,
00162                                      bond,
00163                                      repoCurve,
00164                                      repoCurve);
00165 
00166 
00167         cout << "Underlying bond clean price: "
00168              << bond->cleanPrice()
00169              << endl;
00170         cout << "Underlying bond dirty price: "
00171              << bond->dirtyPrice()
00172              << endl;
00173         cout << "Underlying bond accrued at settlement: "
00174              << bond->accruedAmount(repoSettlementDate)
00175              << endl;
00176         cout << "Underlying bond accrued at delivery:   "
00177              << bond->accruedAmount(repoDeliveryDate)
00178              << endl;
00179         cout << "Underlying bond spot income: "
00180              << bondFwd.spotIncome(repoCurve)
00181              << endl;
00182         cout << "Underlying bond fwd income:  "
00183              << bondFwd.spotIncome(repoCurve)/
00184                 repoCurve->discount(repoDeliveryDate)
00185              << endl;
00186         cout << "Repo strike: "
00187              << dummyStrike
00188              << endl;
00189         cout << "Repo NPV:    "
00190              << bondFwd.NPV()
00191              << endl;
00192         cout << "Repo clean forward price: "
00193              << bondFwd.cleanForwardPrice()
00194              << endl;
00195         cout << "Repo dirty forward price: "
00196              << bondFwd.forwardPrice()
00197              << endl;
00198         cout << "Repo implied yield: "
00199              << bondFwd.impliedYield(bond->dirtyPrice(),
00200                                      dummyStrike,
00201                                      repoSettlementDate,
00202                                      repoCompounding,
00203                                      repoDayCountConvention)
00204              << endl;
00205         cout << "Market repo rate:   "
00206              << repoCurve->zeroRate(repoDeliveryDate,
00207                                     repoDayCountConvention,
00208                                     repoCompounding,
00209                                     repoCompoundFreq)
00210              << endl
00211              << endl;
00212 
00213         cout << "Compare with example given at \n"
00214              << "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm"
00215              <<  endl;
00216         cout << "Clean forward price = 88.2408"
00217              <<  endl
00218              <<  endl;
00219         cout << "In that example, it is unknown what bond calendar they are\n"
00220              << "using, as well as settlement Days. For that reason, I have\n"
00221              << "made the simplest possible assumptions here: NullCalendar\n"
00222              << "and 0 settlement days."
00223              << endl;
00224 
00225 
00226         Real seconds = timer.elapsed();
00227         Integer hours = int(seconds/3600);
00228         seconds -= hours * 3600;
00229         Integer minutes = int(seconds/60);
00230         seconds -= minutes * 60;
00231         cout << " \nRun completed in ";
00232         if (hours > 0)
00233             cout << hours << " h ";
00234         if (hours > 0 || minutes > 0)
00235             cout << minutes << " m ";
00236         cout << fixed << setprecision(0)
00237              << seconds << " s\n" << endl;
00238 
00239         return 0;
00240 
00241     } catch (exception& e) {
00242         cout << e.what() << endl;
00243         return 1;
00244     } catch (...) {
00245         cout << "unknown error" << endl;
00246         return 1;
00247     }
00248 }
00249