QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
blackcapfloorengine.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2007 Ferdinando Ametrano
5 Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb
6 Copyright (C) 2006, 2007 StatPro Italia srl
7 Copyright (C) 2015 Michael von den Driesch
8 Copyright (C) 2019 Wojciech Ĺšlusarski
9
10 This file is part of QuantLib, a free-software/open-source library
11 for financial quantitative analysts and developers - http://quantlib.org/
12
13 QuantLib is free software: you can redistribute it and/or modify it
14 under the terms of the QuantLib license. You should have received a
15 copy of the license along with this program; if not, please email
16 <quantlib-dev@lists.sf.net>. The license is also available online at
17 <http://quantlib.org/license.shtml>.
18
19 This program is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 FOR A PARTICULAR PURPOSE. See the license for more details.
22*/
23
24#include <ql/pricingengines/blackformula.hpp>
25#include <ql/pricingengines/capfloor/blackcapfloorengine.hpp>
26#include <ql/termstructures/volatility/optionlet/constantoptionletvol.hpp>
27#include <ql/termstructures/yieldtermstructure.hpp>
28#include <ql/time/calendars/nullcalendar.hpp>
29#include <utility>
30
31namespace QuantLib {
32
34 Volatility v,
35 const DayCounter& dc,
36 Real displacement)
37 : discountCurve_(std::move(discountCurve)),
38 vol_(ext::shared_ptr<OptionletVolatilityStructure>(
40 displacement_(displacement) {
42 }
43
45 const Handle<Quote>& v,
46 const DayCounter& dc,
47 Real displacement)
48 : discountCurve_(std::move(discountCurve)),
49 vol_(ext::shared_ptr<OptionletVolatilityStructure>(
51 displacement_(displacement) {
54 }
55
58 Real displacement)
59 : discountCurve_(std::move(discountCurve)), vol_(std::move(volatility)) {
60 QL_REQUIRE(
61 vol_->volatilityType() == ShiftedLognormal,
62 "BlackCapFloorEngine should only be used for vol surfaces stripped "
63 "with shifted log normal model. Options were stripped with model "
64 << vol_->volatilityType());
65 if (displacement != Null< Real >()) {
67 QL_REQUIRE(vol_->displacement() == displacement_,
68 "Displacement used for stripping and provided for "
69 "pricing differ. Model displacement was : "
70 << vol_->displacement());
71 } else
72 displacement_ = vol_->displacement();
75 }
76
78 Real value = 0.0;
79 Real vega = 0.0;
80 Size optionlets = arguments_.startDates.size();
81 std::vector<Real> values(optionlets, 0.0);
82 std::vector<Real> deltas(optionlets, 0.0);
83 std::vector<Real> vegas(optionlets, 0.0);
84 std::vector<Real> stdDevs(optionlets, 0.0);
85 std::vector<DiscountFactor> discountFactors(optionlets, 0.0);
87 Date today = vol_->referenceDate();
88 Date settlement = discountCurve_->referenceDate();
89
90 for (Size i=0; i<optionlets; ++i) {
91 Date paymentDate = arguments_.endDates[i];
92 // handling of settlementDate, npvDate and includeSettlementFlows
93 // should be implemented.
94 // For the time being just discard expired caplets
95 if (paymentDate > settlement) {
96 DiscountFactor d = discountCurve_->discount(paymentDate);
97 discountFactors[i] = d;
98 Real accrualFactor = arguments_.nominals[i] *
101 Real discountedAccrual = d * accrualFactor;
102 Rate forward = arguments_.forwards[i];
103
104 Date fixingDate = arguments_.fixingDates[i];
105 Time sqrtTime = 0.0;
106 if (fixingDate > today)
107 sqrtTime = std::sqrt(vol_->timeFromReference(fixingDate));
108
109 if (type == CapFloor::Cap || type == CapFloor::Collar) {
110 Rate strike = arguments_.capRates[i];
111 if (sqrtTime>0.0) {
112 stdDevs[i] = std::sqrt(vol_->blackVariance(fixingDate,
113 strike));
114 vegas[i] = blackFormulaStdDevDerivative(strike,
115 forward, stdDevs[i], discountedAccrual, displacement_)
116 * sqrtTime;
118 strike, forward, stdDevs[i], displacement_);
119 }
120 // include caplets with past fixing date
121 values[i] = blackFormula(Option::Call,
122 strike, forward, stdDevs[i], discountedAccrual,
124 }
125 if (type == CapFloor::Floor || type == CapFloor::Collar) {
126 Rate strike = arguments_.floorRates[i];
127 Real floorletVega = 0.0;
128 Real floorletDelta = 0.0;
129 if (sqrtTime>0.0) {
130 stdDevs[i] = std::sqrt(vol_->blackVariance(fixingDate,
131 strike));
132 floorletVega = blackFormulaStdDevDerivative(strike,
133 forward, stdDevs[i], discountedAccrual, displacement_)
134 * sqrtTime;
136 Option::Put, strike, forward,
137 stdDevs[i], displacement_);
138 }
139 Real floorlet = blackFormula(Option::Put,
140 strike, forward, stdDevs[i], discountedAccrual, displacement_);
141 if (type == CapFloor::Floor) {
142 values[i] = floorlet;
143 vegas[i] = floorletVega;
144 deltas[i] = floorletDelta;
145 } else {
146 // a collar is long a cap and short a floor
147 values[i] -= floorlet;
148 vegas[i] -= floorletVega;
149 deltas[i] -= floorletDelta;
150 }
151 }
152 value += values[i];
153 vega += vegas[i];
154 }
155 }
156 results_.value = value;
157 results_.additionalResults["vega"] = vega;
158
159 results_.additionalResults["optionletsPrice"] = values;
160 results_.additionalResults["optionletsVega"] = vegas;
161 results_.additionalResults["optionletsDelta"] = deltas;
162 results_.additionalResults["optionletsDiscountFactor"] = discountFactors;
163 results_.additionalResults["optionletsAtmForward"] = arguments_.forwards;
164 if (type != CapFloor::Collar)
165 results_.additionalResults["optionletsStdDev"] = stdDevs;
166 }
167
168}
Handle< YieldTermStructure > discountCurve_
BlackCapFloorEngine(Handle< YieldTermStructure > discountCurve, Volatility vol, const DayCounter &dc=Actual365Fixed(), Real displacement=0.0)
Handle< OptionletVolatilityStructure > vol_
std::vector< Time > accrualTimes
Definition: capfloor.hpp:145
std::vector< Rate > forwards
Definition: capfloor.hpp:148
std::vector< Date > startDates
Definition: capfloor.hpp:142
std::vector< Real > gearings
Definition: capfloor.hpp:149
std::vector< Rate > floorRates
Definition: capfloor.hpp:147
std::vector< Real > nominals
Definition: capfloor.hpp:151
std::vector< Date > endDates
Definition: capfloor.hpp:144
std::vector< Rate > capRates
Definition: capfloor.hpp:146
std::vector< Date > fixingDates
Definition: capfloor.hpp:143
Constant caplet volatility, no time-strike dependence.
Concrete date class.
Definition: date.hpp:125
day counter class
Definition: daycounter.hpp:44
Shared handle to an observable.
Definition: handle.hpp:41
std::map< std::string, ext::any > additionalResults
Definition: instrument.hpp:123
Calendar for reproducing theoretical calculations.
template class providing a null value for a given type.
Definition: null.hpp:76
std::pair< iterator, bool > registerWith(const ext::shared_ptr< Observable > &)
Definition: observable.hpp:228
Optionlet (caplet/floorlet) volatility structure.
Real Time
continuous quantity with 1-year units
Definition: types.hpp:62
QL_REAL Real
real number
Definition: types.hpp:50
Real DiscountFactor
discount factor between dates
Definition: types.hpp:66
Real Volatility
volatility
Definition: types.hpp:78
QL_INTEGER Integer
integer number
Definition: types.hpp:35
Real Rate
interest rates
Definition: types.hpp:70
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Real blackFormulaAssetItmProbability(Option::Type optionType, Real strike, Real forward, Real stdDev, Real displacement)
Real blackFormula(Option::Type optionType, Real strike, Real forward, Real stdDev, Real discount, Real displacement)
Real blackFormulaStdDevDerivative(Rate strike, Rate forward, Real stdDev, Real discount, Real displacement)
STL namespace.