From 322e3892793ab119e5c5168b25eec6e82bbd04e9 Mon Sep 17 00:00:00 2001 From: Sasha Date: Fri, 18 Sep 2026 14:43:24 -0300 Subject: [PATCH 1/3] Add missing CME-family futures early closes for 2023-2025 shortened sessions Add the early closes, and the same-evening late opens, that the per-symbol CME, CBOT, NYMEX and COMEX entries lack for 3 Jul 2023, 3 Jul 2024, 29 Nov 2024 and 9 Jan 2025, at the times CME published for each product group. Additive only: 80 early closes and 25 late opens across 52 entries, inserted in chronological order. Cover the change with a MarketHoursDatabaseTests case that resolves one entry per product group on each date. --- Data/market-hours/market-hours-database.json | 105 ++++++++++++++++++ .../Securities/MarketHoursDatabaseTests.cs | 38 +++++++ 2 files changed, 143 insertions(+) diff --git a/Data/market-hours/market-hours-database.json b/Data/market-hours/market-hours-database.json index 9cdf3bdf59e3..9f09b89dee6b 100644 --- a/Data/market-hours/market-hours-database.json +++ b/Data/market-hours/market-hours-database.json @@ -2697,6 +2697,7 @@ "11/22/2023": "16:00:00", "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", + "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", "1/19/2025": "16:00:00", @@ -3207,6 +3208,7 @@ "11/22/2023": "16:00:00", "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", + "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", "1/19/2025": "16:00:00", @@ -3858,6 +3860,7 @@ "11/22/2023": "16:00:00", "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", + "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", "1/19/2025": "16:00:00", @@ -4214,6 +4217,7 @@ "12/24/2027" ], "earlyCloses": { + "11/29/2024": "12:05:00", "12/31/2025": "16:00:00", "1/18/2026": "16:00:00", "2/15/2026": "16:00:00", @@ -4368,6 +4372,7 @@ "12/24/2027" ], "earlyCloses": { + "11/29/2024": "12:05:00", "12/31/2025": "16:00:00", "1/18/2026": "16:00:00", "2/15/2026": "16:00:00", @@ -4522,6 +4527,7 @@ "12/24/2027" ], "earlyCloses": { + "11/29/2024": "12:05:00", "12/31/2025": "16:00:00", "1/18/2026": "16:00:00", "2/15/2026": "16:00:00", @@ -4770,6 +4776,7 @@ "11/22/2023": "16:00:00", "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", + "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", "1/19/2025": "16:00:00", @@ -5494,6 +5501,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -6088,6 +6096,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -6682,6 +6691,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -7276,6 +7286,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -7870,6 +7881,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -8464,6 +8476,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -9058,6 +9071,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -11394,6 +11408,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -39491,6 +39506,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:45:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -40376,6 +40392,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -42032,6 +42049,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -51545,6 +51563,7 @@ "4/7/2023": "08:15:00", "5/29/2023": "12:00:00", "6/19/2023": "12:00:00", + "7/3/2023": "12:15:00", "7/4/2023": "12:00:00", "9/4/2023": "12:00:00", "11/23/2023": "12:00:00", @@ -51553,11 +51572,14 @@ "2/19/2024": "12:00:00", "5/27/2024": "12:00:00", "6/19/2024": "12:00:00", + "7/3/2024": "12:15:00", "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "08:30:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -51679,6 +51701,7 @@ "2/20/2023": "17:00:00", "5/29/2023": "17:00:00", "6/19/2023": "17:00:00", + "7/3/2023": "17:00:00", "7/4/2023": "17:00:00", "9/4/2023": "17:00:00", "11/23/2023": "17:00:00", @@ -51688,11 +51711,13 @@ "2/19/2024": "17:00:00", "5/27/2024": "17:00:00", "6/19/2024": "17:00:00", + "7/3/2024": "17:00:00", "7/4/2024": "17:00:00", "9/2/2024": "17:00:00", "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -53763,6 +53788,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:45:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -56738,6 +56764,7 @@ "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "12:00:00", @@ -57333,6 +57360,7 @@ "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "12:00:00", @@ -62652,6 +62680,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -63707,6 +63736,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -68521,6 +68551,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -69095,6 +69126,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -69697,6 +69729,7 @@ "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "12:00:00", @@ -70292,6 +70325,7 @@ "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "12:00:00", @@ -70887,6 +70921,7 @@ "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "12:00:00", @@ -71482,6 +71517,7 @@ "7/4/2024": "12:00:00", "9/2/2024": "12:00:00", "11/28/2024": "12:00:00", + "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", "1/20/2025": "12:00:00", @@ -72287,6 +72323,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -72295,11 +72332,14 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -72421,6 +72461,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -72430,11 +72471,13 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -74551,6 +74594,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -74559,11 +74603,14 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -74685,6 +74732,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -74694,11 +74742,13 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -75117,6 +75167,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -75125,11 +75176,14 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -75251,6 +75305,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -75260,11 +75315,13 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -75683,6 +75740,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -75691,9 +75749,11 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", "1/20/2025": "13:00:00", @@ -75818,6 +75878,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -75827,6 +75888,7 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", @@ -77629,6 +77691,7 @@ "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", "1/20/2025": "13:00:00", @@ -78195,6 +78258,7 @@ "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", "1/20/2025": "13:00:00", @@ -78771,6 +78835,8 @@ "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", "11/27/2024": "16:00:00", + "11/29/2024": "12:05:00", + "1/9/2025": "12:15:00", "11/28/2025": "12:05:00", "12/24/2025": "12:15:00", "11/27/2026": "12:05:00", @@ -79070,6 +79136,8 @@ "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", "11/27/2024": "16:00:00", + "11/29/2024": "12:05:00", + "1/9/2025": "12:15:00", "11/28/2025": "12:05:00", "12/24/2025": "12:15:00", "11/27/2026": "12:05:00", @@ -79369,6 +79437,8 @@ "11/24/2023": "12:05:00", "3/28/2024": "16:00:00", "11/27/2024": "16:00:00", + "11/29/2024": "12:05:00", + "1/9/2025": "12:15:00", "11/28/2025": "12:05:00", "12/24/2025": "12:15:00", "11/27/2026": "12:05:00", @@ -79532,6 +79602,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -79887,6 +79958,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -81725,6 +81797,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -82080,6 +82153,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -109457,6 +109531,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -109465,11 +109540,14 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -109591,6 +109669,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -109600,11 +109679,13 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -110023,6 +110104,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -110031,11 +110113,14 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -110157,6 +110242,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -110166,11 +110252,13 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -111183,6 +111271,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -111191,11 +111280,14 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -111317,6 +111409,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -111326,11 +111419,13 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -111749,6 +111844,7 @@ "4/7/2023": "09:15:00", "5/29/2023": "13:00:00", "6/19/2023": "13:00:00", + "7/3/2023": "13:15:00", "7/4/2023": "13:00:00", "9/4/2023": "13:00:00", "11/23/2023": "13:00:00", @@ -111757,9 +111853,11 @@ "2/19/2024": "13:00:00", "5/27/2024": "13:00:00", "6/19/2024": "13:00:00", + "7/3/2024": "13:15:00", "7/4/2024": "13:00:00", "9/2/2024": "13:00:00", "11/28/2024": "13:00:00", + "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", "1/20/2025": "13:00:00", @@ -111884,6 +111982,7 @@ "2/20/2023": "18:00:00", "5/29/2023": "18:00:00", "6/19/2023": "18:00:00", + "7/3/2023": "18:00:00", "7/4/2023": "18:00:00", "9/4/2023": "18:00:00", "11/23/2023": "18:00:00", @@ -111893,6 +111992,7 @@ "2/19/2024": "18:00:00", "5/27/2024": "18:00:00", "6/19/2024": "18:00:00", + "7/3/2024": "18:00:00", "7/4/2024": "18:00:00", "9/2/2024": "18:00:00", "11/28/2024": "18:00:00", @@ -112329,6 +112429,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -113361,6 +113462,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:45:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -113692,6 +113794,7 @@ "7/4/2024": "16:00:00", "9/2/2024": "16:00:00", "11/28/2024": "16:00:00", + "11/29/2024": "13:45:00", "12/24/2024": "12:45:00", "12/31/2024": "16:00:00", "1/20/2025": "16:00:00", @@ -114128,6 +114231,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", @@ -115296,6 +115400,7 @@ "7/4/2024": "14:30:00", "9/2/2024": "14:30:00", "11/28/2024": "14:30:00", + "11/29/2024": "14:45:00", "12/24/2024": "13:45:00", "12/31/2024": "17:00:00", "1/20/2025": "14:30:00", diff --git a/Tests/Common/Securities/MarketHoursDatabaseTests.cs b/Tests/Common/Securities/MarketHoursDatabaseTests.cs index 3aa927ad9843..06cdee271b8c 100644 --- a/Tests/Common/Securities/MarketHoursDatabaseTests.cs +++ b/Tests/Common/Securities/MarketHoursDatabaseTests.cs @@ -224,6 +224,44 @@ public void CorrectlyReadsCMEGroupFutureEarlyCloses(string futureTicker, string } } + [TestCase("ES", Market.CME, "7/3/2023", "13:15:00", "18:00:00")] + [TestCase("MNQ", Market.CME, "7/3/2024", "13:15:00", "18:00:00")] + [TestCase("YM", Market.CBOT, "7/3/2024", "13:15:00", "18:00:00")] + [TestCase("EMD", Market.CME, "7/3/2024", "12:15:00", "17:00:00")] + [TestCase("ES", Market.CME, "1/9/2025", "09:30:00", "18:00:00")] + [TestCase("LE", Market.CME, "1/9/2025", "12:15:00", null)] + [TestCase("ES", Market.CME, "11/29/2024", "13:15:00", null)] + [TestCase("ZN", Market.CBOT, "11/29/2024", "12:15:00", null)] + [TestCase("ZC", Market.CBOT, "11/29/2024", "12:05:00", null)] + [TestCase("6E", Market.CME, "11/29/2024", "13:45:00", null)] + [TestCase("BTC", Market.CME, "11/29/2024", "13:45:00", null)] + [TestCase("CL", Market.NYMEX, "11/29/2024", "14:45:00", null)] + [TestCase("GC", Market.COMEX, "11/29/2024", "14:45:00", null)] + public void CorrectlyReadsCMEGroupFutureShortenedSessions(string futureTicker, string market, string date, string earlyClose, string lateOpen) + { + var provider = MarketHoursDatabase.FromDataFolder(); + var ticker = OptionSymbol.MapToUnderlying(futureTicker, SecurityType.Future); + var future = Symbol.Create(ticker, SecurityType.Future, market); + + var exchangeHours = provider.GetEntry(market, ticker, future.SecurityType).ExchangeHours; + var day = DateTime.Parse(date, CultureInfo.InvariantCulture); + var earlyCloseTime = TimeSpan.Parse(earlyClose, CultureInfo.InvariantCulture); + + Assert.IsFalse(exchangeHours.Holidays.Contains(day)); + Assert.AreEqual(earlyCloseTime, exchangeHours.EarlyCloses[day]); + Assert.AreEqual(day + earlyCloseTime, exchangeHours.GetLastDailyMarketClose(day, false)); + + if (lateOpen == null) + { + Assert.IsFalse(exchangeHours.LateOpens.ContainsKey(day)); + return; + } + + var lateOpenTime = TimeSpan.Parse(lateOpen, CultureInfo.InvariantCulture); + Assert.AreEqual(lateOpenTime, exchangeHours.LateOpens[day]); + Assert.AreEqual(lateOpenTime, exchangeHours.GetMarketHours(day).GetMarketOpen(earlyCloseTime, true)); + } + /// /// An early close or a late open only says something about a day the exchange trades. Both get /// carried from one year to the next, and carrying them by calendar date rather than by trading From 69dd3571de8e8d945f862a58ce76673204f336c8 Mon Sep 17 00:00:00 2001 From: Sasha Date: Fri, 18 Sep 2026 14:58:27 -0300 Subject: [PATCH 2/3] Correct Christmas 2025 and National Day of Mourning sessions for CME-family futures Drop the 25 Dec 2025 early close that 110 entries carry at their own regular close alongside the evening late open. SecurityExchangeHours treats an early close that precedes a late open as a pause, so the pair opened the whole regular session on a day the exchange is closed. The late open alone is how every entry encodes 25 Dec 2023 and 25 Dec 2024. Move 9 Jan 2025 off the CBOT and COMEX market wildcards. Rates and grains closed 12:15 CT and reopened at their regular evening time, YM and MYM halted 08:30 CT, and metals traded normal hours. AW keeps the closure on its own entry. Extend the MarketHoursDatabaseTests coverage to both dates. --- Data/market-hours/market-hours-database.json | 170 ++++++------------ .../Securities/MarketHoursDatabaseTests.cs | 21 +++ 2 files changed, 77 insertions(+), 114 deletions(-) diff --git a/Data/market-hours/market-hours-database.json b/Data/market-hours/market-hours-database.json index 9f09b89dee6b..67d0de1080de 100644 --- a/Data/market-hours/market-hours-database.json +++ b/Data/market-hours/market-hours-database.json @@ -1137,7 +1137,6 @@ "1/1/2024", "1/2/2023", "1/2/2007", - "1/9/2025", "1/20/2025", "1/19/1998", "1/18/1999", @@ -1851,7 +1850,6 @@ "1/1/2021", "1/1/2022", "1/1/2024", - "1/9/2025", "1/20/2025", "1/2/2023", "1/2/2007", @@ -2700,6 +2698,7 @@ "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/19/2025": "16:00:00", "2/16/2025": "16:00:00", "4/17/2025": "16:00:00", @@ -2805,6 +2804,7 @@ "5/27/2024": "19:00:00", "6/19/2024": "19:00:00", "9/2/2024": "19:00:00", + "1/9/2025": "19:00:00", "1/20/2025": "19:00:00", "2/17/2025": "19:00:00", "5/26/2025": "19:00:00", @@ -3211,6 +3211,7 @@ "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/19/2025": "16:00:00", "2/16/2025": "16:00:00", "4/17/2025": "16:00:00", @@ -3316,6 +3317,7 @@ "5/27/2024": "19:00:00", "6/19/2024": "19:00:00", "9/2/2024": "19:00:00", + "1/9/2025": "19:00:00", "1/20/2025": "19:00:00", "2/17/2025": "19:00:00", "5/26/2025": "19:00:00", @@ -3863,6 +3865,7 @@ "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/19/2025": "16:00:00", "2/16/2025": "16:00:00", "4/17/2025": "16:00:00", @@ -3968,6 +3971,7 @@ "5/27/2024": "19:00:00", "6/19/2024": "19:00:00", "9/2/2024": "19:00:00", + "1/9/2025": "19:00:00", "1/20/2025": "19:00:00", "2/17/2025": "19:00:00", "5/26/2025": "19:00:00", @@ -4218,6 +4222,7 @@ ], "earlyCloses": { "11/29/2024": "12:05:00", + "1/9/2025": "12:15:00", "12/31/2025": "16:00:00", "1/18/2026": "16:00:00", "2/15/2026": "16:00:00", @@ -4243,6 +4248,7 @@ "12/31/2027": "16:00:00" }, "lateOpens": { + "1/9/2025": "19:00:00", "1/2/2026": "08:30:00", "1/19/2026": "19:00:00", "2/16/2026": "19:00:00", @@ -4373,6 +4379,7 @@ ], "earlyCloses": { "11/29/2024": "12:05:00", + "1/9/2025": "12:15:00", "12/31/2025": "16:00:00", "1/18/2026": "16:00:00", "2/15/2026": "16:00:00", @@ -4398,6 +4405,7 @@ "12/31/2027": "16:00:00" }, "lateOpens": { + "1/9/2025": "19:00:00", "1/2/2026": "08:30:00", "1/19/2026": "19:00:00", "2/16/2026": "19:00:00", @@ -4528,6 +4536,7 @@ ], "earlyCloses": { "11/29/2024": "12:05:00", + "1/9/2025": "12:15:00", "12/31/2025": "16:00:00", "1/18/2026": "16:00:00", "2/15/2026": "16:00:00", @@ -4553,6 +4562,7 @@ "12/31/2027": "16:00:00" }, "lateOpens": { + "1/9/2025": "19:00:00", "1/2/2026": "08:30:00", "1/19/2026": "19:00:00", "2/16/2026": "19:00:00", @@ -4779,6 +4789,7 @@ "11/29/2024": "12:05:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/19/2025": "16:00:00", "2/16/2025": "16:00:00", "4/17/2025": "16:00:00", @@ -4884,6 +4895,7 @@ "5/27/2024": "19:00:00", "6/19/2024": "19:00:00", "9/2/2024": "19:00:00", + "1/9/2025": "19:00:00", "1/20/2025": "19:00:00", "2/17/2025": "19:00:00", "5/26/2025": "19:00:00", @@ -9649,7 +9661,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -10223,7 +10234,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -13174,7 +13184,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -13748,7 +13757,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -14322,7 +14330,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -14896,7 +14903,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -15470,7 +15476,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -16044,7 +16049,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -16618,7 +16622,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -17192,7 +17195,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -17766,7 +17768,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -18340,7 +18341,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -18914,7 +18914,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -19488,7 +19487,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -20062,7 +20060,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -20636,7 +20633,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -21210,7 +21206,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -21784,7 +21779,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -22358,7 +22352,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -22932,7 +22925,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -23506,7 +23498,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -24080,7 +24071,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -25248,7 +25238,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -25822,7 +25811,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -26396,7 +26384,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -26970,7 +26957,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -27544,7 +27530,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -28118,7 +28103,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -29286,7 +29270,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -29860,7 +29843,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -31028,7 +31010,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -31602,7 +31583,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -32176,7 +32156,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -33321,7 +33300,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -33693,6 +33671,7 @@ "saturday": [], "holidays": [ "4/7/2023", + "1/9/2025", "1/1/2026", "1/19/2026", "2/16/2026", @@ -33987,7 +33966,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -34561,7 +34539,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -35135,7 +35112,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -35709,7 +35685,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -36283,7 +36258,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -36815,6 +36789,7 @@ "3/28/2024": "16:00:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/19/2025": "16:00:00", "2/16/2025": "16:00:00", "4/17/2025": "16:00:00", @@ -36920,6 +36895,7 @@ "5/27/2024": "19:00:00", "6/19/2024": "19:00:00", "9/2/2024": "19:00:00", + "1/9/2025": "19:00:00", "1/20/2025": "19:00:00", "2/17/2025": "19:00:00", "5/26/2025": "19:00:00", @@ -37306,7 +37282,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -37873,7 +37848,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -38447,7 +38421,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -39021,7 +38994,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -39912,6 +39884,7 @@ "3/28/2024": "16:00:00", "12/24/2024": "12:05:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/19/2025": "16:00:00", "2/16/2025": "16:00:00", "4/17/2025": "16:00:00", @@ -40017,6 +39990,7 @@ "5/27/2024": "19:00:00", "6/19/2024": "19:00:00", "9/2/2024": "19:00:00", + "1/9/2025": "19:00:00", "1/20/2025": "19:00:00", "2/17/2025": "19:00:00", "5/26/2025": "19:00:00", @@ -40405,7 +40379,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -42062,7 +42035,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -43054,7 +43026,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -44308,7 +44279,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -44882,7 +44852,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -45456,7 +45425,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -46518,7 +46486,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -47580,7 +47547,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -50494,6 +50460,7 @@ "11/28/2024": "13:30:00", "12/24/2024": "12:45:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "13:30:00", "2/17/2025": "13:30:00", "4/17/2025": "16:00:00", @@ -50503,8 +50470,7 @@ "9/1/2025": "13:30:00", "11/27/2025": "13:30:00", "11/28/2025": "13:45:00", - "12/24/2025": "12:45:00", - "12/25/2025": "16:00:00" + "12/24/2025": "12:45:00" }, "lateOpens": { "1/19/2009": "17:00:00", @@ -50607,6 +50573,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -51021,7 +50988,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -51591,7 +51557,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -52161,7 +52126,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -52735,7 +52699,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -54237,7 +54200,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -54811,7 +54773,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -55385,7 +55346,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -55959,7 +55919,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -56381,7 +56340,12 @@ ], "saturday": [], "holidays": [], - "earlyCloses": {} + "earlyCloses": { + "1/9/2025": "12:15:00" + }, + "lateOpens": { + "1/9/2025": "17:00:00" + } }, "Future-cbot-UB": { "dataTimeZone": "UTC", @@ -56580,6 +56544,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -56767,6 +56732,7 @@ "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -56777,7 +56743,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -57176,6 +57141,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -57363,6 +57329,7 @@ "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -57373,7 +57340,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -57772,6 +57738,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -57958,6 +57925,7 @@ "11/28/2024": "12:00:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -57968,7 +57936,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -58367,6 +58334,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -58553,6 +58521,7 @@ "11/28/2024": "12:00:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -58563,7 +58532,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -59009,7 +58977,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -59583,7 +59550,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -60157,7 +60123,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -60731,7 +60696,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -63174,7 +63138,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -63749,7 +63712,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -64323,7 +64285,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -65131,7 +65092,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -65704,7 +65664,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -66270,7 +66229,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -66836,7 +66794,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -67402,7 +67359,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -68564,7 +68520,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -69139,7 +69094,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -69732,6 +69686,7 @@ "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -69742,7 +69697,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -69867,6 +69821,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -70328,6 +70283,7 @@ "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -70338,7 +70294,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -70463,6 +70418,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -70924,6 +70880,7 @@ "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -70934,7 +70891,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -71059,6 +71015,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -71520,6 +71477,7 @@ "11/29/2024": "12:15:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -71530,7 +71488,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -71655,6 +71612,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -72351,7 +72309,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -72920,7 +72877,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -73486,7 +73442,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -74052,7 +74007,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -74622,7 +74576,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -75195,7 +75148,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -75756,6 +75708,7 @@ "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -75767,7 +75720,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -75894,6 +75846,7 @@ "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -76572,7 +76525,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -77138,7 +77090,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -77705,7 +77656,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -78272,7 +78222,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -80451,7 +80400,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -81017,7 +80965,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -109559,7 +109506,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -110132,7 +110078,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -111299,7 +111244,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -111860,6 +111804,7 @@ "11/29/2024": "13:15:00", "12/24/2024": "13:15:00", "12/31/2024": "17:00:00", + "1/9/2025": "09:30:00", "1/20/2025": "13:00:00", "2/17/2025": "13:00:00", "4/17/2025": "17:00:00", @@ -111871,7 +111816,6 @@ "11/27/2025": "13:00:00", "11/28/2025": "13:15:00", "12/24/2025": "13:15:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "13:00:00", "2/16/2026": "13:00:00", @@ -111998,6 +111942,7 @@ "11/28/2024": "18:00:00", "12/25/2024": "18:00:00", "1/1/2025": "18:00:00", + "1/9/2025": "18:00:00", "1/20/2025": "18:00:00", "2/17/2025": "18:00:00", "5/26/2025": "18:00:00", @@ -114244,7 +114189,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -115984,7 +115928,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -117746,7 +117689,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -118320,7 +118262,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -118847,6 +118788,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -119033,6 +118975,7 @@ "11/28/2024": "12:00:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -119043,7 +118986,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -120539,6 +120481,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -120725,6 +120668,7 @@ "11/28/2024": "12:00:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -120735,7 +120679,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -121181,7 +121124,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -121755,7 +121697,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", @@ -122282,6 +122223,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -122468,6 +122410,7 @@ "11/28/2024": "12:00:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -122478,7 +122421,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -124378,6 +124320,7 @@ "11/28/2024": "17:00:00", "12/25/2024": "17:00:00", "1/1/2025": "17:00:00", + "1/9/2025": "17:00:00", "1/20/2025": "17:00:00", "2/17/2025": "17:00:00", "5/26/2025": "17:00:00", @@ -124564,6 +124507,7 @@ "11/28/2024": "12:00:00", "12/24/2024": "12:15:00", "12/31/2024": "16:00:00", + "1/9/2025": "12:15:00", "1/20/2025": "12:00:00", "2/17/2025": "12:00:00", "4/17/2025": "16:00:00", @@ -124574,7 +124518,6 @@ "11/27/2025": "12:00:00", "11/28/2025": "12:15:00", "12/24/2025": "12:15:00", - "12/25/2025": "16:00:00", "12/31/2025": "16:00:00", "1/19/2026": "12:00:00", "2/16/2026": "12:00:00", @@ -125653,7 +125596,6 @@ "11/27/2025": "14:30:00", "11/28/2025": "14:45:00", "12/24/2025": "13:45:00", - "12/25/2025": "17:00:00", "12/31/2025": "17:00:00", "1/19/2026": "14:30:00", "2/16/2026": "14:30:00", diff --git a/Tests/Common/Securities/MarketHoursDatabaseTests.cs b/Tests/Common/Securities/MarketHoursDatabaseTests.cs index 06cdee271b8c..b0150169fc7e 100644 --- a/Tests/Common/Securities/MarketHoursDatabaseTests.cs +++ b/Tests/Common/Securities/MarketHoursDatabaseTests.cs @@ -237,6 +237,9 @@ public void CorrectlyReadsCMEGroupFutureEarlyCloses(string futureTicker, string [TestCase("BTC", Market.CME, "11/29/2024", "13:45:00", null)] [TestCase("CL", Market.NYMEX, "11/29/2024", "14:45:00", null)] [TestCase("GC", Market.COMEX, "11/29/2024", "14:45:00", null)] + [TestCase("ZN", Market.CBOT, "1/9/2025", "12:15:00", "17:00:00")] + [TestCase("ZC", Market.CBOT, "1/9/2025", "12:15:00", "19:00:00")] + [TestCase("YM", Market.CBOT, "1/9/2025", "09:30:00", "18:00:00")] public void CorrectlyReadsCMEGroupFutureShortenedSessions(string futureTicker, string market, string date, string earlyClose, string lateOpen) { var provider = MarketHoursDatabase.FromDataFolder(); @@ -262,6 +265,24 @@ public void CorrectlyReadsCMEGroupFutureShortenedSessions(string futureTicker, s Assert.AreEqual(lateOpenTime, exchangeHours.GetMarketHours(day).GetMarketOpen(earlyCloseTime, true)); } + [TestCase("ES", Market.CME, "12/25/2025", false, true)] + [TestCase("CL", Market.NYMEX, "12/25/2025", false, true)] + [TestCase("ZN", Market.CBOT, "12/25/2025", false, true)] + [TestCase("GC", Market.COMEX, "1/9/2025", true, true)] + [TestCase("AW", Market.CBOT, "1/9/2025", false, false)] + public void CorrectlyReadsCMEGroupFutureSessionAvailability(string futureTicker, string market, string date, bool hasRegularSession, bool hasExtendedSession) + { + var provider = MarketHoursDatabase.FromDataFolder(); + var ticker = OptionSymbol.MapToUnderlying(futureTicker, SecurityType.Future); + var future = Symbol.Create(ticker, SecurityType.Future, market); + + var exchangeHours = provider.GetEntry(market, ticker, future.SecurityType).ExchangeHours; + var day = DateTime.Parse(date, CultureInfo.InvariantCulture); + + Assert.AreEqual(hasRegularSession, exchangeHours.IsDateOpen(day)); + Assert.AreEqual(hasExtendedSession, exchangeHours.IsDateOpen(day, true)); + } + /// /// An early close or a late open only says something about a day the exchange trades. Both get /// carried from one year to the next, and carrying them by calendar date rather than by trading From 0a9c5854888cdccc1afd69b11959b6a611d184e7 Mon Sep 17 00:00:00 2001 From: Sasha Date: Fri, 18 Sep 2026 15:08:53 -0300 Subject: [PATCH 3/3] Assert shortened sessions on the resolved segments A halt at the regular open, such as the equity index entries on 9 Jan 2025, leaves the date without a regular session, so GetLastDailyMarketClose moves to the next trading day. Assert that anchor only when the date keeps a regular session, and check the early close and the reopen on the resolved segments for every case. --- Tests/Common/Securities/MarketHoursDatabaseTests.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Tests/Common/Securities/MarketHoursDatabaseTests.cs b/Tests/Common/Securities/MarketHoursDatabaseTests.cs index b0150169fc7e..3472415cf116 100644 --- a/Tests/Common/Securities/MarketHoursDatabaseTests.cs +++ b/Tests/Common/Securities/MarketHoursDatabaseTests.cs @@ -252,15 +252,23 @@ public void CorrectlyReadsCMEGroupFutureShortenedSessions(string futureTicker, s Assert.IsFalse(exchangeHours.Holidays.Contains(day)); Assert.AreEqual(earlyCloseTime, exchangeHours.EarlyCloses[day]); - Assert.AreEqual(day + earlyCloseTime, exchangeHours.GetLastDailyMarketClose(day, false)); + // A halt at the regular open leaves no regular session, so the close anchor only exists on days that keep one + if (exchangeHours.IsDateOpen(day)) + { + Assert.AreEqual(day + earlyCloseTime, exchangeHours.GetLastDailyMarketClose(day, false)); + } + + var segments = exchangeHours.GetMarketHours(day).Segments; if (lateOpen == null) { Assert.IsFalse(exchangeHours.LateOpens.ContainsKey(day)); + Assert.AreEqual(earlyCloseTime, segments.Last().End); return; } var lateOpenTime = TimeSpan.Parse(lateOpen, CultureInfo.InvariantCulture); + Assert.AreEqual(earlyCloseTime, segments.Last(segment => segment.Start < lateOpenTime).End); Assert.AreEqual(lateOpenTime, exchangeHours.LateOpens[day]); Assert.AreEqual(lateOpenTime, exchangeHours.GetMarketHours(day).GetMarketOpen(earlyCloseTime, true)); }