1 | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | |
3 | /*! |
4 | Copyright (C) 2006 Allen Kuo |
5 | |
6 | This file is part of QuantLib, a free-software/open-source library |
7 | for financial quantitative analysts and developers - http://quantlib.org/ |
8 | |
9 | QuantLib is free software: you can redistribute it and/or modify it |
10 | under the terms of the QuantLib license. You should have received a |
11 | copy of the license along with this program; if not, please email |
12 | <quantlib-dev@lists.sf.net>. The license is also available online at |
13 | <http://quantlib.org/license.shtml>. |
14 | |
15 | This program is distributed in the hope that it will be useful, but WITHOUT |
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
17 | FOR A PARTICULAR PURPOSE. See the license for more details. |
18 | */ |
19 | |
20 | /* a Repo calculation done using the FixedRateBondForward class |
21 | cf. aaBondFwd() repo example at |
22 | http://www.fincad.com/support/developerFunc/mathref/BFWD.htm |
23 | |
24 | This repo is set up to use the repo rate to do all discounting |
25 | (including the underlying bond income). Forward delivery price is |
26 | also obtained using this repo rate. All this is done by supplying |
27 | the FixedRateBondForward constructor with a flat repo |
28 | YieldTermStructure. |
29 | */ |
30 | |
31 | #include <ql/qldefines.hpp> |
32 | #if !defined(BOOST_ALL_NO_LIB) && defined(BOOST_MSVC) |
33 | # include <ql/auto_link.hpp> |
34 | #endif |
35 | #include <ql/instruments/bondforward.hpp> |
36 | #include <ql/instruments/bonds/fixedratebond.hpp> |
37 | #include <ql/pricingengines/bond/discountingbondengine.hpp> |
38 | #include <ql/termstructures/yield/flatforward.hpp> |
39 | #include <ql/time/schedule.hpp> |
40 | #include <ql/time/calendars/nullcalendar.hpp> |
41 | #include <ql/time/daycounters/actual360.hpp> |
42 | #include <ql/time/daycounters/thirty360.hpp> |
43 | |
44 | #include <iostream> |
45 | #include <iomanip> |
46 | |
47 | using namespace std; |
48 | using namespace QuantLib; |
49 | |
50 | int main(int, char* []) { |
51 | |
52 | try { |
53 | |
54 | std::cout << std::endl; |
55 | |
56 | Date repoSettlementDate(14,February,2000);; |
57 | Date repoDeliveryDate(15,August,2000); |
58 | Rate repoRate = 0.05; |
59 | DayCounter repoDayCountConvention = Actual360(); |
60 | Integer repoSettlementDays = 0; |
61 | Compounding repoCompounding = Simple; |
62 | Frequency repoCompoundFreq = Annual; |
63 | |
64 | // assume a ten year bond- this is irrelevant |
65 | Date bondIssueDate(15,September,1995); |
66 | Date bondDatedDate(15,September,1995); |
67 | Date bondMaturityDate(15,September,2005); |
68 | Real bondCoupon = 0.08; |
69 | Frequency bondCouponFrequency = Semiannual; |
70 | // unknown what calendar fincad is using |
71 | Calendar bondCalendar = NullCalendar(); |
72 | DayCounter bondDayCountConvention = Thirty360(Thirty360::BondBasis); |
73 | // unknown what fincad is using. this may affect accrued calculation |
74 | Integer bondSettlementDays = 0; |
75 | BusinessDayConvention bondBusinessDayConvention = Unadjusted; |
76 | Real bondCleanPrice = 89.97693786; |
77 | Real bondRedemption = 100.0; |
78 | Real faceAmount = 100.0; |
79 | |
80 | |
81 | Settings::instance().evaluationDate() = repoSettlementDate; |
82 | |
83 | RelinkableHandle<YieldTermStructure> bondCurve; |
84 | bondCurve.linkTo(h: ext::make_shared<FlatForward>(args&: repoSettlementDate, |
85 | args: .01, // dummy rate |
86 | args&: bondDayCountConvention, |
87 | args: Compounded, |
88 | args&: bondCouponFrequency)); |
89 | |
90 | /* |
91 | auto bond = ext::make_shared<FixedRateBond>(faceAmount, |
92 | bondIssueDate, |
93 | bondDatedDate, |
94 | bondMaturityDate, |
95 | bondSettlementDays, |
96 | std::vector<Rate>(1,bondCoupon), |
97 | bondCouponFrequency, |
98 | bondCalendar, |
99 | bondDayCountConvention, |
100 | bondBusinessDayConvention, |
101 | bondBusinessDayConvention, |
102 | bondRedemption, |
103 | bondCurve); |
104 | */ |
105 | |
106 | Schedule bondSchedule(bondDatedDate, bondMaturityDate, |
107 | Period(bondCouponFrequency), |
108 | bondCalendar,bondBusinessDayConvention, |
109 | bondBusinessDayConvention, |
110 | DateGeneration::Backward,false); |
111 | auto bond = ext::make_shared<FixedRateBond>(args&: bondSettlementDays, |
112 | args&: faceAmount, |
113 | args&: bondSchedule, |
114 | args: std::vector<Rate>(1,bondCoupon), |
115 | args&: bondDayCountConvention, |
116 | args&: bondBusinessDayConvention, |
117 | args&: bondRedemption, |
118 | args&: bondIssueDate); |
119 | bond->setPricingEngine(ext::make_shared<DiscountingBondEngine>(args&: bondCurve)); |
120 | |
121 | bondCurve.linkTo(h: ext::make_shared<FlatForward>(args&: repoSettlementDate, |
122 | args: bond->yield(cleanPrice: bondCleanPrice, |
123 | dc: bondDayCountConvention, |
124 | comp: Compounded, |
125 | freq: bondCouponFrequency), |
126 | args&: bondDayCountConvention, |
127 | args: Compounded, |
128 | args&: bondCouponFrequency)); |
129 | |
130 | Position::Type fwdType = Position::Long; |
131 | double dummyStrike = 91.5745; |
132 | |
133 | RelinkableHandle<YieldTermStructure> repoCurve; |
134 | repoCurve.linkTo(h: ext::make_shared<FlatForward>(args&: repoSettlementDate, |
135 | args&: repoRate, |
136 | args&: repoDayCountConvention, |
137 | args&: repoCompounding, |
138 | args&: repoCompoundFreq)); |
139 | |
140 | |
141 | BondForward bondFwd(repoSettlementDate, repoDeliveryDate, fwdType, dummyStrike, |
142 | repoSettlementDays, repoDayCountConvention, bondCalendar, |
143 | bondBusinessDayConvention, bond, repoCurve, repoCurve); |
144 | |
145 | |
146 | cout << "Underlying bond clean price: " |
147 | << bond->cleanPrice() |
148 | << endl; |
149 | cout << "Underlying bond dirty price: " |
150 | << bond->dirtyPrice() |
151 | << endl; |
152 | cout << "Underlying bond accrued at settlement: " |
153 | << bond->accruedAmount(d: repoSettlementDate) |
154 | << endl; |
155 | cout << "Underlying bond accrued at delivery: " |
156 | << bond->accruedAmount(d: repoDeliveryDate) |
157 | << endl; |
158 | cout << "Underlying bond spot income: " |
159 | << bondFwd.spotIncome(incomeDiscountCurve: repoCurve) |
160 | << endl; |
161 | cout << "Underlying bond fwd income: " |
162 | << bondFwd.spotIncome(incomeDiscountCurve: repoCurve)/ |
163 | repoCurve->discount(d: repoDeliveryDate) |
164 | << endl; |
165 | cout << "Repo strike: " |
166 | << dummyStrike |
167 | << endl; |
168 | cout << "Repo NPV: " |
169 | << bondFwd.NPV() |
170 | << endl; |
171 | cout << "Repo clean forward price: " |
172 | << bondFwd.cleanForwardPrice() |
173 | << endl; |
174 | cout << "Repo dirty forward price: " |
175 | << bondFwd.forwardPrice() |
176 | << endl; |
177 | cout << "Repo implied yield: " |
178 | << bondFwd.impliedYield(underlyingSpotValue: bond->dirtyPrice(), |
179 | forwardValue: dummyStrike, |
180 | settlementDate: repoSettlementDate, |
181 | compoundingConvention: repoCompounding, |
182 | dayCounter: repoDayCountConvention) |
183 | << endl; |
184 | cout << "Market repo rate: " |
185 | << repoCurve->zeroRate(d: repoDeliveryDate, |
186 | resultDayCounter: repoDayCountConvention, |
187 | comp: repoCompounding, |
188 | freq: repoCompoundFreq) |
189 | << endl |
190 | << endl; |
191 | |
192 | cout << "Compare with example given at \n" |
193 | << "http://www.fincad.com/support/developerFunc/mathref/BFWD.htm" |
194 | << endl; |
195 | cout << "Clean forward price = 88.2408" |
196 | << endl |
197 | << endl; |
198 | cout << "In that example, it is unknown what bond calendar they are\n" |
199 | << "using, as well as settlement Days. For that reason, I have\n" |
200 | << "made the simplest possible assumptions here: NullCalendar\n" |
201 | << "and 0 settlement days." |
202 | << endl; |
203 | |
204 | |
205 | return 0; |
206 | |
207 | } catch (exception& e) { |
208 | cerr << e.what() << endl; |
209 | return 1; |
210 | } catch (...) { |
211 | cerr << "unknown error" << endl; |
212 | return 1; |
213 | } |
214 | } |
215 | |
216 | |