1919#include < ored/portfolio/fxkikobarrieroption.hpp>
2020#include < ored/portfolio/genericbarrieroption.hpp>
2121#include < ored/utilities/parsers.hpp>
22+ #include < ored/utilities/optionpaymentdates.hpp>
2223namespace ore {
2324namespace data {
2425
@@ -36,6 +37,28 @@ struct GenericBarrierOptionData {
3637 std::string kikoType;
3738};
3839
40+ QuantLib::Date calculateOptionPaymentDate (const std::string tradeId, const std::string tradeType,
41+ const QuantLib::Date& expiryDate,
42+ const QuantLib::ext::optional<OptionPaymentData>& opd) {
43+ Date paymentDate = expiryDate;
44+ if (opd) {
45+ if (opd->rulesBased ()) {
46+ const Calendar& cal = opd->calendar ();
47+ QL_REQUIRE (cal != Calendar (), " Need a non-empty calendar for rules based payment date." );
48+ paymentDate = cal.advance (expiryDate, opd->lag (), Days, opd->convention ());
49+ } else {
50+ if (opd->dates ().size () > 1 )
51+ ore::data::StructuredTradeWarningMessage (tradeId, tradeType, " Trade build" ,
52+ " Found more than 1 payment date. The first one will be used." )
53+ .log ();
54+ paymentDate = opd->dates ().front ();
55+ }
56+ QL_REQUIRE (paymentDate >= expiryDate, " Payment date must be greater than or equal to expiry date." );
57+ }
58+ return paymentDate;
59+ }
60+
61+
3962GenericBarrierOptionData parseFxBarrierOption (const ore::data::FxOptionWithBarrier* fxBarrierOption) {
4063 QL_REQUIRE (fxBarrierOption != nullptr , " FxBarrierOptionScriptedEngineBuilder: internal error, could not "
4164 " cast to ore::data::FxOptionWithBarrier. Contact dev." );
@@ -79,20 +102,8 @@ GenericBarrierOptionData parseFxBarrierOption(const ore::data::FxOptionWithBarri
79102 data.transatlanticBarrier = BarrierData ();
80103 data.payCurrency = fxBarrierOption->soldCurrency ();
81104 Date expiryDate = parseDate (exerciseDate);
82- Date paymentDate = expiryDate;
83- const QuantLib::ext::optional<OptionPaymentData>& opd = data.optionData .paymentData ();
84- if (opd) {
85- if (opd->rulesBased ()) {
86- const Calendar& cal = opd->calendar ();
87- QL_REQUIRE (cal != Calendar (), " Need a non-empty calendar for rules based payment date." );
88- paymentDate = cal.advance (expiryDate, opd->lag (), Days, opd->convention ());
89- } else {
90- const vector<Date>& dates = opd->dates ();
91- QL_REQUIRE (dates.size () == 1 , " Need exactly one payment date for cash settled European option." );
92- paymentDate = dates[0 ];
93- }
94- QL_REQUIRE (paymentDate >= expiryDate, " Payment date must be greater than or equal to expiry date." );
95- }
105+ Date paymentDate = calculateOptionPaymentDate (fxBarrierOption->id (), fxBarrierOption->tradeType (), expiryDate,
106+ data.optionData .paymentData ());
96107 data.settlementDate = to_string (paymentDate);
97108 data.quantity = to_string (fxBarrierOption->boughtAmount ());
98109 data.strike = to_string (fxBarrierOption->strike ());
@@ -125,20 +136,8 @@ GenericBarrierOptionData parseFxKIKOBarrierOptionData(const ore::data::FxKIKOBar
125136 data.transatlanticBarrier = BarrierData ();
126137 data.payCurrency = fxKiKoBarrierOption->soldCurrency ();
127138 Date expiryDate = parseDate (exerciseDate);
128- Date paymentDate = expiryDate;
129- const QuantLib::ext::optional<OptionPaymentData>& opd = data.optionData .paymentData ();
130- if (opd) {
131- if (opd->rulesBased ()) {
132- const Calendar& cal = opd->calendar ();
133- QL_REQUIRE (cal != Calendar (), " Need a non-empty calendar for rules based payment date." );
134- paymentDate = cal.advance (expiryDate, opd->lag (), Days, opd->convention ());
135- } else {
136- const vector<Date>& dates = opd->dates ();
137- QL_REQUIRE (dates.size () == 1 , " Need exactly one payment date for cash settled European option." );
138- paymentDate = dates[0 ];
139- }
140- QL_REQUIRE (paymentDate >= expiryDate, " Payment date must be greater than or equal to expiry date." );
141- }
139+ Date paymentDate = calculateOptionPaymentDate (fxKiKoBarrierOption->id (), fxKiKoBarrierOption->tradeType (), expiryDate,
140+ data.optionData .paymentData ());
142141 data.settlementDate = to_string (paymentDate);
143142 data.quantity = to_string (fxKiKoBarrierOption->boughtAmount ());
144143 data.strike = to_string (fxKiKoBarrierOption->strike ());
0 commit comments