# 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 _cmeHolidays = new System.Collections.Generic.HashSet { // 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 /// /// Returns true if the given UTC date is a CME holiday (market closed all day). /// 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