Skip to content

Commit e736726

Browse files
Merge remote-tracking branch 'origin/master' into github_modules
2 parents 0ec4585 + 07d3f72 commit e736726

18 files changed

Lines changed: 145 additions & 22 deletions

OREAnalytics/orea/app/reportwriter.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,22 @@ void addInflationCurveCalibrationInfo(ore::data::Report& report, const std::stri
12521252
}
12531253
}
12541254

1255+
void addCommodityCurveCalibrationInfo(ore::data::Report& report, const std::string& id,
1256+
boost::shared_ptr<CommodityCurveCalibrationInfo> const& info) {
1257+
if(info == nullptr)
1258+
return ;
1259+
addRowMktCalReport(report, "commodityCurve", id, "calendar", "", "", "", info->calendar);
1260+
addRowMktCalReport(report, "commodityCurve", id, "dayCounter", "", "", "", info->dayCounter);
1261+
addRowMktCalReport(report, "commodityCurve", id, "currenct", "", "", "", info->currency);
1262+
addRowMktCalReport(report, "commodityCurve", id, "interpolationMethod", "", "", "", info->interpolationMethod);
1263+
1264+
for (Size i = 0; i < info->pillarDates.size(); ++i){
1265+
auto date = to_string(info->pillarDates.at(i));
1266+
addRowMktCalReport(report, "commodityCurve", id, "time", date, "", "", info->times.at(i));
1267+
addRowMktCalReport(report, "commodityCurve", id, "price", date, "", "", info->futurePrices.at(i));
1268+
}
1269+
}
1270+
12551271
void addFxEqVolCalibrationInfo(ore::data::Report& report, const std::string& type, const std::string& id,
12561272
boost::shared_ptr<FxEqVolCalibrationInfo> info) {
12571273
if (info == nullptr)
@@ -1404,6 +1420,12 @@ void ReportWriter::writeTodaysMarketCalibrationReport(
14041420
addInflationCurveCalibrationInfo(report, r.first, r.second);
14051421
}
14061422

1423+
// commodity curve results
1424+
1425+
for (auto const& r :calibrationInfo->commodityCurveCalibrationInfo) {
1426+
addCommodityCurveCalibrationInfo(report, r.first, r.second);
1427+
}
1428+
14071429
// fx vol results
14081430
for (auto const& r : calibrationInfo->fxVolCalibrationInfo) {
14091431
addFxEqVolCalibrationInfo(report, "fxVol", r.first, r.second);

OREData/OREData.vcxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@
111111
<ClInclude Include="ored\model\calibrationinstruments\yoycapfloor.hpp" />
112112
<ClInclude Include="ored\model\calibrationinstruments\yoyswap.hpp" />
113113
<ClInclude Include="ored\model\calibrationpointcache.hpp" />
114+
<ClInclude Include="ored\model\commodityschwartzmodelbuilder.hpp" />
115+
<ClInclude Include="ored\model\commodityschwartzmodeldata.hpp" />
114116
<ClInclude Include="ored\model\crcirbuilder.hpp" />
115117
<ClInclude Include="ored\model\crcirdata.hpp" />
116118
<ClInclude Include="ored\model\crlgmbuilder.hpp" />
@@ -380,6 +382,8 @@
380382
<ClCompile Include="ored\model\calibrationinstruments\yoycapfloor.cpp" />
381383
<ClCompile Include="ored\model\calibrationinstruments\yoyswap.cpp" />
382384
<ClCompile Include="ored\model\calibrationpointcache.cpp" />
385+
<ClCompile Include="ored\model\commodityschwartzmodelbuilder.cpp" />
386+
<ClCompile Include="ored\model\commodityschwartzmodeldata.cpp" />
383387
<ClCompile Include="ored\model\crcirbuilder.cpp" />
384388
<ClCompile Include="ored\model\crcirdata.cpp" />
385389
<ClCompile Include="ored\model\crlgmbuilder.cpp" />

OREData/OREData.vcxproj.filters

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,12 @@
852852
<ClInclude Include="ored\portfolio\builders\fxdigitaloption.hpp">
853853
<Filter>portfolio\builders</Filter>
854854
</ClInclude>
855+
<ClInclude Include="ored\model\commodityschwartzmodelbuilder.hpp">
856+
<Filter>model</Filter>
857+
</ClInclude>
858+
<ClInclude Include="ored\model\commodityschwartzmodeldata.hpp">
859+
<Filter>model</Filter>
860+
</ClInclude>
855861
</ItemGroup>
856862
<ItemGroup>
857863
<ClCompile Include="ored\configuration\capfloorvolcurveconfig.cpp">
@@ -1479,5 +1485,11 @@
14791485
<ClCompile Include="ored\model\hwbuilder.cpp">
14801486
<Filter>model</Filter>
14811487
</ClCompile>
1488+
<ClCompile Include="ored\model\commodityschwartzmodelbuilder.cpp">
1489+
<Filter>model</Filter>
1490+
</ClCompile>
1491+
<ClCompile Include="ored\model\commodityschwartzmodeldata.cpp">
1492+
<Filter>model</Filter>
1493+
</ClCompile>
14821494
</ItemGroup>
1483-
</Project>
1495+
</Project>

OREData/ored/marketdata/commoditycurve.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ CommodityCurve::CommodityCurve(const Date& asof, const CommodityCurveSpec& spec,
112112
const CurveConfigurations& curveConfigs,
113113
const FXTriangulation& fxSpots,
114114
const map<string, boost::shared_ptr<YieldCurve>>& yieldCurves,
115-
const map<string, boost::shared_ptr<CommodityCurve>>& commodityCurves)
115+
const map<string, boost::shared_ptr<CommodityCurve>>& commodityCurves,
116+
bool const buildCalibrationInfo)
116117
: spec_(spec), commoditySpot_(Null<Real>()), onValue_(Null<Real>()), tnValue_(Null<Real>()), regexQuotes_(false) {
117118

118119
try {
@@ -168,7 +169,21 @@ CommodityCurve::CommodityCurve(const Date& asof, const CommodityCurveSpec& spec,
168169

169170
Handle<PriceTermStructure> pts(commodityPriceCurve_);
170171
commodityIndex_ = parseCommodityIndex(spec_.curveConfigID(), false, pts);
171-
172+
commodityPriceCurve_->pillarDates();
173+
174+
if (buildCalibrationInfo) { // the curve is built, save info for later usage
175+
auto calInfo = boost::make_shared<CommodityCurveCalibrationInfo>();
176+
calInfo->dayCounter = dayCounter_.name();
177+
calInfo->interpolationMethod = interpolationMethod_;
178+
calInfo->calendar = commodityPriceCurve_->calendar().name();
179+
calInfo->currency = commodityPriceCurve_->currency().code();
180+
for (auto d : commodityPriceCurve_->pillarDates()){
181+
calInfo->times.emplace_back(commodityPriceCurve_->timeFromReference(d));
182+
calInfo->pillarDates.emplace_back(d);
183+
calInfo->futurePrices.emplace_back(commodityPriceCurve_->price(d, true));
184+
}
185+
calibrationInfo_ = calInfo;
186+
}
172187
} catch (std::exception& e) {
173188
QL_FAIL("commodity curve building failed: " << e.what());
174189
} catch (...) {

OREData/ored/marketdata/commoditycurve.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <ored/marketdata/fxtriangulation.hpp>
3131
#include <ored/marketdata/loader.hpp>
3232
#include <ored/marketdata/yieldcurve.hpp>
33+
#include <ored/marketdata/todaysmarketcalibrationinfo.hpp>
3334
#include <ql/math/interpolations/backwardflatinterpolation.hpp>
3435
#include <ql/math/interpolations/linearinterpolation.hpp>
3536
#include <ql/math/interpolations/loginterpolation.hpp>
@@ -51,20 +52,23 @@ class CommodityCurve {
5152
const CurveConfigurations& curveConfigs,
5253
const FXTriangulation& fxSpots = FXTriangulation(),
5354
const std::map<std::string, boost::shared_ptr<YieldCurve>>& yieldCurves = {},
54-
const std::map<std::string, boost::shared_ptr<CommodityCurve>>& commodityCurves = {});
55+
const std::map<std::string, boost::shared_ptr<CommodityCurve>>& commodityCurves = {},
56+
bool const buildCalibrationInfo = false);
5557
//@}
5658

5759
//! \name Inspectors
5860
//@{
5961
const CommodityCurveSpec& spec() const { return spec_; }
6062
boost::shared_ptr<QuantExt::PriceTermStructure> commodityPriceCurve() const { return commodityPriceCurve_; }
6163
boost::shared_ptr<QuantExt::CommodityIndex> commodityIndex() const { return commodityIndex_; }
64+
boost::shared_ptr<CommodityCurveCalibrationInfo> calibrationInfo() const { return calibrationInfo_; }
6265
//@}
6366

6467
private:
6568
CommodityCurveSpec spec_;
6669
boost::shared_ptr<QuantExt::PriceTermStructure> commodityPriceCurve_;
6770
boost::shared_ptr<QuantExt::CommodityIndex> commodityIndex_;
71+
boost::shared_ptr<CommodityCurveCalibrationInfo> calibrationInfo_;
6872

6973
//! Store the commodity spot value with \c Null<Real>() indicating that none has been provided.
7074
QuantLib::Real commoditySpot_;

OREData/ored/marketdata/todaysmarket.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -716,17 +716,18 @@ void TodaysMarket::buildNode(const std::string& configuration, Node& node) const
716716
QL_REQUIRE(commodityCurveSpec, "Failed to convert spec, " << *spec << ", to CommodityCurveSpec");
717717
auto itr = requiredCommodityCurves_.find(commodityCurveSpec->name());
718718
if (itr == requiredCommodityCurves_.end()) {
719-
DLOG("Building CommodityCurve for asof " << asof_);
719+
DLOG("Building CommodityCurve " << commodityCurveSpec->name() << " for asof " << asof_);
720720
boost::shared_ptr<CommodityCurve> commodityCurve =
721721
boost::make_shared<CommodityCurve>(asof_, *commodityCurveSpec, *loader_, *curveConfigs_, *fx_,
722-
requiredYieldCurves_, requiredCommodityCurves_);
722+
requiredYieldCurves_, requiredCommodityCurves_, buildCalibrationInfo_);
723723
itr = requiredCommodityCurves_.insert(make_pair(commodityCurveSpec->name(), commodityCurve)).first;
724724
}
725725

726726
DLOG("Adding CommodityCurve, " << node.name << ", with spec " << *commodityCurveSpec << " to configuration "
727727
<< configuration);
728728
Handle<CommodityIndex> commIdx(itr->second->commodityIndex());
729729
commodityIndices_[make_pair(configuration, node.name)] = commIdx;
730+
calibrationInfo_->commodityCurveCalibrationInfo[commodityCurveSpec->name()] = itr->second->calibrationInfo();
730731
break;
731732
}
732733

OREData/ored/marketdata/todaysmarketcalibrationinfo.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,19 @@ struct YoYInflationCurveCalibrationInfo : public InflationCurveCalibrationInfo {
9191
std::vector<double> yoyRates;
9292
};
9393

94+
// commodity curves
95+
96+
struct CommodityCurveCalibrationInfo {
97+
virtual ~CommodityCurveCalibrationInfo() = default;
98+
std::string dayCounter;
99+
std::string calendar;
100+
std::string currency;
101+
std::string interpolationMethod;
102+
std::vector<QuantLib::Date> pillarDates;
103+
std::vector<QuantLib::Real> futurePrices;
104+
std::vector<QuantLib::Real> times;
105+
};
106+
94107
// fx, eq vols
95108

96109
struct FxEqVolCalibrationInfo {
@@ -161,6 +174,8 @@ struct TodaysMarketCalibrationInfo {
161174
std::map<std::string, boost::shared_ptr<YieldCurveCalibrationInfo>> dividendCurveCalibrationInfo;
162175
// inflation curves
163176
std::map<std::string, boost::shared_ptr<InflationCurveCalibrationInfo>> inflationCurveCalibrationInfo;
177+
// commodity curves
178+
std::map<std::string, boost::shared_ptr<CommodityCurveCalibrationInfo>> commodityCurveCalibrationInfo;
164179
// fx vols
165180
std::map<std::string, boost::shared_ptr<FxEqVolCalibrationInfo>> fxVolCalibrationInfo;
166181
// eq vols

OREData/ored/portfolio/builders/equitydigitaloption.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class EquityDigitalOptionEngineBuilder
5858
market_->equityForecastCurve(assetName, configuration(ore::data::MarketContext::pricing)),
5959
market_->equityVol(assetName, configuration(ore::data::MarketContext::pricing)));
6060

61-
return boost::make_shared<AnalyticEuropeanEngine>(gbsp);
61+
return boost::make_shared<QuantExt::AnalyticEuropeanEngine>(gbsp);
6262
}
6363
};
6464

OREData/ored/portfolio/builders/equitytouchoption.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ class EquityTouchOptionEngineBuilder
6363

6464
if (type == "One-Touch") {
6565
engine_ = "AnalyticDigitalAmericanEngine";
66-
return boost::make_shared<AnalyticDigitalAmericanEngine>(gbsp);
66+
return boost::make_shared<QuantExt::AnalyticDigitalAmericanEngine>(gbsp);
6767
} else if (type == "No-Touch") {
6868
engine_ = "AnalyticDigitalAmericanKOEngine";
69-
return boost::make_shared<AnalyticDigitalAmericanKOEngine>(gbsp);
69+
return boost::make_shared<QuantExt::AnalyticDigitalAmericanKOEngine>(gbsp);
7070
} else {
7171
QL_FAIL("Unknwon EQ touch option type: " << type);
7272
}

OREData/ored/portfolio/equityoption.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ void EquityOption::build(const boost::shared_ptr<EngineFactory>& engineFactory)
4747

4848
// check the equity currency
4949
underlyingCurrency_ =
50-
market->equityCurve(assetName_, engineFactory->configuration(MarketContext::pricing))->currency().code();
50+
market->equityCurve(assetName_, engineFactory->configuration(MarketContext::pricing))->currency();
5151
QL_REQUIRE(!underlyingCurrency_.empty(), "No equity currency in equityCurve for equity " << assetName_ << ".");
5252

5353
// Set the strike currency - if we have a minor currency, convert the strike
5454
if (!strikeCurrency_.empty())
5555
strike_.setCurrency(strikeCurrency_);
5656
else if (strike_.currency().empty()) {
5757
// If payoff currency and underlying currency are equivalent (and payoff currency could be a minor currency)
58-
if (ccy == parseCurrency(underlyingCurrency_)) {
58+
if (ccy == underlyingCurrency_) {
5959
TLOG("Setting strike currency to payoff currency " << ccy << " for trade " << id() << ".");
6060
strike_.setCurrency(ccy.code());
6161
} else {
@@ -67,15 +67,15 @@ void EquityOption::build(const boost::shared_ptr<EngineFactory>& engineFactory)
6767

6868
// Quanto payoff condition, i.e. currency_ != underlyingCurrency_, will be checked in VanillaOptionTrade::build()
6969
// Build the trade using the shared functionality in the base class.
70-
if (strike_.currency() != underlyingCurrency_) {
70+
if (strike_.currency() != underlyingCurrency_.code()) {
7171

7272
// We have a composite EQ Trade
7373

7474
Currency strikeCcy = parseCurrencyWithMinors(strikeCurrency_);
7575
QL_REQUIRE(ccy == strikeCcy, "Equity composite option requires pay ccy ("
7676
<< ccy.code() << ") to match strike ccy (" << strikeCcy.code()
7777
<< "), quanto composite options are not supported (underlying currency is "
78-
<< underlyingCurrency_ << ")");
78+
<< underlyingCurrency_.code() << ")");
7979

8080
Option::Type type = parseOptionType(option_.callPut());
8181
boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(type, strike_.value()));
@@ -133,7 +133,7 @@ void EquityOption::build(const boost::shared_ptr<EngineFactory>& engineFactory)
133133
// TODO cast and set pricing engine
134134

135135
auto compositeBuilder = boost::dynamic_pointer_cast<EquityEuropeanCompositeEngineBuilder>(builder);
136-
vanilla->setPricingEngine(compositeBuilder->engine(assetName_, parseCurrency(underlyingCurrency_),
136+
vanilla->setPricingEngine(compositeBuilder->engine(assetName_, underlyingCurrency_,
137137
parseCurrency(strike_.currency()), expiryDate_));
138138

139139
string configuration = Market::defaultConfiguration;

0 commit comments

Comments
 (0)