Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | List of all members
AnalyticCashSettledEuropeanEngine Class Reference

Pricing engine for cash settled European vanilla options using analytical formulae. More...

#include <qle/pricingengines/analyticcashsettledeuropeanengine.hpp>

+ Inheritance diagram for AnalyticCashSettledEuropeanEngine:
+ Collaboration diagram for AnalyticCashSettledEuropeanEngine:

Public Member Functions

 AnalyticCashSettledEuropeanEngine (const QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > &bsp)
 
 AnalyticCashSettledEuropeanEngine (const QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > &bsp, const QuantLib::Handle< QuantLib::YieldTermStructure > &discountCurve)
 

PricingEngine interface

QuantExt::AnalyticEuropeanForwardEngine underlyingEngine_
 Underlying engine that does the work. More...
 
QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > bsp_
 Underlying process. More...
 
QuantLib::Handle< QuantLib::YieldTermStructure > discountCurve_
 Curve for discounting cashflows. More...
 
void calculate () const override
 

Detailed Description

Pricing engine for cash settled European vanilla options using analytical formulae.

Definition at line 36 of file analyticcashsettledeuropeanengine.hpp.

Constructor & Destructor Documentation

◆ AnalyticCashSettledEuropeanEngine() [1/2]

AnalyticCashSettledEuropeanEngine ( const QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > &  bsp)

The risk-free rate in the given process bsp is used for both forecasting and discounting.

◆ AnalyticCashSettledEuropeanEngine() [2/2]

AnalyticCashSettledEuropeanEngine ( const QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > &  bsp,
const QuantLib::Handle< QuantLib::YieldTermStructure > &  discountCurve 
)

As usual, the risk-free rate from the given process bsp is used for forecasting the forward price. The discountCurve is used for discounting.

Member Function Documentation

◆ calculate()

void calculate ( ) const
override

Definition at line 54 of file analyticcashsettledeuropeanengine.cpp.

54 {
55
56 // Same logic as underlying engine for discount curve.
57 QuantLib::ext::shared_ptr<YieldTermStructure> dts =
58 discountCurve_.empty() ? bsp_->riskFreeRate().currentLink() : discountCurve_.currentLink();
59
60 // Option expiry date.
61 Date expiryDate = arguments_.exercise->lastDate();
62
63 Date today = Settings::instance().evaluationDate();
64 if (expiryDate <= today) {
65 // If expiry has occurred, we attempt to establish the payoff amount, if any, and discount it.
66 Real payoffAmount = 0.0;
67 Real priceAtExercise = 0.0;
68 bool deterministicPayoff = true;
69 if (arguments_.automaticExercise) {
70 // If we have automatic exercise, we base the payoff on the value of the index on the expiry date.
71 QL_REQUIRE(arguments_.underlying, "Expect a valid underlying index when exercise is automatic.");
72 priceAtExercise = arguments_.underlying->fixing(expiryDate);
73 payoffAmount = (*arguments_.payoff)(priceAtExercise);
74 } else if (arguments_.exercised) {
75 // If we have manually exercised, we base the payoff on the value at exercise.
76 QL_REQUIRE(arguments_.priceAtExercise != Null<Real>(), "Expect a valid price at exercise when option "
77 << "has been manually exercised.");
78 priceAtExercise = arguments_.priceAtExercise;
79 payoffAmount = (*arguments_.payoff)(priceAtExercise);
80 } else if (expiryDate == today) {
81 // Expiry date is today, not automatic exercise and hasn't been manually exercised - use spot.
82 priceAtExercise = bsp_->x0();
83 payoffAmount = (*arguments_.payoff)(priceAtExercise);
84 deterministicPayoff = false;
85 }
86
87 if(deterministicPayoff) {
88 results_.delta = 0.0;
89 results_.deltaForward = 0.0;
90 results_.elasticity = 0.0;
91 results_.gamma = 0.0;
92 results_.dividendRho = 0.0;
93 results_.vega = 0.0;
94 }
95
96 // Discount factor to payment date.
97 DiscountFactor df_tp = dts->discount(arguments_.paymentDate);
98 Time delta_tp = dts->timeFromReference(arguments_.paymentDate);
99
100 // Only value, rho and theta are meaningful now.
101 results_.value = df_tp * payoffAmount;
102 results_.rho = -delta_tp * results_.value;
103 results_.theta = 0.0;
104 if (delta_tp > 0.0 && !close(delta_tp, 0.0)) {
105 results_.theta = -std::log(df_tp) / delta_tp * results_.value;
106 }
107 results_.thetaPerDay = results_.theta / 365.0;
108
109 // Populate some additional results.
110 results_.additionalResults["spot"] = bsp_->x0();
111 auto payoff = QuantLib::ext::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
112 if (payoff)
113 results_.additionalResults["strike"] = payoff->strike();
114 results_.additionalResults["priceAtExercise"] = priceAtExercise;
115 results_.additionalResults["payoffAmount"] = payoffAmount;
116 results_.additionalResults["discountFactor"] = df_tp;
117 results_.additionalResults["timeToExpiry"] = delta_tp;
118
119 } else {
120
121 // If expiry has not occurred, we use the underlying engine and amend the results to account
122 // for the deferred cash payment.
123
124 // Prepare the underlying engine for the valuation.
125 underlyingEngine_.reset();
126 VanillaForwardOption::arguments* underlyingArgs =
127 dynamic_cast<VanillaForwardOption::arguments*>(underlyingEngine_.getArguments());
128 QL_REQUIRE(underlyingArgs, "Underlying engine expected to have vanilla option arguments.");
129 underlyingArgs->exercise = arguments_.exercise;
130 underlyingArgs->payoff = arguments_.payoff;
131
132 // If we have a commodity future index, set the forward date to its expiry to get the right future price
133 // in the Black formula. If not, just use the expiry date => same result as standard QL engine.
134 if (auto cfi = QuantLib::ext::dynamic_pointer_cast<CommodityFuturesIndex>(arguments_.underlying)) {
135 underlyingArgs->forwardDate = cfi->expiryDate();
136 } else {
137 underlyingArgs->forwardDate = expiryDate;
138 }
140
141 // Discount factor from payment date back to expiry date i.e. P(t_e, t_p) when rates are deterministic.
142 DiscountFactor df_te_tp = dts->discount(arguments_.paymentDate) / dts->discount(expiryDate);
143 Time delta_te_tp = dts->timeFromReference(arguments_.paymentDate) - dts->timeFromReference(expiryDate);
144
145 // Populate this engine's results using the results from the underlying engine.
146 const CashSettledEuropeanOption::results* underlyingResults =
147 dynamic_cast<const CashSettledEuropeanOption::results*>(underlyingEngine_.getResults());
148 QL_REQUIRE(underlyingResults, "Underlying engine expected to have compatible results.");
149
150 results_.value = df_te_tp * underlyingResults->value;
151 results_.delta = df_te_tp * underlyingResults->delta;
152 results_.deltaForward = df_te_tp * underlyingResults->deltaForward;
153 results_.elasticity = underlyingResults->elasticity;
154 results_.gamma = df_te_tp * underlyingResults->gamma;
155 results_.rho = df_te_tp * (underlyingResults->rho - delta_te_tp * underlyingResults->value);
156 results_.dividendRho = df_te_tp * underlyingResults->dividendRho;
157 results_.vega = df_te_tp * underlyingResults->vega;
158 if (underlyingResults->theta != Null<Real>())
159 results_.theta = df_te_tp * underlyingResults->theta;
160 if (underlyingResults->thetaPerDay != Null<Real>())
161 results_.thetaPerDay = df_te_tp * underlyingResults->thetaPerDay;
162 results_.strikeSensitivity = df_te_tp * underlyingResults->strikeSensitivity;
163 results_.itmCashProbability = underlyingResults->itmCashProbability;
164
165 // Take the additional results from the underlying engine and add more.
166 results_.additionalResults = underlyingResults->additionalResults;
167 results_.additionalResults["discountFactorTeTp"] = df_te_tp;
168 }
169
170}
const Instrument::results * results_
Definition: cdsoption.cpp:81
QuantLib::Handle< QuantLib::YieldTermStructure > discountCurve_
Curve for discounting cashflows.
QuantExt::AnalyticEuropeanForwardEngine underlyingEngine_
Underlying engine that does the work.
QuantLib::ext::shared_ptr< QuantLib::GeneralizedBlackScholesProcess > bsp_
Underlying process.
Swap::arguments * arguments_

Member Data Documentation

◆ underlyingEngine_

QuantExt::AnalyticEuropeanForwardEngine underlyingEngine_
mutableprivate

Underlying engine that does the work.

Definition at line 55 of file analyticcashsettledeuropeanengine.hpp.

◆ bsp_

QuantLib::ext::shared_ptr<QuantLib::GeneralizedBlackScholesProcess> bsp_
private

Underlying process.

Definition at line 57 of file analyticcashsettledeuropeanengine.hpp.

◆ discountCurve_

QuantLib::Handle<QuantLib::YieldTermStructure> discountCurve_
private

Curve for discounting cashflows.

Definition at line 59 of file analyticcashsettledeuropeanengine.hpp.