QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
jamshidianswaptionengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
5 Copyright (C) 2013 Peter Caspers
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/math/solvers1d/brent.hpp>
22#include <ql/pricingengines/swaption/jamshidianswaptionengine.hpp>
23#include <utility>
24
25namespace QuantLib {
26
27 class JamshidianSwaptionEngine::rStarFinder {
28 public:
29 rStarFinder(const ext::shared_ptr<OneFactorAffineModel>& model,
30 Real nominal,
31 Time maturity,
32 Time valueTime,
33 std::vector<Time> fixedPayTimes,
34 const std::vector<Real>& amounts)
35 : strike_(nominal), maturity_(maturity), valueTime_(valueTime),
36 times_(std::move(fixedPayTimes)), amounts_(amounts), model_(model) {}
37
38 Real operator()(Rate x) const {
39 Real value = strike_;
40 Real B = model_->discountBond(maturity_, valueTime_, x);
41 Size size = times_.size();
42 for (Size i=0; i<size; i++) {
43 Real dbValue =
44 model_->discountBond(maturity_, times_[i], x) / B;
45 value -= amounts_[i]*dbValue;
46 }
47 return value;
48 }
49 private:
50 Real strike_;
51 Time maturity_,valueTime_;
52 std::vector<Time> times_;
53 const std::vector<Real>& amounts_;
54 const ext::shared_ptr<OneFactorAffineModel>& model_;
55 };
56
58
59 QL_REQUIRE(arguments_.settlementMethod != Settlement::ParYieldCurve,
60 "cash settled (ParYieldCurve) swaptions not priced with "
61 "JamshidianSwaptionEngine");
62
63 QL_REQUIRE(arguments_.exercise->type() == Exercise::European,
64 "cannot use the Jamshidian decomposition "
65 "on exotic swaptions");
66
67 QL_REQUIRE(arguments_.swap->spread() == 0.0, "non zero spread (" << arguments_.swap->spread() << ") not allowed");
68
69 QL_REQUIRE(arguments_.nominal != Null<Real>(),
70 "non-constant nominals are not supported yet");
71
72 QL_REQUIRE(!model_.empty(), "no model specified");
73
74 Date referenceDate;
75 DayCounter dayCounter;
76
77 ext::shared_ptr<TermStructureConsistentModel> tsmodel =
78 ext::dynamic_pointer_cast<TermStructureConsistentModel>(*model_);
79 if (tsmodel != nullptr) {
80 referenceDate = tsmodel->termStructure()->referenceDate();
81 dayCounter = tsmodel->termStructure()->dayCounter();
82 } else {
83 referenceDate = termStructure_->referenceDate();
84 dayCounter = termStructure_->dayCounter();
85 }
86
87 std::vector<Real> amounts(arguments_.fixedCoupons);
88 amounts.back() += arguments_.nominal;
89
90 Real maturity = dayCounter.yearFraction(referenceDate,
91 arguments_.exercise->date(0));
92
93 std::vector<Time> fixedPayTimes(arguments_.fixedPayDates.size());
94 Time valueTime = dayCounter.yearFraction(referenceDate,arguments_.fixedResetDates[0]);
95 for (Size i=0; i<fixedPayTimes.size(); i++)
96 fixedPayTimes[i] = dayCounter.yearFraction(referenceDate,
97 arguments_.fixedPayDates[i]);
98
99 rStarFinder finder(*model_, arguments_.nominal, maturity, valueTime,
100 fixedPayTimes, amounts);
101 Brent s1d;
102 Rate minStrike = -10.0;
103 Rate maxStrike = 10.0;
104 s1d.setMaxEvaluations(10000);
105 s1d.setLowerBound(minStrike);
106 s1d.setUpperBound(maxStrike);
107 Rate rStar = s1d.solve(finder, 1e-8, 0.05, minStrike, maxStrike);
108
110 Size size = arguments_.fixedCoupons.size();
111
112 Real value = 0.0;
113 Real B = model_->discountBond(maturity, valueTime, rStar);
114 for (Size i=0; i<size; i++) {
115 Real fixedPayTime =
116 dayCounter.yearFraction(referenceDate,
117 arguments_.fixedPayDates[i]);
118 Real strike = model_->discountBond(maturity,
119 fixedPayTime,
120 rStar) / B;
121 // Looks like the swaption decomposed into individual options adjusted for maturity. Each individual option is valued by Hull-White (or other one-factor model).
122 Real dboValue = model_->discountBondOption(
123 w, strike, maturity, valueTime,
124 fixedPayTime);
125 value += amounts[i]*dboValue;
126 }
127 results_.value = value;
128 }
129
130}
131
Brent 1-D solver
Definition: brent.hpp:37
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
bool empty() const
checks if the contained shared pointer points to anything
Definition: handle.hpp:166
Handle< YieldTermStructure > termStructure_
template class providing a null value for a given type.
Definition: null.hpp:76
void setMaxEvaluations(Size evaluations)
Definition: solver1d.hpp:238
void setLowerBound(Real lowerBound)
sets the lower bound for the function domain
Definition: solver1d.hpp:243
Real solve(const F &f, Real accuracy, Real guess, Real step) const
Definition: solver1d.hpp:84
void setUpperBound(Real upperBound)
sets the upper bound for the function domain
Definition: solver1d.hpp:249
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
STL namespace.