Skip to content

Commit ca06e24

Browse files
author
jenkins
committed
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "1dc751f4cb" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "e3e95e17a5" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo" commit: "110b9eb"
2 parents 35d7a4c + e3e95e1 commit ca06e24

5 files changed

Lines changed: 38 additions & 6 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

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 {

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)