Skip to content

Commit e30d0bd

Browse files
NathanielVolfangojenkins
authored andcommitted
QPR-11947 -- Create separate node for schedule-based exercise dates
1 parent 3c38227 commit e30d0bd

3 files changed

Lines changed: 44 additions & 28 deletions

File tree

Docs/UserGuide/tradecomponents/optiondata.tex

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,14 @@ \subsubsection{Option Data}
2929
<ExerciseDate>2019-04-20</ExerciseDate>
3030
<ExerciseDate>2020-04-20</ExerciseDate>
3131
</ExerciseDates>
32-
<!-- ExerciseDates alternative ScheduleData format -->
33-
<ExerciseDates>
34-
<Dates>
35-
<Dates>
36-
<Date>2019-04-20</Date>
37-
<Date>2020-04-20</Date>
38-
</Dates>
39-
</Dates>
40-
</ExerciseDates>
32+
<!-- Alternative format for exercise dates using Schedule format -->
33+
<ExerciseSchedule>
34+
<Rules>
35+
<StartDate>2019-04-20</StartDate>
36+
<EndDate>2024-04-20</EndDate>
37+
<Tenor>3M</Tenor>
38+
</Rules>
39+
</ExerciseSchedule>
4140
<Premiums>
4241
<Premium>
4342
<Amount>100000</Amount>
@@ -203,13 +202,17 @@ \subsubsection{Option Data}
203202
204203
Allowable values: See Table \ref{tab:convention} Roll Convention.
205204
206-
\item ExerciseDates: This node can either contain child elements of type
207-
\lstinline!ExerciseDate!, or be specified in the same format as a Schedule
208-
(see Section \ref{ss:schedule_data}). Options of style \emph{European} or
205+
\item ExerciseDates: This node contains child elements of type
206+
\lstinline!ExerciseDate!. Options of style \emph{European} or
209207
\emph{American} require a single exercise date expressed by one
210208
single \lstinline!ExerciseDate! child element. \emph{Bermudan}
211209
style options must have two or more \lstinline!ExerciseDate! child
212-
elements.
210+
elements. One can alternatively use \lstinline!ExerciseSchedule! to
211+
specify the option exercise dates.
212+
213+
\item ExerciseSchedule [Optional]: This node can be provided instead of \lstinline!ExerciseDates! and
214+
should be specified in the same format as a Schedule (see Section \ref{ss:schedule_data}), e.g.\ for
215+
a list of Bermudan exercise dates.
213216
214217
\item Premiums [Optional]: Option premium amounts paid by the option buyer to the option seller.
215218

OREData/ored/portfolio/optiondata.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,15 @@ void OptionData::fromXML(XMLNode* node) {
5555
exerciseFeeSettlementConvention_ = XMLUtils::getChildValue(node, "ExerciseFeeSettlementConvention", false);
5656
exercisePrices_ = XMLUtils::getChildrenValuesAsDoubles(node, "ExercisePrices", "ExercisePrice", false);
5757

58-
if (XMLNode* n = XMLUtils::getChildNode(node, "ExerciseDates")) {
59-
if (XMLUtils::getChildNode(n, "ExerciseDate")) {
60-
// For backward compatibility
61-
exerciseDates_ = XMLUtils::getChildrenValues(node, "ExerciseDates", "ExerciseDate");
62-
} else {
63-
exerciseDatesSchedule_.fromXML(n);
64-
}
58+
XMLNode* exDatesNode = XMLUtils::getChildNode(node, "ExerciseDates");
59+
XMLNode* exScheduleNode = XMLUtils::getChildNode(node, "ExerciseSchedule");
60+
QL_REQUIRE(!(exDatesNode && exScheduleNode),
61+
"Cannot specify both ExerciseDates and ExerciseSchedule. Only one must be used.");
62+
if (exDatesNode) {
63+
exerciseDates_ = XMLUtils::getChildrenValues(node, "ExerciseDates", "ExerciseDate");
64+
}
65+
if (exScheduleNode) {
66+
exerciseDatesSchedule_.fromXML(exScheduleNode);
6567
}
6668

6769
automaticExercise_ = boost::none;
@@ -112,7 +114,14 @@ XMLNode* OptionData::toXML(XMLDocument& doc) {
112114
if (exerciseFeeSettlementConvention_ != "")
113115
XMLUtils::addChild(doc, node, "ExerciseFeeSettlementConvention", exerciseFeeSettlementConvention_);
114116
XMLUtils::addChildren(doc, node, "ExercisePrices", "ExercisePrice", exercisePrices_);
115-
XMLUtils::addChildren(doc, node, "ExerciseDates", "ExerciseDate", exerciseDates_);
117+
118+
if (exerciseDatesSchedule_.hasData()) {
119+
XMLNode* scheduleDataNode = exerciseDatesSchedule_.toXML(doc);
120+
XMLUtils::setNodeName(doc, scheduleDataNode, "ExerciseSchedule");
121+
XMLUtils::appendNode(node, scheduleDataNode);
122+
} else {
123+
XMLUtils::addChildren(doc, node, "ExerciseDates", "ExerciseDate", exerciseDates_);
124+
}
116125

117126
if (automaticExercise_)
118127
XMLUtils::addChild(doc, node, "AutomaticExercise", *automaticExercise_);

xsd/instruments.xsd

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,7 @@
317317
<xs:element type="xs:string" name="ExerciseFeeSettlementPeriod" minOccurs="0"/>
318318
<xs:element type="xs:string" name="ExerciseFeeSettlementCalendar" minOccurs="0"/>
319319
<xs:element type="xs:string" name="ExerciseFeeSettlementConvention" minOccurs="0"/>
320-
<xs:element name="ExerciseDates" minOccurs="0">
321-
<xs:complexType>
322-
<xs:sequence>
323-
<xs:element type="date" name="ExerciseDate" minOccurs="0" maxOccurs="unbounded"/>
324-
</xs:sequence>
325-
</xs:complexType>
326-
</xs:element>
320+
<xs:element ref="exerciseDatesGroup" minOccurs="0" />
327321
<xs:element type="bool" name="AutomaticExercise" minOccurs="0"/>
328322
<xs:element type="optionExerciseData" name="ExerciseData" minOccurs="0"/>
329323
<xs:element type="optionPaymentData" name="PaymentData" minOccurs="0"/>
@@ -416,6 +410,16 @@
416410
</xs:all>
417411
</xs:complexType>
418412

413+
<xs:element name="exerciseDatesGroup" abstract="true" />
414+
<xs:element name="ExerciseDates" substitutionGroup="exerciseDatesGroup">
415+
<xs:complexType>
416+
<xs:sequence>
417+
<xs:element type="date" name="ExerciseDate" minOccurs="0" maxOccurs="unbounded"/>
418+
</xs:sequence>
419+
</xs:complexType>
420+
</xs:element>
421+
<xs:element name="ExerciseSchedule" type="scheduleData" substitutionGroup="exerciseDatesGroup" />
422+
419423
<xs:element name="legDataType" abstract="true"/>
420424
<xs:element name="CashflowData" substitutionGroup="legDataType">
421425
<xs:complexType>

0 commit comments

Comments
 (0)