/src/quantlib/ql/models/shortrate/calibrationhelpers/caphelper.cpp
Line | Count | Source |
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) 2007 StatPro Italia srl |
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 | | <https://www.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/cashflows/cashflowvectors.hpp> |
22 | | #include <ql/models/shortrate/calibrationhelpers/caphelper.hpp> |
23 | | #include <ql/pricingengines/capfloor/bacheliercapfloorengine.hpp> |
24 | | #include <ql/pricingengines/capfloor/blackcapfloorengine.hpp> |
25 | | #include <ql/pricingengines/capfloor/discretizedcapfloor.hpp> |
26 | | #include <ql/pricingengines/swap/discountingswapengine.hpp> |
27 | | #include <ql/quotes/simplequote.hpp> |
28 | | #include <ql/time/schedule.hpp> |
29 | | #include <utility> |
30 | | |
31 | | namespace QuantLib { |
32 | | |
33 | | CapHelper::CapHelper(const Period& length, |
34 | | const Handle<Quote>& volatility, |
35 | | ext::shared_ptr<IborIndex> index, |
36 | | Frequency fixedLegFrequency, |
37 | | DayCounter fixedLegDayCounter, |
38 | | bool includeFirstSwaplet, |
39 | | Handle<YieldTermStructure> termStructure, |
40 | | BlackCalibrationHelper::CalibrationErrorType errorType, |
41 | | const VolatilityType type, |
42 | | const Real shift) |
43 | 0 | : BlackCalibrationHelper(volatility, errorType, type, shift), length_(length), |
44 | 0 | index_(std::move(index)), termStructure_(std::move(termStructure)), |
45 | 0 | fixedLegFrequency_(fixedLegFrequency), fixedLegDayCounter_(std::move(fixedLegDayCounter)), |
46 | 0 | includeFirstSwaplet_(includeFirstSwaplet) { |
47 | 0 | registerWith(index_); |
48 | 0 | registerWith(termStructure_); |
49 | 0 | } Unexecuted instantiation: QuantLib::CapHelper::CapHelper(QuantLib::Period const&, QuantLib::Handle<QuantLib::Quote> const&, boost::shared_ptr<QuantLib::IborIndex>, QuantLib::Frequency, QuantLib::DayCounter, bool, QuantLib::Handle<QuantLib::YieldTermStructure>, QuantLib::BlackCalibrationHelper::CalibrationErrorType, QuantLib::VolatilityType, double) Unexecuted instantiation: QuantLib::CapHelper::CapHelper(QuantLib::Period const&, QuantLib::Handle<QuantLib::Quote> const&, boost::shared_ptr<QuantLib::IborIndex>, QuantLib::Frequency, QuantLib::DayCounter, bool, QuantLib::Handle<QuantLib::YieldTermStructure>, QuantLib::BlackCalibrationHelper::CalibrationErrorType, QuantLib::VolatilityType, double) |
50 | | |
51 | 0 | void CapHelper::addTimesTo(std::list<Time>& times) const { |
52 | 0 | calculate(); |
53 | 0 | CapFloor::arguments args; |
54 | 0 | cap_->setupArguments(&args); |
55 | 0 | std::vector<Time> capTimes = |
56 | 0 | DiscretizedCapFloor(args, |
57 | 0 | termStructure_->referenceDate(), |
58 | 0 | termStructure_->dayCounter()).mandatoryTimes(); |
59 | 0 | times.insert(times.end(), |
60 | 0 | capTimes.begin(), capTimes.end()); |
61 | 0 | } |
62 | | |
63 | 0 | Real CapHelper::modelValue() const { |
64 | 0 | calculate(); |
65 | 0 | cap_->setPricingEngine(engine_); |
66 | 0 | return cap_->NPV(); |
67 | 0 | } |
68 | | |
69 | 0 | Real CapHelper::blackPrice(Volatility sigma) const { |
70 | 0 | calculate(); |
71 | 0 | Handle<Quote> vol(ext::shared_ptr<Quote>(new SimpleQuote(sigma))); |
72 | 0 | ext::shared_ptr<PricingEngine> engine; |
73 | 0 | switch(volatilityType_) { |
74 | 0 | case ShiftedLognormal: |
75 | 0 | engine = ext::make_shared<BlackCapFloorEngine>( |
76 | 0 | termStructure_, vol, Actual365Fixed(), shift_); |
77 | 0 | break; |
78 | 0 | case Normal: |
79 | 0 | engine = ext::make_shared<BachelierCapFloorEngine>( |
80 | 0 | termStructure_, vol, Actual365Fixed()); |
81 | 0 | break; |
82 | 0 | default: |
83 | 0 | QL_FAIL("unknown volatility type: " << volatilityType_); |
84 | 0 | } |
85 | 0 | cap_->setPricingEngine(engine); |
86 | 0 | Real value = cap_->NPV(); |
87 | 0 | cap_->setPricingEngine(engine_); |
88 | 0 | return value; |
89 | 0 | } |
90 | | |
91 | 0 | void CapHelper::performCalculations() const { |
92 | |
|
93 | 0 | Period indexTenor = index_->tenor(); |
94 | 0 | Rate fixedRate = 0.04; // dummy value |
95 | 0 | Date startDate, maturity; |
96 | 0 | if (includeFirstSwaplet_) { |
97 | 0 | startDate = termStructure_->referenceDate(); |
98 | 0 | maturity = termStructure_->referenceDate() + length_; |
99 | 0 | } else { |
100 | 0 | startDate = termStructure_->referenceDate() + indexTenor; |
101 | 0 | maturity = termStructure_->referenceDate() + length_; |
102 | 0 | } |
103 | 0 | ext::shared_ptr<IborIndex> dummyIndex(new |
104 | 0 | IborIndex("dummy", |
105 | 0 | indexTenor, |
106 | 0 | index_->fixingDays(), |
107 | 0 | index_->currency(), |
108 | 0 | index_->fixingCalendar(), |
109 | 0 | index_->businessDayConvention(), |
110 | 0 | index_->endOfMonth(), |
111 | 0 | termStructure_->dayCounter(), |
112 | 0 | termStructure_)); |
113 | |
|
114 | 0 | std::vector<Real> nominals(1,1.0); |
115 | |
|
116 | 0 | Schedule floatSchedule(startDate, maturity, |
117 | 0 | index_->tenor(), index_->fixingCalendar(), |
118 | 0 | index_->businessDayConvention(), |
119 | 0 | index_->businessDayConvention(), |
120 | 0 | DateGeneration::Forward, false); |
121 | 0 | Leg floatingLeg = IborLeg(floatSchedule, index_) |
122 | 0 | .withNotionals(nominals) |
123 | 0 | .withPaymentAdjustment(index_->businessDayConvention()) |
124 | 0 | .withFixingDays(0); |
125 | |
|
126 | 0 | Schedule fixedSchedule(startDate, maturity, Period(fixedLegFrequency_), |
127 | 0 | index_->fixingCalendar(), |
128 | 0 | Unadjusted, Unadjusted, |
129 | 0 | DateGeneration::Forward, false); |
130 | 0 | Leg fixedLeg = FixedRateLeg(fixedSchedule) |
131 | 0 | .withNotionals(nominals) |
132 | 0 | .withCouponRates(fixedRate, fixedLegDayCounter_) |
133 | 0 | .withPaymentAdjustment(index_->businessDayConvention()); |
134 | |
|
135 | 0 | Swap swap(floatingLeg, fixedLeg); |
136 | 0 | swap.setPricingEngine(ext::shared_ptr<PricingEngine>( |
137 | 0 | new DiscountingSwapEngine(termStructure_, false))); |
138 | 0 | Rate fairRate = fixedRate - swap.NPV()/(swap.legBPS(1)/1.0e-4); |
139 | 0 | cap_ = ext::make_shared<Cap>(floatingLeg, |
140 | 0 | std::vector<Rate>(1, fairRate)); |
141 | |
|
142 | 0 | BlackCalibrationHelper::performCalculations(); |
143 | |
|
144 | 0 | } |
145 | | |
146 | | |
147 | | } |