@@ -65,22 +65,24 @@ void CommodityPosition::build(const boost::shared_ptr<ore::data::EngineFactory>&
6565 ConventionsBasedFutureExpiry feCalc (*convention);
6666 Date expiry = Settings::instance ().evaluationDate ();
6767 Size nOffset = u.futureMonthOffset () == Null<Size>() ? 0 : u.futureMonthOffset ();
68- if (u.futureExpiryDate ().empty ()) {
68+ if (!u.futureContractMonth ().empty ()) {
69+ QL_REQUIRE (u.futureContractMonth ().size () == 7 ,
70+ " FutureContractMonth has invalid format, please use Mon-YYYY, where 'Mon' is a 3 letter "
71+ " month abbreviation." );
72+ auto month = parseMonth (u.futureContractMonth ().substr (0 , 3 ));
73+ auto year = parseInteger (u.futureContractMonth ().substr (3 , 4 ));
74+ Date contractDate (1 , month, year);
75+ expiry = feCalc.expiryDate (contractDate, nOffset, false );
76+ } else if (!u.futureExpiryDate ().empty ()) {
77+ expiry = parseDate (u.futureExpiryDate ());
78+ expiry = feCalc.nextExpiry (true ,expiry, nOffset, false );
79+ } else {
6980 if (u.deliveryRollDays () != Null<Size>()) {
70- auto cal = u.deliveryRollCalendar ().empty () ? convention->calendar () : parseCalendar (u.deliveryRollCalendar ());
81+ auto cal = u.deliveryRollCalendar ().empty () ? convention->calendar ()
82+ : parseCalendar (u.deliveryRollCalendar ());
7183 expiry = cal.advance (expiry, u.deliveryRollDays () * Days, convention->businessDayConvention ());
7284 }
73-
7485 expiry = feCalc.nextExpiry (true , expiry, nOffset);
75- } else if (u.futureExpiryDate ().size () == 7 ) {
76- // parse MONTHYYYY (e.g. NOV2023) format into date
77- auto month = parseMonth (u.futureExpiryDate ().substr (0 , 3 ));
78- auto year = parseInteger (u.futureExpiryDate ().substr (3 , 4 ));
79- Date contractDate (1 , month, year);
80- expiry = feCalc.expiryDate (contractDate, nOffset, false );
81- } else {
82- Date contractDate = parseDate (u.futureExpiryDate ());
83- expiry = feCalc.expiryDate (contractDate, nOffset, false );
8486 }
8587 index = index->clone (expiry, pts);
8688 }
0 commit comments