106 lines
3.5 KiB
Markdown
106 lines
3.5 KiB
Markdown
# TASK-05: Add CME Holiday Awareness to SessionManager
|
|
|
|
**File:** `src/NT8.Core/MarketData/SessionManager.cs`
|
|
**Priority:** MEDIUM
|
|
**No dependencies**
|
|
**Estimated time:** 30 min
|
|
|
|
---
|
|
|
|
## Background
|
|
|
|
`IsRegularTradingHours()` currently only checks session time windows. It has no awareness of CME holidays, so the system would attempt to trade on Christmas, Thanksgiving, etc. when markets are closed.
|
|
|
|
---
|
|
|
|
## Exact Changes Required
|
|
|
|
### 1. Add a static holiday set as a private field on `SessionManager`
|
|
|
|
Add this inside the class (near the other private fields):
|
|
|
|
```csharp
|
|
// CME US Futures holidays — markets closed all day on these dates.
|
|
// Update annually. Dates are in the format new DateTime(year, month, day).
|
|
private static readonly System.Collections.Generic.HashSet<DateTime> _cmeHolidays =
|
|
new System.Collections.Generic.HashSet<DateTime>
|
|
{
|
|
// 2025 holidays
|
|
new DateTime(2025, 1, 1), // New Year's Day
|
|
new DateTime(2025, 1, 20), // Martin Luther King Jr. Day
|
|
new DateTime(2025, 2, 17), // Presidents' Day
|
|
new DateTime(2025, 4, 18), // Good Friday
|
|
new DateTime(2025, 5, 26), // Memorial Day
|
|
new DateTime(2025, 6, 19), // Juneteenth
|
|
new DateTime(2025, 7, 4), // Independence Day
|
|
new DateTime(2025, 9, 1), // Labor Day
|
|
new DateTime(2025, 11, 27), // Thanksgiving
|
|
new DateTime(2025, 12, 25), // Christmas Day
|
|
|
|
// 2026 holidays
|
|
new DateTime(2026, 1, 1), // New Year's Day
|
|
new DateTime(2026, 1, 19), // Martin Luther King Jr. Day
|
|
new DateTime(2026, 2, 16), // Presidents' Day
|
|
new DateTime(2026, 4, 3), // Good Friday
|
|
new DateTime(2026, 5, 25), // Memorial Day
|
|
new DateTime(2026, 6, 19), // Juneteenth
|
|
new DateTime(2026, 7, 4), // Independence Day (observed Mon 7/3 if falls on Sat — keep both just in case)
|
|
new DateTime(2026, 9, 7), // Labor Day
|
|
new DateTime(2026, 11, 26), // Thanksgiving
|
|
new DateTime(2026, 12, 25), // Christmas Day
|
|
};
|
|
```
|
|
|
|
### 2. Add a helper method
|
|
|
|
```csharp
|
|
/// <summary>
|
|
/// Returns true if the given UTC date is a CME holiday (market closed all day).
|
|
/// </summary>
|
|
private static bool IsCmeHoliday(DateTime utcTime)
|
|
{
|
|
// Convert to ET for holiday date comparison
|
|
try
|
|
{
|
|
var estTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime,
|
|
TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"));
|
|
return _cmeHolidays.Contains(estTime.Date);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Update `IsRegularTradingHours()` to check holidays first
|
|
|
|
The existing method body is:
|
|
```csharp
|
|
var sessionInfo = GetCurrentSession(symbol, time);
|
|
return sessionInfo.IsRegularHours;
|
|
```
|
|
|
|
Replace with:
|
|
```csharp
|
|
// Markets are fully closed on CME holidays
|
|
if (IsCmeHoliday(time))
|
|
{
|
|
_logger.LogInformation("Holiday detected for {0} on {1} — market closed.", symbol, time.Date);
|
|
return false;
|
|
}
|
|
|
|
var sessionInfo = GetCurrentSession(symbol, time);
|
|
return sessionInfo.IsRegularHours;
|
|
```
|
|
|
|
---
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] `IsRegularTradingHours("ES", new DateTime(2025, 12, 25, 14, 0, 0, DateTimeKind.Utc))` returns `false`
|
|
- [ ] `IsRegularTradingHours("ES", new DateTime(2025, 12, 26, 14, 0, 0, DateTimeKind.Utc))` returns `true` (normal day)
|
|
- [ ] `IsRegularTradingHours("ES", new DateTime(2025, 11, 27, 14, 0, 0, DateTimeKind.Utc))` returns `false` (Thanksgiving)
|
|
- [ ] `verify-build.bat` passes
|
|
- [ ] All existing tests pass
|