QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
lfmprocess.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2005, 2006 Klaus Spanderen
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#include <ql/cashflows/cashflows.hpp>
21#include <ql/cashflows/cashflowvectors.hpp>
22#include <ql/cashflows/couponpricer.hpp>
23#include <ql/cashflows/floatingratecoupon.hpp>
24#include <ql/cashflows/iborcoupon.hpp>
25#include <ql/legacy/libormarketmodels/lfmprocess.hpp>
26#include <ql/processes/eulerdiscretization.hpp>
27#include <ql/termstructures/yieldtermstructure.hpp>
28#include <ql/time/schedule.hpp>
29#include <utility>
30
31namespace QuantLib {
32
33 LiborForwardModelProcess::LiborForwardModelProcess(Size size, ext::shared_ptr<IborIndex> index)
34 : StochasticProcess(ext::shared_ptr<discretization>(new EulerDiscretization)), size_(size),
35 index_(std::move(index)), initialValues_(size_), fixingTimes_(size_), fixingDates_(size_),
36 accrualStartTimes_(size), accrualEndTimes_(size), accrualPeriod_(size_), m1(size_),
37 m2(size_) {
38
39 const DayCounter dayCounter = index_->dayCounter();
40 const Leg flows = cashFlows();
41
42 QL_REQUIRE(size_ == flows.size(), "wrong number of cashflows");
43
44 Date settlement = index_->forwardingTermStructure()->referenceDate();
45 const Date startDate =
46 ext::dynamic_pointer_cast<IborCoupon>(flows[0])->fixingDate();
47
48 for (Size i = 0; i < size_; ++i) {
49 const ext::shared_ptr<IborCoupon> coupon =
50 ext::dynamic_pointer_cast<IborCoupon>(flows[i]);
51
52 QL_REQUIRE(coupon->date() == coupon->accrualEndDate(),
53 "irregular coupon types are not suppported");
54
55 initialValues_[i] = coupon->rate();
56 accrualPeriod_[i] = coupon->accrualPeriod();
57
58 fixingDates_[i] = coupon->fixingDate();
59 fixingTimes_[i] =
60 dayCounter.yearFraction(startDate, coupon->fixingDate());
62 dayCounter.yearFraction(settlement,coupon->accrualStartDate());
64 dayCounter.yearFraction(settlement,coupon->accrualEndDate());
65 }
66 }
67
69 const Array& x) const {
70 Array f(size_, 0.0);
71 Matrix covariance(lfmParam_->covariance(t, x));
72
73 const Size m = nextIndexReset(t);
74
75 for (Size k=m; k<size_; ++k) {
76 m1[k] = accrualPeriod_[k]*x[k]/(1+accrualPeriod_[k]*x[k]);
77 f[k] = std::inner_product(m1.begin()+m, m1.begin()+k+1,
79 - 0.5*covariance[k][k];
80 }
81
82 return f;
83 }
84
86 return lfmParam_->diffusion(t, x);
87 }
88
90 return lfmParam_->covariance(t, x)*dt;
91 }
92
93 Array LiborForwardModelProcess::apply(const Array& x0, const Array& dx) const {
94 Array tmp(size_);
95
96 for (Size k=0; k<size_; ++k) {
97 tmp[k] = x0[k] * std::exp(dx[k]);
98 }
99
100 return tmp;
101 }
102
104 Time dt, const Array& dw) const {
105 /* predictor-corrector step to reduce discretization errors.
106
107 Short - but slow - solution would be
108
109 Array rnd_0 = stdDeviation(t0, x0, dt)*dw;
110 Array drift_0 = discretization_->drift(*this, t0, x0, dt);
111
112 return apply(x0, ( drift_0 + discretization_
113 ->drift(*this,t0,apply(x0, drift_0 + rnd_0),dt) )*0.5 + rnd_0);
114
115 The following implementation does the same but is faster.
116 */
117
118 const Size m = nextIndexReset(t0);
119 const Real sdt = std::sqrt(dt);
120
121 Array f(x0);
122 Matrix diff = lfmParam_->diffusion(t0, x0);
123 Matrix covariance = lfmParam_->covariance(t0, x0);
124
125 for (Size k=m; k<size_; ++k) {
126 const Real y = accrualPeriod_[k]*x0[k];
127 m1[k] = y/(1+y);
128 const Real d = (
129 std::inner_product(m1.begin()+m, m1.begin()+k+1,
130 covariance.column_begin(k)+m,Real(0.0))
131 -0.5*covariance[k][k]) * dt;
132
133 const Real r = std::inner_product(
134 diff.row_begin(k), diff.row_end(k), dw.begin(), Real(0.0))*sdt;
135
136 const Real x = y*std::exp(d + r);
137 m2[k] = x/(1+x);
138 f[k] = x0[k] * std::exp(0.5*(d+
139 (std::inner_product(m2.begin()+m, m2.begin()+k+1,
140 covariance.column_begin(k)+m,Real(0.0))
141 -0.5*covariance[k][k])*dt)+ r);
142 }
143
144 return f;
145 }
146
148 return initialValues_;
149 }
150
152 const ext::shared_ptr<LfmCovarianceParameterization> & param) {
153 lfmParam_ = param;
154 }
155
156 ext::shared_ptr<LfmCovarianceParameterization>
158 return lfmParam_;
159 }
160
161 ext::shared_ptr<IborIndex>
163 return index_;
164 }
165
166 Leg
168 Date refDate = index_->forwardingTermStructure()->referenceDate();
169 Schedule schedule(refDate,
170 refDate + Period(index_->tenor().length()*size_,
171 index_->tenor().units()),
172 index_->tenor(), index_->fixingCalendar(),
173 index_->businessDayConvention(),
174 index_->businessDayConvention(),
176 return IborLeg(schedule,index_)
177 .withNotionals(amount)
178 .withPaymentDayCounter(index_->dayCounter())
179 .withPaymentAdjustment(index_->businessDayConvention())
180 .withFixingDays(index_->fixingDays());
181 }
182
184 return size_;
185 }
186
188 return lfmParam_->factors();
189 }
190
191 const std::vector<Time> & LiborForwardModelProcess::fixingTimes() const {
192 return fixingTimes_;
193 }
194
195 const std::vector<Date> & LiborForwardModelProcess::fixingDates() const {
196 return fixingDates_;
197 }
198
199 const std::vector<Time> &
201 return accrualStartTimes_;
202 }
203
204 const std::vector<Time> &
206 return accrualEndTimes_;
207 }
208
210 return std::upper_bound(fixingTimes_.begin(), fixingTimes_.end(), t)
211 - fixingTimes_.begin();
212 }
213
214 std::vector<DiscountFactor> LiborForwardModelProcess::discountBond(
215 const std::vector<Rate> & rates) const {
216
217 std::vector<DiscountFactor> discountFactors(size_);
218 discountFactors[0] = 1.0/(1.0 + rates[0]*accrualPeriod_[0]);
219
220 for (Size i = 1; i < size_; ++i) {
221 discountFactors[i] =
222 discountFactors[i-1]/(1.0 + rates[i]*accrualPeriod_[i]);
223 }
224
225 return discountFactors;
226 }
227
228}
229
1-D array used in linear algebra.
Definition: array.hpp:52
const_iterator begin() const
Definition: array.hpp:503
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Time yearFraction(const Date &, const Date &, const Date &refPeriodStart=Date(), const Date &refPeriodEnd=Date()) const
Returns the period between two dates as a fraction of year.
Definition: daycounter.hpp:128
Euler discretization for stochastic processes.
helper class building a sequence of capped/floored ibor-rate coupons
Definition: iborcoupon.hpp:133
IborLeg & withPaymentAdjustment(BusinessDayConvention)
Definition: iborcoupon.cpp:173
IborLeg & withPaymentDayCounter(const DayCounter &)
Definition: iborcoupon.cpp:168
IborLeg & withNotionals(Real notional)
Definition: iborcoupon.cpp:158
IborLeg & withFixingDays(Natural fixingDays)
Definition: iborcoupon.cpp:188
Array drift(Time t, const Array &x) const override
returns the drift part of the equation, i.e.,
Definition: lfmprocess.cpp:68
Size size() const override
returns the number of dimensions of the stochastic process
Definition: lfmprocess.cpp:183
Leg cashFlows(Real amount=1.0) const
Definition: lfmprocess.cpp:167
Array evolve(Time t0, const Array &x0, Time dt, const Array &dw) const override
Definition: lfmprocess.cpp:103
const std::vector< Time > & fixingTimes() const
Definition: lfmprocess.cpp:191
std::vector< Date > fixingDates_
Definition: lfmprocess.hpp:101
const ext::shared_ptr< IborIndex > index_
Definition: lfmprocess.hpp:95
ext::shared_ptr< LfmCovarianceParameterization > lfmParam_
Definition: lfmprocess.hpp:96
Matrix diffusion(Time t, const Array &x) const override
returns the diffusion part of the equation, i.e.
Definition: lfmprocess.cpp:85
std::vector< Time > accrualPeriod_
Definition: lfmprocess.hpp:104
const std::vector< Time > & accrualEndTimes() const
Definition: lfmprocess.cpp:205
Size factors() const override
returns the number of independent factors of the process
Definition: lfmprocess.cpp:187
ext::shared_ptr< LfmCovarianceParameterization > covarParam() const
Definition: lfmprocess.cpp:157
std::vector< Time > accrualEndTimes_
Definition: lfmprocess.hpp:103
Matrix covariance(Time t0, const Array &x0, Time dt) const override
Definition: lfmprocess.cpp:89
const std::vector< Time > & accrualStartTimes() const
Definition: lfmprocess.cpp:200
LiborForwardModelProcess(Size size, ext::shared_ptr< IborIndex > index)
Definition: lfmprocess.cpp:33
Array initialValues() const override
returns the initial values of the state variables
Definition: lfmprocess.cpp:147
std::vector< Time > fixingTimes_
Definition: lfmprocess.hpp:100
std::vector< DiscountFactor > discountBond(const std::vector< Rate > &rates) const
Definition: lfmprocess.cpp:214
void setCovarParam(const ext::shared_ptr< LfmCovarianceParameterization > &param)
Definition: lfmprocess.cpp:151
Array apply(const Array &x0, const Array &dx) const override
Definition: lfmprocess.cpp:93
const std::vector< Date > & fixingDates() const
Definition: lfmprocess.cpp:195
ext::shared_ptr< IborIndex > index() const
Definition: lfmprocess.cpp:162
std::vector< Time > accrualStartTimes_
Definition: lfmprocess.hpp:102
Matrix used in linear algebra.
Definition: matrix.hpp:41
const_row_iterator row_begin(Size i) const
Definition: matrix.hpp:360
const_column_iterator column_begin(Size i) const
Definition: matrix.hpp:415
const_row_iterator row_end(Size i) const
Definition: matrix.hpp:378
Payment schedule.
Definition: schedule.hpp:40
discretization of a stochastic process over a given time interval
multi-dimensional stochastic process class.
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
std::vector< ext::shared_ptr< CashFlow > > Leg
Sequence of cash-flows.
Definition: cashflow.hpp:78
STL namespace.