Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
commodityapoengine.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/commodityapoengine.hpp
20 \brief commodity average price option engine
21 \ingroup engines
22*/
23
24#ifndef quantext_commodity_apo_engine_hpp
25#define quantext_commodity_apo_engine_hpp
26
30
31#include <ql/termstructures/volatility/equityfx/blackvoltermstructure.hpp>
32#include <ql/termstructures/yieldtermstructure.hpp>
33
34namespace QuantExt {
35
36namespace CommodityAveragePriceOptionMomementMatching {
37
38// Return the atm forward - accruals and the volatility of
40 Time tn;
41 Real forward;
43 Real sigma;
44 std::vector<QuantLib::Real> times;
45 std::vector<Real> forwards;
46 std::vector<Real> futureVols;
47 std::vector<Real> spotVols;
48 std::vector<std::string> indexNames;
49 std::vector<QuantLib::Date> pricingDates;
50 std::vector<QuantLib::Date> indexExpiries;
51 std::vector<QuantLib::Real> fixings;
52 Real EA2;
53
54 Real firstMoment();
55 Real secondMoment();
56 Real stdDev();
57 Time timeToExpriy();
58};
59
60// Matches the first two moments of a lognormal distribution
61// For options with accruals the strike of the options need to be adjusted by the accruals
62// See Iain Clark - Commodity Option Pricing A Practitioner’s Guide - Section 2.74
64 const ext::shared_ptr<CommodityIndexedAverageCashFlow>& flow,
65 const ext::shared_ptr<QuantLib::BlackVolTermStructure>& vol,
66 const std::function<double(const QuantLib::Date& expiry1, const QuantLib::Date& expiry2)>& rho,
67 QuantLib::Real strike = QuantLib::Null<QuantLib::Real>());
68}
69
70
71/*! Commodity APO Engine base class
72 Correlation is parametrized as \f$\rho(s, t) = \exp(-\beta * \abs(s - t))\f$
73 where \f$s\f$ and \f$t\f$ are times to futures expiry.
74 */
76public:
77 CommodityAveragePriceOptionBaseEngine(const QuantLib::Handle<QuantLib::YieldTermStructure>& discountCurve,
78 const QuantLib::Handle<QuantExt::BlackScholesModelWrapper>& model,
79 QuantLib::Real beta = 0.0);
80
81 // if you want speed-optimized observability, use the other constructor
82 CommodityAveragePriceOptionBaseEngine(const QuantLib::Handle<QuantLib::YieldTermStructure>& discountCurve,
83 const QuantLib::Handle<QuantLib::BlackVolTermStructure>& vol,
84 QuantLib::Real beta = 0.0);
85
86protected:
87 //! Return the correlation between two future expiry dates \p ed_1 and \p ed_2
88 QuantLib::Real rho(const QuantLib::Date& ed_1, const QuantLib::Date& ed_2) const;
89
90 /*! In certain cases, the APO value is not model dependent. This method returns \c true if the APO value is model
91 dependent. If the APO value is not model dependent, this method returns \c false and populates the results
92 with the model independent value.
93 */
94 bool isModelDependent() const;
95
96 /*! Check barriers on given (log-)price */
97 bool barrierTriggered(const Real price, const bool logPrice) const;
98
99 /*! Check whether option is alive depending on whether barrier was triggered */
100 bool alive(const bool barrierTriggered) const;
101
102 QuantLib::Handle<QuantLib::YieldTermStructure> discountCurve_;
103 QuantLib::Handle<QuantLib::BlackVolTermStructure> volStructure_;
104 QuantLib::Real beta_;
105 // used in checkBarrier() for efficiency, must be set by methods calling checkBarrier(p, true)
106 mutable QuantLib::Real logBarrier_;
107};
108
109/*! Commodity APO Analytical Engine
110 Analytical pricing based on the two-moment Turnbull-Wakeman approximation.
111 Reference: Iain Clark, Commodity Option Pricing, Wiley, section 2.7.4
112 See also the documentation in the ORE+ product catalogue.
113*/
115public:
117 void calculate() const override;
118};
119
120/*! Commodity APO Monte Carlo Engine
121 Monte Carlo implementation of the APO payoff
122 Reference: Iain Clark, Commodity Option Pricing, Wiley, section 2.7.4, equations (2.118) and (2.126)
123*/
125public:
126 CommodityAveragePriceOptionMonteCarloEngine(const QuantLib::Handle<QuantLib::YieldTermStructure>& discountCurve,
127 const QuantLib::Handle<QuantExt::BlackScholesModelWrapper>& model,
128 QuantLib::Size samples, QuantLib::Real beta = 0.0,
129 const QuantLib::Size seed = 42)
130 : CommodityAveragePriceOptionBaseEngine(discountCurve, model, beta), samples_(samples), seed_(seed) {}
131
132 // if you want speed-optimized observability, use the other constructor
133 CommodityAveragePriceOptionMonteCarloEngine(const QuantLib::Handle<QuantLib::YieldTermStructure>& discountCurve,
134 const QuantLib::Handle<QuantLib::BlackVolTermStructure>& vol,
135 QuantLib::Size samples, QuantLib::Real beta = 0.0,
136 const QuantLib::Size seed = 42)
137 : CommodityAveragePriceOptionBaseEngine(discountCurve, vol, beta), samples_(samples), seed_(seed) {}
138
139 void calculate() const override;
140
141private:
142 //! Calculations when underlying swap references a commodity spot price
143 void calculateSpot() const;
144
145 //! Calculations when underlying swap references a commodity spot price
146 void calculateFuture() const;
147
148 /*! Prepare data for APO calculation. The \p outVolatilities parameter will be populated with separate future
149 contract volatilities taking into account the \p strike level. The number of elements of \p outVolatilities
150 gives the number, N, of future contracts involved in the non-accrued portion of the APO. The matrix
151 \p outSqrtCorr is populated with the square root of the correlation matrix between the future contracts.
152 The \p outPrices vector will be populated with the current future price values. The \p futureIndex is
153 populated with the index of the future to be used on each timestep in the simulation.
154 */
155 void setupFuture(std::vector<QuantLib::Real>& outVolatilities, QuantLib::Matrix& outSqrtCorr,
156 std::vector<QuantLib::Real>& outPrices, std::vector<QuantLib::Size>& futureIndex,
157 QuantLib::Real strike) const;
158
159 /*! Return the \f$n\f$ timesteps from today, \f$t_0\f$, up to \f$t_n\f$ where \f$n > 0\f$. Note that each
160 \f$t_i\f$ corresponds to a pricing date \f$d_i\f$ that is after today. The method returns the vector of time
161 deltas \f$t_i - t_{i-1}\f$ for \f$i=1,\ldots,n\f$ and populates the vector \p outDates with the dates
162 \f$d_0, d_1,...,d_n\f$. Note that the size of \p outDates is one larger than the size of the return vector.
163 */
164 std::vector<QuantLib::Real> timegrid(std::vector<QuantLib::Date>& outDates) const;
165
166 QuantLib::Size samples_;
167 QuantLib::Size seed_;
168};
169
170} // namespace QuantExt
171
172#endif
wrapper around a vector of BS processes
bool barrierTriggered(const Real price, const bool logPrice) const
QuantLib::Real rho(const QuantLib::Date &ed_1, const QuantLib::Date &ed_2) const
Return the correlation between two future expiry dates ed_1 and ed_2.
CommodityAveragePriceOptionBaseEngine(const QuantLib::Handle< QuantLib::YieldTermStructure > &discountCurve, const QuantLib::Handle< QuantExt::BlackScholesModelWrapper > &model, QuantLib::Real beta=0.0)
QuantLib::Handle< QuantLib::YieldTermStructure > discountCurve_
QuantLib::Handle< QuantLib::BlackVolTermStructure > volStructure_
bool alive(const bool barrierTriggered) const
CommodityAveragePriceOptionMonteCarloEngine(const QuantLib::Handle< QuantLib::YieldTermStructure > &discountCurve, const QuantLib::Handle< QuantLib::BlackVolTermStructure > &vol, QuantLib::Size samples, QuantLib::Real beta=0.0, const QuantLib::Size seed=42)
CommodityAveragePriceOptionMonteCarloEngine(const QuantLib::Handle< QuantLib::YieldTermStructure > &discountCurve, const QuantLib::Handle< QuantExt::BlackScholesModelWrapper > &model, QuantLib::Size samples, QuantLib::Real beta=0.0, const QuantLib::Size seed=42)
void calculateFuture() const
Calculations when underlying swap references a commodity spot price.
void setupFuture(std::vector< QuantLib::Real > &outVolatilities, QuantLib::Matrix &outSqrtCorr, std::vector< QuantLib::Real > &outPrices, std::vector< QuantLib::Size > &futureIndex, QuantLib::Real strike) const
std::vector< QuantLib::Real > timegrid(std::vector< QuantLib::Date > &outDates) const
void calculateSpot() const
Calculations when underlying swap references a commodity spot price.
Swaption class.
base class for multi path generators
MomentMatchingResults matchFirstTwoMomentsTurnbullWakeman(const ext::shared_ptr< CommodityIndexedAverageCashFlow > &flow, const ext::shared_ptr< QuantLib::BlackVolTermStructure > &vol, const std::function< double(const QuantLib::Date &expiry1, const QuantLib::Date &expiry2)> &rho, QuantLib::Real strike)