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