Skip to content

Commit 9fc9715

Browse files
mgronckijenkins
authored andcommitted
QPR-11626 comm spread option improve additional results
include averaging fixings and pricing dates
1 parent 2350877 commit 9fc9715

4 files changed

Lines changed: 33 additions & 5 deletions

File tree

QuantExt/qle/pricingengines/commodityapoengine.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,23 @@ MomentMatchingResults matchFirstTwoMomentsTurnbullWakeman(
5656
std::map<Date, Real> futureVols;
5757
std::vector<double> spotVariances;
5858
size_t n = flow->indices().size();
59-
double forwardUnderlyingCurrency = 0;
59+
double atmUnderlyingCcy = 0;
6060

6161
for (const auto& [pricingDate, index] : flow->indices()) {
6262
Date fixingDate = index->fixingCalendar().adjust(pricingDate, Preceding);
6363
Real fxRate = (flow->fxIndex()) ? flow->fxIndex()->fixing(fixingDate) : 1.0;
64+
res.indexNames.push_back(index->name());
65+
res.pricingDates.push_back(fixingDate);
66+
res.indexExpiries.push_back(index->expiryDate());
67+
res.fixings.push_back(index->fixing(fixingDate) * fxRate);
6468
if (pricingDate <= today) {
65-
res.accruals += index->fixing(fixingDate) * fxRate;
69+
res.accruals += res.fixings.back();
6670
} else {
67-
forwardUnderlyingCurrency = index->fixing(fixingDate);
68-
res.forwards.push_back(index->fixing(fixingDate) * fxRate);
71+
atmUnderlyingCcy = index->fixing(fixingDate);
72+
res.forwards.push_back(res.fixings.back());
6973
res.times.push_back(vol->timeFromReference(pricingDate));
7074
// use ATM vol if no strike is given
71-
double K = strike == Null<Real>() ? forwardUnderlyingCurrency : strike;
75+
double K = strike == Null<Real>() ? atmUnderlyingCcy : strike;
7276
if (flow->useFuturePrice()) {
7377
Date expiry = index->expiryDate();
7478
futureExpiries.push_back(expiry);

QuantExt/qle/pricingengines/commodityapoengine.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ struct MomentMatchingResults {
4545
std::vector<Real> forwards;
4646
std::vector<Real> futureVols;
4747
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;
4852
Real EA2;
4953

5054
Real firstMoment();

QuantExt/qle/pricingengines/commodityspreadoptionengine.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,14 @@ void CommoditySpreadOptionAnalyticalEngine::calculate() const {
152152
mp["w1"] = w1;
153153
mp["w2"] = w2;
154154
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;
155163
}
156164

157165
CommoditySpreadOptionAnalyticalEngine::PricingParameter
@@ -171,6 +179,10 @@ CommoditySpreadOptionAnalyticalEngine::derivePricingParameterFromFlow(const ext:
171179
res.sigma = res.tn > 0 && !QuantLib::close_enough(res.tn, 0.0)
172180
? vol->blackVol(res.tn, atmUnderlyingCurrency, true)
173181
: 0.0;
182+
res.indexNames.push_back(cf->index()->name());
183+
res.expiries.push_back(cf->index()->expiryDate());
184+
res.fixings.push_back(atmUnderlyingCurrency);
185+
res.pricingDates.push_back(cf->pricingDate());
174186
} else if (auto avgCf = ext::dynamic_pointer_cast<CommodityIndexedAverageCashFlow>(flow)) {
175187
auto parameter = CommodityAveragePriceOptionMomementMatching::matchFirstTwoMomentsTurnbullWakeman(
176188
avgCf, vol,
@@ -180,6 +192,10 @@ CommoditySpreadOptionAnalyticalEngine::derivePricingParameterFromFlow(const ext:
180192
res.atm = parameter.forward;
181193
res.accruals = parameter.accruals;
182194
res.sigma = parameter.sigma;
195+
res.indexNames = parameter.indexNames;
196+
res.expiries = parameter.indexExpiries;
197+
res.fixings = parameter.fixings;
198+
res.pricingDates = parameter.pricingDates;
183199
} else {
184200
QL_FAIL("SpreadOptionEngine supports only CommodityIndexedCashFlow or CommodityIndexedAverageCashFlow");
185201
}

QuantExt/qle/pricingengines/commodityspreadoptionengine.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class CommoditySpreadOptionAnalyticalEngine : public CommoditySpreadOption::engi
5454
Real atm;
5555
Real sigma;
5656
Real accruals;
57+
std::vector<QuantLib::Date> pricingDates;
58+
std::vector<std::string> indexNames;
59+
std::vector<Real> fixings;
60+
std::vector<QuantLib::Date> expiries;
5761
};
5862

5963
PricingParameter derivePricingParameterFromFlow(const ext::shared_ptr<CommodityCashFlow>& flow,

0 commit comments

Comments
 (0)