Skip to content

Commit

Permalink
Fix HSI future expiration function (#8534)
Browse files Browse the repository at this point in the history
* Fix HSI future expiration function

- Fix HSI futures expiration function. Adding unit tests reproducing
  issue

* Minor update to sample test data
  • Loading branch information
Martin-Molinero authored Jan 15, 2025
1 parent 1cb8fcf commit c35d6ee
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 11 deletions.
10 changes: 6 additions & 4 deletions Common/Securities/Future/FuturesExpiryFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -912,16 +912,18 @@ public static Func<DateTime, DateTime> FuturesExpiryFunction(Symbol symbol)
// 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
{Symbol.Create(Futures.Indices.HangSeng, SecurityType.Future, Market.HKFE), (time =>
{
// Short-dated Futures: Spot, next calendar month & next two calendar quarter months; and Long-dated Futures: the following 5 December months
// Short-dated Futures:
// Spot, next three calendar month & next three calendar quarter months; and
// Long-dated Futures:
// The three months of June and December plus the next three months of December

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

var holidays = FuturesExpiryUtilityFunctions.GetHolidays(Market.HKFE, Futures.Indices.HangSeng);
var lastBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(lastDay, -1, holidays);
var priorBusinessDay = lastBusinessDay.AddDays(-1);
var lastBusinessDay = FuturesExpiryUtilityFunctions.NthLastBusinessDay(time, 1, holidays);
var priorBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDays(lastBusinessDay, -1, holidays);

priorBusinessDay = FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(priorBusinessDay, -1, holidays);
return priorBusinessDay.Add(new TimeSpan(16, 0, 0));
})
},
Expand Down
Binary file modified Data/future/hkfe/daily/hsi_quote.zip
Binary file not shown.
Binary file modified Data/future/hkfe/daily/hsi_trade.zip
Binary file not shown.
Binary file modified Data/future/hkfe/hour/hsi_quote.zip
Binary file not shown.
Binary file modified Data/future/hkfe/hour/hsi_trade.zip
Binary file not shown.
27 changes: 20 additions & 7 deletions Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,29 @@ public void Init()
}
}

[Test]
public void HSIFutures()
// last day and previous are holidays
[TestCase("20250101", "20250127")]
// normal case
[TestCase("20250201", "20250227")]
[TestCase("20250301", "20250328")]
[TestCase("20250401", "20250429")]
[TestCase("20250501", "20250529")]
[TestCase("20250601", "20250627")]
[TestCase("20250701", "20250730")]
[TestCase("20250801", "20250828")]
[TestCase("20250901", "20250929")]
[TestCase("20251001", "20251030")]
[TestCase("20251101", "20251127")]
[TestCase("20251201", "20251230")]
public void HSIFutures(string input, string expectedStr)
{
var date = Time.ParseDate(input);
var expected = Time.ParseDate(expectedStr);

var canonical = Symbol.Create("HSI", SecurityType.Future, Market.HKFE);
var expiration = FuturesExpiryFunctions.FuturesExpiryDictionary[canonical];

// last day and previous are holidays
Assert.AreEqual(new DateTime(2025, 1, 27, 16, 0, 0), expiration(new DateTime(2025, 1, 1)));
// normal case
Assert.AreEqual(new DateTime(2025, 2, 27, 16, 0, 0), expiration(new DateTime(2025, 2, 1)));
var result = expiration(date);
Assert.AreEqual(expected, result.Date);
}

[Test]
Expand Down

0 comments on commit c35d6ee

Please sign in to comment.