Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
commodityswaptionengine.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file qle/pricingengines/commodityswaptionengine.hpp
20 \brief commodity swaption engine
21 \ingroup engines
22*/
23
24#ifndef quantext_commodity_swaption_engine_hpp
25#define quantext_commodity_swaption_engine_hpp
26
27#include <ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp>
28#include <ql/termstructures/yieldtermstructure.hpp>
31
32namespace QuantExt {
33using namespace QuantLib;
34
35//! Commodity Swaption Engine base class
36/*! Correlation is parametrized as rho(s, t) = exp(-beta * abs(s - t)) where s and t are times to futures expiry.
37 This is described in detail in the ORE+ Product Catalogue.
38 */
40public:
41 CommoditySwaptionBaseEngine(const Handle<YieldTermStructure>& discountCurve,
42 const Handle<QuantLib::BlackVolTermStructure>& vol, Real beta = 0.0);
43
44protected:
45 /*! Performs checks on the underlying swap to ensure that:
46 - it has two legs with a commodity fixed leg against a commodity floating leg
47 - every cashflow on the commodity floating leg is either averaging or non-averaging
48 Returns the index of the commodity fixed leg. Based on the checks, the commodity floating leg is the other leg.
49 */
50 QuantLib::Size fixedLegIndex() const;
51
52 //! Give back the fixed leg price at the swaption expiry time
53 QuantLib::Real fixedLegValue(QuantLib::Size fixedLegIndex) const;
54
55 /*! Need a strike price when querying the volatility surface in certain calculations. We take this as the
56 first fixed leg period amount divided by the first floating leg quantity.
57 */
58 QuantLib::Real strike(QuantLib::Size fixedLegIndex) const;
59
60 /*! Return the correlation between two future expiry dates \p ed_1 and \p ed_2
61 */
62 QuantLib::Real rho(const QuantLib::Date& ed_1, const QuantLib::Date& ed_2) const;
63
64 /*! Return `true` if floating leg is averaging, otherwise false.
65 */
66 bool averaging(QuantLib::Size floatLegIndex) const;
67
68 // set by the constructor
69 Handle<YieldTermStructure> discountCurve_;
70 Handle<QuantLib::BlackVolTermStructure> volStructure_;
71 Real beta_;
72};
73
74//! Commodity Swaption Analytical Engine
75/*! Analytical pricing based on the two-moment Turnbull-Wakeman approximation similar to APO pricing.
76 Reference: Iain Clark, Commodity Option Pricing, Wiley, section 2.8
77 See also the documentation in the ORE+ product catalogue.
78*/
80public:
81 CommoditySwaptionEngine(const Handle<YieldTermStructure>& discountCurve,
82 const Handle<QuantLib::BlackVolTermStructure>& vol, Real beta = 0.0)
83 : CommoditySwaptionBaseEngine(discountCurve, vol, beta) {}
84 void calculate() const override;
85
86private:
87 /*! Calculate the expected value of the floating leg at the swaption expiry date i.e. the expected value of the
88 quantity A(t_e) from the ORE+ Product Catalogue. Quantities in the calculation are divided by the
89 \p normFactor to guard against numerical blow up.
90 */
91 QuantLib::Real expA(QuantLib::Size floatLegIndex, QuantLib::Real normFactor) const;
92
93 /*! Calculate the expected value of the floating leg squared at the swaption expiry date i.e. the expected value
94 of the quantity A^2(t_e) from the ORE+ Product Catalogue. Quantities in the calculation are divided by the
95 \p normFactor to guard against numerical blow up.
96 */
97 QuantLib::Real expASquared(QuantLib::Size floatLegIndex, QuantLib::Real strike, QuantLib::Real normFactor) const;
98
99 /*! Calculate the cross terms involved in expASquared. Quantities in the calculation are divided by the
100 \p normFactor to guard against numerical blow up.
101 */
102 QuantLib::Real crossTerms(const QuantLib::ext::shared_ptr<QuantLib::CashFlow>& cf_1,
103 const QuantLib::ext::shared_ptr<QuantLib::CashFlow>& cf_2, bool isAveraging,
104 QuantLib::Real strike, QuantLib::Real normFactor) const;
105
106 /*! Return the maximum quantity over all cashflows on the commodity floating leg. This is used as a
107 normalisation factor in the calculation of E[A(t_e)] and E[A^2(t_e)] to guard against blow up.
108 */
109 QuantLib::Real maxQuantity(QuantLib::Size floatLegIndex) const;
110};
111
112//! Commodity Swaption Monte Carlo Engine
113/*! Monte Carlo implementation of the Swaption payoff for as documented in ORE+ Product Catalogue.
114 Reference: Iain Clark, Commodity Option Pricing, Wiley, section 2.8
115*/
117public:
118 CommoditySwaptionMonteCarloEngine(const Handle<YieldTermStructure>& discountCurve,
119 const Handle<QuantLib::BlackVolTermStructure>& vol, Size samples, Real beta = 0.0,
120 const Size seed = 42)
121 : CommoditySwaptionBaseEngine(discountCurve, vol, beta), samples_(samples), seed_(seed) {}
122 void calculate() const override;
123
124private:
125 //! Calculations when underlying swap references a commodity spot price
126 void calculateSpot(QuantLib::Size idxFixed, QuantLib::Size idxFloat, QuantLib::Real strike) const;
127
128 //! Calculations when underlying swap references a commodity spot price
129 void calculateFuture(QuantLib::Size idxFixed, QuantLib::Size idxFloat, QuantLib::Real strike) const;
130
131 /*! Calculate the underlying spot float leg factor value at expiry time. This quantity will be multiplied by
132 a sample value on each Monte Carlo iteration to give the swap float leg value.
133 */
134 QuantLib::Real spotFloatLegFactor(QuantLib::Size idxFloat, QuantLib::Real discountExercise) const;
135
136 /*! Populate the factors that we need to value the floating leg of a swap referencing a future contract given
137 a Monte Carlo sample. This is to avoid recalculation of these quantities on each iteration.
138 */
139 void futureFloatLegFactors(QuantLib::Size idxFloat, QuantLib::Real discountExercise,
140 const std::vector<QuantLib::Date>& expiries, QuantLib::Matrix& floatLegFactors,
141 QuantLib::Array& discounts, QuantLib::Array& amounts) const;
142
143 /*! Given the index of the floating leg \p idxFloat, populate a map where the keys are the unique expiry dates of
144 the future contracts referenced in the floating leg and the values are the volatilities associated with the
145 future contract. Also, the matrix \p outSqrtCorr is poulated with the square root of the correlation matrix
146 between the expiries.
147
148 An exception is thrown if the floating leg is not referencing a commodity future price.
149 */
150 std::map<QuantLib::Date, QuantLib::Real> futureExpiries(QuantLib::Size idxFloat, QuantLib::Matrix& outSqrtCorr,
151 QuantLib::Real strike) const;
152
154 long seed_;
155};
156
157} // namespace QuantExt
158
159#endif
Commodity Swaption Engine base class.
Handle< QuantLib::BlackVolTermStructure > volStructure_
QuantLib::Real rho(const QuantLib::Date &ed_1, const QuantLib::Date &ed_2) const
QuantLib::Real fixedLegValue(QuantLib::Size fixedLegIndex) const
Give back the fixed leg price at the swaption expiry time.
bool averaging(QuantLib::Size floatLegIndex) const
QuantLib::Real strike(QuantLib::Size fixedLegIndex) const
Commodity Swaption Analytical Engine.
CommoditySwaptionEngine(const Handle< YieldTermStructure > &discountCurve, const Handle< QuantLib::BlackVolTermStructure > &vol, Real beta=0.0)
QuantLib::Real expASquared(QuantLib::Size floatLegIndex, QuantLib::Real strike, QuantLib::Real normFactor) const
QuantLib::Real expA(QuantLib::Size floatLegIndex, QuantLib::Real normFactor) const
QuantLib::Real crossTerms(const QuantLib::ext::shared_ptr< QuantLib::CashFlow > &cf_1, const QuantLib::ext::shared_ptr< QuantLib::CashFlow > &cf_2, bool isAveraging, QuantLib::Real strike, QuantLib::Real normFactor) const
QuantLib::Real maxQuantity(QuantLib::Size floatLegIndex) const
Commodity Swaption Monte Carlo Engine.
void calculateSpot(QuantLib::Size idxFixed, QuantLib::Size idxFloat, QuantLib::Real strike) const
Calculations when underlying swap references a commodity spot price.
void futureFloatLegFactors(QuantLib::Size idxFloat, QuantLib::Real discountExercise, const std::vector< QuantLib::Date > &expiries, QuantLib::Matrix &floatLegFactors, QuantLib::Array &discounts, QuantLib::Array &amounts) const
void calculateFuture(QuantLib::Size idxFixed, QuantLib::Size idxFloat, QuantLib::Real strike) const
Calculations when underlying swap references a commodity spot price.
std::map< QuantLib::Date, QuantLib::Real > futureExpiries(QuantLib::Size idxFloat, QuantLib::Matrix &outSqrtCorr, QuantLib::Real strike) const
QuantLib::Real spotFloatLegFactor(QuantLib::Size idxFloat, QuantLib::Real discountExercise) const
CommoditySwaptionMonteCarloEngine(const Handle< YieldTermStructure > &discountCurve, const Handle< QuantLib::BlackVolTermStructure > &vol, Size samples, Real beta=0.0, const Size seed=42)
base class for swaption engines
Swaption class.
base class for multi path generators