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