Skip to content

Commit 5cc8347

Browse files
Fix HSI future expiration function
- Fix HSI futures expiration function. Adding unit tests reproducing issue
1 parent 1cb8fcf commit 5cc8347

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

Common/Securities/Future/FuturesExpiryFunctions.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -912,16 +912,18 @@ public static Func<DateTime, DateTime> FuturesExpiryFunction(Symbol symbol)
912912
// HSI Index Futures:https://www.hkex.com.hk/Products/Listed-Derivatives/Equity-Index/Hang-Seng-Index-(HSI)/Hang-Seng-Index-Futures?sc_lang=en#&product=HSI
913913
{Symbol.Create(Futures.Indices.HangSeng, SecurityType.Future, Market.HKFE), (time =>
914914
{
915-
// Short-dated Futures: Spot, next calendar month & next two calendar quarter months; and Long-dated Futures: the following 5 December months
915+
// Short-dated Futures:
916+
// Spot, next three calendar month & next three calendar quarter months; and
917+
// Long-dated Futures:
918+
// The three months of June and December plus the next three months of December
916919

917920
// The Business Day immediately preceding the last Business Day of the Contract Month
918921
var lastDay = new DateTime(time.Year, time.Month, DateTime.DaysInMonth(time.Year, time.Month));
919922

920923
var holidays = FuturesExpiryUtilityFunctions.GetHolidays(Market.HKFE, Futures.Indices.HangSeng);
921-
var lastBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(lastDay, -1, holidays);
922-
var priorBusinessDay = lastBusinessDay.AddDays(-1);
924+
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
925+
var priorBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDays(lastBusinessDay, -1, holidays);
923926

924-
priorBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(priorBusinessDay, -1, holidays);
925927
return priorBusinessDay.Add(new TimeSpan(16, 0, 0));
926928
})
927929
},

Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,29 @@ public void Init()
6969
}
7070
}
7171

72-
[Test]
73-
public void HSIFutures()
72+
// last day and previous are holidays
73+
[TestCase("20250101", "20250127")]
74+
// normal case
75+
[TestCase("20250201", "20250227")]
76+
[TestCase("20250301", "20250328")]
77+
[TestCase("20250401", "20250429")]
78+
[TestCase("20250501", "20250529")]
79+
[TestCase("20250601", "20250627")]
80+
[TestCase("20250701", "20250730")]
81+
[TestCase("20250801", "20250828")]
82+
[TestCase("20250901", "20250929")]
83+
[TestCase("20251001", "20251030")]
84+
[TestCase("20251101", "20251127")]
85+
[TestCase("20251201", "20251230")]
86+
public void HSIFutures(string input, string expectedStr)
7487
{
88+
var date = Time.ParseDate(input);
89+
var expected = Time.ParseDate(expectedStr);
90+
7591
var canonical = Symbol.Create("HSI", SecurityType.Future, Market.HKFE);
7692
var expiration = FuturesExpiryFunctions.FuturesExpiryDictionary[canonical];
77-
78-
// last day and previous are holidays
79-
Assert.AreEqual(new DateTime(2025, 1, 27, 16, 0, 0), expiration(new DateTime(2025, 1, 1)));
80-
// normal case
81-
Assert.AreEqual(new DateTime(2025, 2, 27, 16, 0, 0), expiration(new DateTime(2025, 2, 1)));
93+
var result = expiration(date);
94+
Assert.AreEqual(expected, result.Date);
8295
}
8396

8497
[Test]

0 commit comments

Comments
 (0)