51 {
52
53 auto& mp =
results_.additionalResults;
54 QL_REQUIRE(
arguments_.exercise->type() == QuantLib::Exercise::European,
"Only European Spread Option supported");
56
57 Date today = Settings::instance().evaluationDate();
58
59 Date exerciseDate =
arguments_.exercise->lastDate();
60
62 if (paymentDate == Date())
64
65 QL_REQUIRE(paymentDate >= exerciseDate, "Payment date needs to be on or after exercise date");
66
68
71
72 auto parameterFlow1 =
74
75 auto parameterFlow2 =
77
78 double F1 = parameterFlow1.atm;
79 double F2 = parameterFlow2.atm;
80 double sigma1 = parameterFlow1.sigma;
81 double sigma2 = parameterFlow2.sigma;
82 double obsTime1 = parameterFlow1.tn;
83 double obsTime2 = parameterFlow2.tn;
84 double accruals1 = parameterFlow1.accruals;
85 double accruals2 = parameterFlow2.accruals;
86
87 double sigma = 0;
88 double stdDev = 0;
89 double Y = 0;
90 double Z = 0;
91 double sigmaY = 0;
92 double w1 =
arguments_.longAssetFlow->gearing();
93 double w2 =
arguments_.shortAssetFlow->gearing();
94
95 double effectiveStrike =
arguments_.effectiveStrike - w1 * accruals1 + w2 * accruals2;
96 Real correlation = QuantLib::Null<Real>();
97
98 if (exerciseDate <= today && paymentDate <= today) {
100 } else if (exerciseDate <= today && paymentDate > today) {
101
102
103 double omega =
arguments_.type == Option::Call ? 1 : -1;
104
105 results_.value = df *
arguments_.quantity * omega * std::max(w1 * F1 - w2 * F2 - effectiveStrike, 0.0);
106
107 } else if (effectiveStrike + F2 * w2 < 0) {
108
110 results_.value = df *
arguments_.quantity * std::max(w1 * F1 - w2 * F2 - effectiveStrike, 0.0);
111 } else {
113 }
114
115 } else {
116 sigma1 = sigma1 * std::min(1.0, std::sqrt(obsTime1 / tte));
117 sigma2 = sigma2 * std::min(1.0, std::sqrt(obsTime2 / tte));
119
120 Y = (F2 * w2 + effectiveStrike);
121 Z = w1 * F1 / Y;
122 sigmaY = sigma2 * F2 * w2 / Y;
123
124 sigma = std::sqrt(std::pow(sigma1, 2.0) + std::pow(sigmaY, 2.0) - 2 * sigma1 * sigmaY * correlation);
125
126 stdDev = sigma *
sqrt(tte);
127
129 }
130
131
132 mp["F1"] = F1;
133 mp["accruals1"] = accruals1;
134 mp["sigma1"] = sigma1;
135 mp["obsTime1"] = obsTime1;
136 mp["F2"] = F2;
137 mp["accruals2"] = accruals2;
138 mp["sigma2"] = sigma2;
139 mp["obsTime2"] = obsTime2;
140 mp["tte"] = tte;
141 mp["ttp"] = ttp;
142 mp["df"] = df;
143 mp["sigma"] = sigma;
144 mp["stdDev"] = stdDev;
145 mp["Y"] = Y;
146 mp["Z"] = Z;
147 mp["sigma_Y"] = sigmaY;
150 mp["exerciseDate"] = exerciseDate;
151 mp["paymentDate"] = paymentDate;
152 mp["w1"] = w1;
153 mp["w2"] = w2;
154 mp["rho"] = correlation;
155 mp["index1_pricingDates"] = parameterFlow1.pricingDates;
156 mp["index1_index"] = parameterFlow1.indexNames;
157 mp["index1_index_expiry"] = parameterFlow1.expiries;
158 mp["index1_fixing"] = parameterFlow1.fixings;
159 mp["index2_pricingDates"] = parameterFlow2.pricingDates;
160 mp["index2_index"] = parameterFlow2.indexNames;
161 mp["index2_index_expiry"] = parameterFlow2.expiries;
162 mp["index2_fixing"] = parameterFlow2.fixings;
163}
const Instrument::results * results_
PricingParameter derivePricingParameterFromFlow(const ext::shared_ptr< CommodityCashFlow > &flow, const ext::shared_ptr< BlackVolTermStructure > &vol, const ext::shared_ptr< FxIndex > &fxIndex) const
RandomVariable sqrt(RandomVariable x)
Swap::arguments * arguments_