Skip to content

Commit 63e73dd

Browse files
author
jenkins
committed
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "e8a6202652" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "ca06e24764" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo" commit: "110b9eb"
2 parents d4d6a2a + ca06e24 commit 63e73dd

10 files changed

Lines changed: 794 additions & 802 deletions

File tree

Docs/UserGuide/tradecomponents/underlying.tex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ \subsubsection{Underlying}
106106
<FutureMonthOffset>0</FutureMonthOffset>
107107
<DeliveryRollDays>0</DeliveryRollDays>
108108
<DeliveryRollCalendar>TARGET</DeliveryRollCalendar>
109+
<FutureContractMonth>Nov2023</FutureContractMonth>
109110
</Underlying>
110111
\end{minted}
111112
\caption{Commodity Underlying}
@@ -242,6 +243,14 @@ \subsubsection{Underlying}
242243

243244
Allowable values: See Table \ref{tab:calendar}. Defaults to the null calendar if left blank or omitted, and \lstinline!Type!: is \emph{Commodity}.
244245

246+
\item \lstinline!FutureContractMonth! [Optional]:
247+
Only valid when \lstinline!Type! is \emph{Commodity}, \lstinline!PriceType! is FutureSettlement and there is no \lstinline!FutureExpiryDate! node. It specifies the underlying future contract month in the format \emph{MonYYYY}, for example Nov2023.
248+
249+
\item \lstinline!FutureExpiryDate! [Optional]:
250+
Only valid when \lstinline!Type! is \emph{Commodity}, \lstinline!PriceType! is FutureSettlement and there is no \lstinline!FutureContractMonth! node. This gives the expiration date of the underlying commodity future contract.
251+
252+
If the field \lstinline!FutureExpiryDate! and \lstinline!FutureContractMonth! are omitted, the expiration date of the underlying commodity future contract is set to the prompt future, adjusted for any \lstinline!FutureMonthOffset!.
253+
245254
\item \lstinline!Interpolation! [Optional]:
246255
Only valid when \lstinline!Type! is \emph{Inflation}. The index observation interpolation between fixings.
247256

Examples/Example_40/ExpectedOutput/parsensitivity.csv

Lines changed: 372 additions & 395 deletions
Large diffs are not rendered by default.

Examples/Example_50/ExpectedOutput/parconversion_sensitivity.csv

Lines changed: 375 additions & 398 deletions
Large diffs are not rendered by default.

OREAnalytics/orea/engine/parsensitivityanalysis.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include <ql/pricingengines/capfloor/blackcapfloorengine.hpp>
6464
#include <ql/pricingengines/credit/midpointcdsengine.hpp>
6565
#include <ql/pricingengines/swap/discountingswapengine.hpp>
66+
#include <ql/quotes/derivedquote.hpp>
6667
#include <ql/termstructures/yield/flatforward.hpp>
6768
#include <ql/termstructures/yield/oisratehelper.hpp>
6869
#include <qle/instruments/fixedbmaswap.hpp>
@@ -1701,6 +1702,10 @@ ParSensitivityAnalysis::makeCrossCcyBasisSwap(const boost::shared_ptr<Market>& m
17011702
boost::shared_ptr<FxIndex> fxIndex =
17021703
boost::make_shared<FxIndex>("dummy", conv->settlementDays(), currency, baseCurrency, conv->settlementCalendar(),
17031704
fxSpot, discountCurve, baseDiscountCurve);
1705+
auto m = [](Real x) { return 1.0 / x; };
1706+
boost::shared_ptr<FxIndex> reversedFxIndex = boost::make_shared<FxIndex>(
1707+
"dummyRev", conv->settlementDays(), baseCurrency, currency, conv->settlementCalendar(),
1708+
Handle<Quote>(boost::make_shared<DerivedQuote<decltype(m)>>(fxSpot, m)), baseDiscountCurve, discountCurve);
17041709

17051710
// LOG("Make Cross Ccy Swap for base ccy " << baseCcy << " currency " << ccy);
17061711
// Set up first leg as spread leg, second as flat leg
@@ -1714,7 +1719,7 @@ ParSensitivityAnalysis::makeCrossCcyBasisSwap(const boost::shared_ptr<Market>& m
17141719
DLOG("create resettable xccy par instrument (1), convention " << conv->id());
17151720
helper = boost::make_shared<CrossCcyBasisMtMResetSwap>(
17161721
baseNotional, baseCurrency, baseSchedule, *baseIndex, 0.0, // spread index leg => use fairForeignSpread
1717-
currency, schedule, *index, 0.0, fxIndex, true, // resettable flat index leg
1722+
currency, schedule, *index, 0.0, reversedFxIndex, true, // resettable flat index leg
17181723
conv->paymentLag(), conv->flatPaymentLag(),
17191724
conv->includeSpread(), conv->lookback(), conv->fixingDays(), conv->rateCutoff(), conv->isAveraged(),
17201725
conv->flatIncludeSpread(), conv->flatLookback(), conv->flatFixingDays(), conv->flatRateCutoff(), conv->flatIsAveraged(),
@@ -1758,7 +1763,7 @@ ParSensitivityAnalysis::makeCrossCcyBasisSwap(const boost::shared_ptr<Market>& m
17581763
// second leg is resettable, so the second leg is the non-base non-flat spread leg
17591764
helper = boost::make_shared<CrossCcyBasisMtMResetSwap>(
17601765
baseNotional, baseCurrency, baseSchedule, *baseIndex, 0.0, // flat index leg
1761-
currency, schedule, *index, 0.0, fxIndex, true, // resettable spread index leg => use fairDomesticSpread
1766+
currency, schedule, *index, 0.0, reversedFxIndex, true, // resettable spread index leg => use fairDomesticSpread
17621767
conv->flatPaymentLag(), conv->paymentLag(),
17631768
conv->flatIncludeSpread(), conv->flatLookback(), conv->flatFixingDays(), conv->flatRateCutoff(), conv->flatIsAveraged(),
17641769
conv->includeSpread(), conv->lookback(), conv->fixingDays(), conv->rateCutoff(), conv->isAveraged(),

OREData/ored/portfolio/commodityposition.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,25 @@ void CommodityPosition::build(const boost::shared_ptr<ore::data::EngineFactory>&
6464
auto convention = boost::dynamic_pointer_cast<CommodityFutureConvention>(p.second);
6565
ConventionsBasedFutureExpiry feCalc(*convention);
6666
Date expiry = Settings::instance().evaluationDate();
67+
Size nOffset = u.futureMonthOffset() == Null<Size>() ? 0 : u.futureMonthOffset();
6768
if (u.deliveryRollDays() != Null<Size>()) {
68-
auto cal = u.deliveryRollCalendar().empty() ? convention->calendar() : parseCalendar(u.deliveryRollCalendar());
69+
auto cal =
70+
u.deliveryRollCalendar().empty() ? convention->calendar() : parseCalendar(u.deliveryRollCalendar());
6971
expiry = cal.advance(expiry, u.deliveryRollDays() * Days, convention->businessDayConvention());
7072
}
71-
72-
Size nOffset = u.futureMonthOffset() == Null<Size>() ? 0 : u.futureMonthOffset();
73-
7473
expiry = feCalc.nextExpiry(true, expiry, nOffset);
75-
74+
if (!u.futureContractMonth().empty()) {
75+
QL_REQUIRE(u.futureContractMonth().size() == 7,
76+
"FutureContractMonth has invalid format, please use MonYYYY, where 'Mon' is a 3 letter "
77+
"month abbreviation.");
78+
auto month = parseMonth(u.futureContractMonth().substr(0, 3));
79+
auto year = parseInteger(u.futureContractMonth().substr(3, 4));
80+
Date contractDate(1, month, year);
81+
expiry = feCalc.expiryDate(contractDate, nOffset, false);
82+
} else if (!u.futureExpiryDate().empty()) {
83+
expiry = parseDate(u.futureExpiryDate());
84+
expiry = feCalc.nextExpiry(true, expiry, nOffset, false);
85+
}
7686
index = index->clone(expiry, pts);
7787
}
7888
indices_.push_back(index);

OREData/ored/portfolio/underlying.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ void CommodityUnderlying::fromXML(XMLNode* node) {
133133
deliveryRollDays_ = Null<Size>();
134134
deliveryRollCalendar_ = XMLUtils::getChildValue(node, "DeliveryRollCalendar", false);
135135
isBasic_ = false;
136+
futureExpiryDate_ = XMLUtils::getChildValue(node, "FutureExpiryDate", false);
137+
futureContractMonth_ = XMLUtils::getChildValue(node, "FutureContractMonth", false);
138+
QL_REQUIRE(futureExpiryDate_.empty() || futureContractMonth_.empty(),
139+
"Only futureExpiryDate or futureContractMonth are allowed not both");
136140
} else {
137141
QL_FAIL("Need either a Name or Underlying node for CommodityUnderlying.");
138142
}
@@ -153,6 +157,10 @@ XMLNode* CommodityUnderlying::toXML(XMLDocument& doc) {
153157
XMLUtils::addChild(doc, node, "DeliveryRollDays", (int)deliveryRollDays_);
154158
if (!deliveryRollCalendar_.empty())
155159
XMLUtils::addChild(doc, node, "DeliveryRollCalendar", deliveryRollCalendar_);
160+
if (!futureExpiryDate_.empty())
161+
XMLUtils::addChild(doc, node, "FutureExpiryDate", futureExpiryDate_);
162+
if (!futureContractMonth_.empty())
163+
XMLUtils::addChild(doc, node, "FutureContractMonth", futureContractMonth_);
156164
}
157165
return node;
158166
}

OREData/ored/portfolio/underlying.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ class CommodityUnderlying : public Underlying {
140140
QuantLib::Size futureMonthOffset() const { return futureMonthOffset_; }
141141
QuantLib::Size deliveryRollDays() const { return deliveryRollDays_; }
142142
const std::string& deliveryRollCalendar() const { return deliveryRollCalendar_; }
143-
143+
const std::string& futureContractMonth() const { return futureContractMonth_; }
144+
const std::string& futureExpiryDate() const { return futureExpiryDate_; }
144145
//! \name Serialisation
145146
//@{
146147
void fromXML(XMLNode* node) override;
@@ -152,6 +153,8 @@ class CommodityUnderlying : public Underlying {
152153
QuantLib::Size futureMonthOffset_ = QuantLib::Null<QuantLib::Size>();
153154
QuantLib::Size deliveryRollDays_ = QuantLib::Null<QuantLib::Size>();
154155
std::string deliveryRollCalendar_;
156+
std::string futureContractMonth_;
157+
std::string futureExpiryDate_;
155158
};
156159

157160
class FXUnderlying : public Underlying {

QuantExt/qle/math/computeenvironment.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#pragma once
2424

2525
#include <ql/patterns/singleton.hpp>
26-
26+
#include <boost/thread/shared_mutex.hpp>
2727
#include <cstdint>
2828
#include <set>
2929

QuantExt/qle/math/randomvariable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <boost/accumulators/statistics/variance.hpp>
3131

3232
#include <iostream>
33+
#include <map>
3334

3435
// if defined, RandomVariableStats are updated (this might impact perfomance!), default is undefined
3536
//#define ENABLE_RANDOMVARIABLE_STATS

xsd/instruments.xsd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,8 @@
17971797
<xs:element type="xs:nonNegativeInteger" name="FutureMonthOffset" minOccurs="0"/>
17981798
<xs:element type="xs:nonNegativeInteger" name="DeliveryRollDays" minOccurs="0"/>
17991799
<xs:element type="xs:string" name="DeliveryRollCalendar" minOccurs="0"/>
1800+
<xs:element type="xs:string" name="FutureExpiryDate" minOccurs="0"/>
1801+
<xs:element type="xs:string" name="FutureContractMonth" minOccurs="0"/>
18001802
<xs:element type="xs:string" name="Interpolation" minOccurs="0"/>
18011803
<xs:element type="xs:float" name="BidAskAdjustment" minOccurs="0"/>
18021804
</xs:all>

0 commit comments

Comments
 (0)