diff --git a/Common/Securities/Future/FutureExpirationCycles.cs b/Common/Securities/Future/FutureExpirationCycles.cs index b372033b6777..bc513ccb5a0b 100644 --- a/Common/Securities/Future/FutureExpirationCycles.cs +++ b/Common/Securities/Future/FutureExpirationCycles.cs @@ -35,6 +35,11 @@ public static class FutureExpirationCycles /// public static readonly int[] March = { 3, 6, 9, 12 }; + /// + /// June Cycle: Expirations in June + /// + public static readonly int[] June = { 6 }; + /// /// December Cycle: Expirations in December /// diff --git a/Common/Securities/Future/Futures.cs b/Common/Securities/Future/Futures.cs index cf3c664edfdf..3f74ef6a4821 100644 --- a/Common/Securities/Future/Futures.cs +++ b/Common/Securities/Future/Futures.cs @@ -1667,6 +1667,11 @@ public static class Indices /// TecDAX Futures /// public const string TecDAX = "FTDX"; + + /// + /// Spot-Quoted Nasdaq-100 Futures + /// + public const string SpotQuotedNasdaq100 = "QNDX"; } /// diff --git a/Common/Securities/Future/FuturesExpiryFunctions.cs b/Common/Securities/Future/FuturesExpiryFunctions.cs index 4f70ada39a51..94e62c69bb0b 100644 --- a/Common/Securities/Future/FuturesExpiryFunctions.cs +++ b/Common/Securities/Future/FuturesExpiryFunctions.cs @@ -239,6 +239,23 @@ public static Func FuturesExpiryFunction(Symbol symbol) return thirdFriday.Add(new TimeSpan(13,30,0)); }) }, + // Spot-Quoted Nasdaq-100 (QNDX): https://www.cmegroup.com/markets/equities/nasdaq/spot-quoted-nasdaq-100.contractSpecs.html + {Symbol.Create(Futures.Indices.SpotQuotedNasdaq100, SecurityType.Future, Market.CME), (time => + { + var market = Market.CME; + var symbol = Futures.Indices.SpotQuotedNasdaq100; + var holidays = FuturesExpiryUtilityFunctions.GetExpirationHolidays(market, symbol); + // Annual contracts (June), a single long dated contract instead of a quarterly roll + while (!FutureExpirationCycles.June.Contains(time.Month)) + { + time = time.AddMonths(1); + } + + // Trading terminates at 4:00 p.m. ET on the 2nd Friday of the contract month + var secondFriday = FuturesExpiryUtilityFunctions.SecondFriday(time); + return FuturesExpiryUtilityFunctions.AddBusinessDaysIfHoliday(secondFriday, -1, holidays).Add(new TimeSpan(20, 0, 0)); + }) + }, // Dow30EMini (YM): http://www.cmegroup.com/trading/equity-index/us-index/e-mini-dow_contract_specifications.html {Symbol.Create(Futures.Indices.Dow30EMini, SecurityType.Future, Market.CBOT), (time => { diff --git a/Data/market-hours/market-hours-database.json b/Data/market-hours/market-hours-database.json index 9cdf3bdf59e3..c4ad87296752 100644 --- a/Data/market-hours/market-hours-database.json +++ b/Data/market-hours/market-hours-database.json @@ -74898,6 +74898,572 @@ "12/31/2027" ] }, + "Future-cme-QNDX": { + "dataTimeZone": "UTC", + "exchangeTimeZone": "America/New_York", + "sunday": [ + { + "start": "18:00:00", + "end": "1.00:00:00", + "state": "premarket" + } + ], + "monday": [ + { + "start": "00:00:00", + "end": "09:30:00", + "state": "premarket" + }, + { + "start": "09:30:00", + "end": "17:00:00", + "state": "market" + }, + { + "start": "18:00:00", + "end": "1.00:00:00", + "state": "postmarket" + } + ], + "tuesday": [ + { + "start": "00:00:00", + "end": "09:30:00", + "state": "premarket" + }, + { + "start": "09:30:00", + "end": "17:00:00", + "state": "market" + }, + { + "start": "18:00:00", + "end": "1.00:00:00", + "state": "postmarket" + } + ], + "wednesday": [ + { + "start": "00:00:00", + "end": "09:30:00", + "state": "premarket" + }, + { + "start": "09:30:00", + "end": "17:00:00", + "state": "market" + }, + { + "start": "18:00:00", + "end": "1.00:00:00", + "state": "postmarket" + } + ], + "thursday": [ + { + "start": "00:00:00", + "end": "09:30:00", + "state": "premarket" + }, + { + "start": "09:30:00", + "end": "17:00:00", + "state": "market" + }, + { + "start": "18:00:00", + "end": "1.00:00:00", + "state": "postmarket" + } + ], + "friday": [ + { + "start": "00:00:00", + "end": "09:30:00", + "state": "premarket" + }, + { + "start": "09:30:00", + "end": "17:00:00", + "state": "market" + } + ], + "saturday": [], + "holidays": [ + "12/25/2026", + "1/1/2027", + "12/24/2027" + ], + "earlyCloses": { + "1/19/2009": "11:30:00", + "2/16/2009": "11:30:00", + "5/25/2009": "11:30:00", + "7/3/2009": "11:30:00", + "9/7/2009": "11:30:00", + "11/26/2009": "11:30:00", + "11/27/2009": "13:15:00", + "12/24/2009": "13:15:00", + "1/18/2010": "11:30:00", + "2/15/2010": "11:30:00", + "4/2/2010": "09:15:00", + "5/31/2010": "11:30:00", + "7/5/2010": "11:30:00", + "9/6/2010": "11:30:00", + "11/25/2010": "11:30:00", + "11/26/2010": "13:15:00", + "1/17/2011": "11:30:00", + "2/21/2011": "11:30:00", + "5/30/2011": "11:30:00", + "7/4/2011": "11:30:00", + "9/5/2011": "11:30:00", + "11/24/2011": "11:30:00", + "11/25/2011": "13:15:00", + "1/16/2012": "11:30:00", + "2/20/2012": "11:30:00", + "4/6/2012": "09:15:00", + "5/28/2012": "11:30:00", + "7/3/2012": "13:15:00", + "7/4/2012": "11:30:00", + "9/3/2012": "11:30:00", + "11/22/2012": "11:30:00", + "11/23/2012": "13:15:00", + "12/24/2012": "13:15:00", + "1/21/2013": "11:30:00", + "2/18/2013": "11:30:00", + "5/27/2013": "11:30:00", + "7/3/2013": "13:15:00", + "7/4/2013": "11:30:00", + "9/2/2013": "11:30:00", + "11/28/2013": "11:30:00", + "11/29/2013": "13:15:00", + "12/24/2013": "13:15:00", + "1/20/2014": "11:30:00", + "2/17/2014": "11:30:00", + "5/26/2014": "13:00:00", + "7/3/2014": "13:15:00", + "7/4/2014": "13:00:00", + "9/1/2014": "13:00:00", + "11/27/2014": "13:00:00", + "11/28/2014": "13:15:00", + "12/24/2014": "13:15:00", + "1/19/2015": "13:00:00", + "2/16/2015": "13:00:00", + "4/3/2015": "09:15:00", + "5/25/2015": "13:00:00", + "7/3/2015": "13:00:00", + "9/7/2015": "13:00:00", + "11/26/2015": "13:00:00", + "11/27/2015": "13:15:00", + "12/24/2015": "13:15:00", + "1/18/2016": "13:00:00", + "2/15/2016": "13:00:00", + "5/30/2016": "13:00:00", + "7/4/2016": "13:00:00", + "9/5/2016": "13:00:00", + "11/24/2016": "13:00:00", + "11/25/2016": "13:15:00", + "1/16/2017": "13:00:00", + "2/20/2017": "13:00:00", + "5/29/2017": "13:00:00", + "7/3/2017": "13:15:00", + "7/4/2017": "13:00:00", + "9/4/2017": "13:00:00", + "11/23/2017": "13:00:00", + "11/24/2017": "13:15:00", + "1/15/2018": "13:00:00", + "2/19/2018": "13:00:00", + "5/28/2018": "13:00:00", + "7/3/2018": "13:15:00", + "7/4/2018": "13:00:00", + "9/3/2018": "13:00:00", + "11/22/2018": "13:00:00", + "11/23/2018": "13:15:00", + "12/24/2018": "13:15:00", + "1/21/2019": "13:00:00", + "2/18/2019": "13:00:00", + "5/27/2019": "13:00:00", + "7/3/2019": "13:15:00", + "7/4/2019": "13:00:00", + "9/2/2019": "13:00:00", + "11/28/2019": "13:00:00", + "11/29/2019": "13:15:00", + "12/24/2019": "13:15:00", + "1/20/2020": "13:00:00", + "2/17/2020": "13:00:00", + "5/25/2020": "13:00:00", + "7/3/2020": "13:00:00", + "9/7/2020": "13:00:00", + "11/26/2020": "13:00:00", + "11/27/2020": "13:15:00", + "12/24/2020": "13:15:00", + "1/18/2021": "13:00:00", + "2/15/2021": "13:00:00", + "4/2/2021": "09:15:00", + "5/31/2021": "13:00:00", + "7/5/2021": "13:00:00", + "9/6/2021": "13:00:00", + "11/25/2021": "13:00:00", + "11/26/2021": "13:15:00", + "1/17/2022": "13:00:00", + "2/21/2022": "13:00:00", + "5/30/2022": "13:00:00", + "6/20/2022": "13:00:00", + "7/4/2022": "13:00:00", + "9/5/2022": "13:00:00", + "11/24/2022": "13:00:00", + "11/25/2022": "13:15:00", + "1/16/2023": "13:00:00", + "2/20/2023": "13:00:00", + "4/7/2023": "09:15:00", + "5/29/2023": "13:00:00", + "6/19/2023": "13:00:00", + "7/4/2023": "13:00:00", + "9/4/2023": "13:00:00", + "11/23/2023": "13:00:00", + "11/24/2023": "13:15:00", + "1/15/2024": "13:00:00", + "2/19/2024": "13:00:00", + "5/27/2024": "13:00:00", + "6/19/2024": "13:00:00", + "7/4/2024": "13:00:00", + "9/2/2024": "13:00:00", + "11/28/2024": "13:00:00", + "12/24/2024": "13:15:00", + "12/31/2024": "17:00:00", + "1/20/2025": "13:00:00", + "2/17/2025": "13:00:00", + "4/17/2025": "17:00:00", + "5/26/2025": "13:00:00", + "6/19/2025": "13:00:00", + "7/3/2025": "13:15:00", + "7/4/2025": "13:00:00", + "9/1/2025": "13:00:00", + "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", + "4/3/2026": "09:15:00", + "5/25/2026": "13:00:00", + "6/19/2026": "13:00:00", + "6/18/2027": "13:00:00", + "7/3/2026": "13:00:00", + "9/7/2026": "13:00:00", + "11/26/2026": "13:00:00", + "11/27/2026": "13:15:00", + "12/24/2026": "13:15:00", + "12/31/2026": "17:00:00", + "1/18/2027": "13:00:00", + "2/15/2027": "13:00:00", + "5/31/2027": "13:00:00", + "7/5/2027": "13:00:00", + "9/6/2027": "13:00:00", + "11/25/2027": "13:00:00", + "11/26/2027": "13:15:00", + "12/23/2027": "17:00:00", + "12/31/2027": "17:00:00" + }, + "lateOpens": { + "1/19/2009": "18:00:00", + "2/16/2009": "18:00:00", + "5/25/2009": "18:00:00", + "9/7/2009": "18:00:00", + "11/26/2009": "18:00:00", + "1/18/2010": "18:00:00", + "2/15/2010": "18:00:00", + "5/31/2010": "18:00:00", + "7/5/2010": "18:00:00", + "9/6/2010": "18:00:00", + "11/25/2010": "18:00:00", + "1/17/2011": "18:00:00", + "2/21/2011": "18:00:00", + "5/30/2011": "18:00:00", + "7/4/2011": "18:00:00", + "9/5/2011": "18:00:00", + "11/24/2011": "18:00:00", + "1/16/2012": "18:00:00", + "2/20/2012": "18:00:00", + "5/28/2012": "18:00:00", + "7/4/2012": "18:00:00", + "9/3/2012": "18:00:00", + "11/22/2012": "18:00:00", + "1/21/2013": "18:00:00", + "2/18/2013": "18:00:00", + "5/27/2013": "18:00:00", + "7/4/2013": "18:00:00", + "9/2/2013": "18:00:00", + "11/28/2013": "18:00:00", + "1/20/2014": "18:00:00", + "2/17/2014": "18:00:00", + "5/26/2014": "18:00:00", + "9/1/2014": "18:00:00", + "11/27/2014": "18:00:00", + "1/19/2015": "18:00:00", + "2/16/2015": "18:00:00", + "5/25/2015": "18:00:00", + "9/7/2015": "18:00:00", + "11/26/2015": "18:00:00", + "1/18/2016": "18:00:00", + "2/15/2016": "18:00:00", + "5/30/2016": "18:00:00", + "7/4/2016": "18:00:00", + "9/5/2016": "18:00:00", + "11/24/2016": "18:00:00", + "1/16/2017": "18:00:00", + "2/20/2017": "18:00:00", + "5/29/2017": "18:00:00", + "7/4/2017": "18:00:00", + "9/4/2017": "18:00:00", + "11/23/2017": "18:00:00", + "1/15/2018": "18:00:00", + "2/19/2018": "18:00:00", + "5/28/2018": "18:00:00", + "7/4/2018": "18:00:00", + "9/3/2018": "18:00:00", + "11/22/2018": "18:00:00", + "1/21/2019": "18:00:00", + "2/18/2019": "18:00:00", + "5/27/2019": "18:00:00", + "7/4/2019": "18:00:00", + "9/2/2019": "18:00:00", + "11/28/2019": "18:00:00", + "1/20/2020": "18:00:00", + "2/17/2020": "18:00:00", + "5/25/2020": "18:00:00", + "9/7/2020": "18:00:00", + "11/26/2020": "18:00:00", + "1/18/2021": "18:00:00", + "2/15/2021": "18:00:00", + "5/31/2021": "18:00:00", + "7/5/2021": "18:00:00", + "9/6/2021": "18:00:00", + "11/25/2021": "18:00:00", + "1/17/2022": "18:00:00", + "2/21/2022": "18:00:00", + "5/30/2022": "18:00:00", + "6/20/2022": "18:00:00", + "7/4/2022": "18:00:00", + "9/5/2022": "18:00:00", + "11/24/2022": "18:00:00", + "1/16/2023": "18:00:00", + "2/20/2023": "18:00:00", + "5/29/2023": "18:00:00", + "6/19/2023": "18:00:00", + "7/4/2023": "18:00:00", + "9/4/2023": "18:00:00", + "11/23/2023": "18:00:00", + "12/25/2023": "18:00:00", + "1/1/2024": "18:00:00", + "1/15/2024": "18:00:00", + "2/19/2024": "18:00:00", + "5/27/2024": "18:00:00", + "6/19/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/20/2025": "18:00:00", + "2/17/2025": "18:00:00", + "5/26/2025": "18:00:00", + "6/19/2025": "18:00:00", + "7/3/2025": "18:00:00", + "9/1/2025": "18:00:00", + "11/27/2025": "18:00:00", + "12/25/2025": "18:00:00", + "1/1/2026": "18:00:00", + "1/19/2026": "18:00:00", + "2/16/2026": "18:00:00", + "5/25/2026": "18:00:00", + "9/7/2026": "18:00:00", + "11/26/2026": "18:00:00", + "1/18/2027": "18:00:00", + "2/15/2027": "18:00:00", + "5/31/2027": "18:00:00", + "7/5/2027": "18:00:00", + "9/6/2027": "18:00:00", + "11/25/2027": "18:00:00" + }, + "bankHolidays": [ + "1/19/2009", + "2/16/2009", + "5/25/2009", + "7/3/2009", + "9/7/2009", + "10/12/2009", + "11/11/2009", + "11/26/2009", + "1/18/2010", + "2/15/2010", + "5/31/2010", + "7/5/2010", + "9/6/2010", + "10/11/2010", + "11/11/2010", + "11/25/2010", + "12/31/2010", + "1/17/2011", + "2/21/2011", + "5/30/2011", + "7/4/2011", + "9/5/2011", + "10/10/2011", + "11/11/2011", + "11/24/2011", + "1/16/2012", + "2/20/2012", + "5/28/2012", + "7/4/2012", + "9/3/2012", + "10/8/2012", + "11/12/2012", + "11/22/2012", + "1/21/2013", + "2/18/2013", + "5/27/2013", + "7/4/2013", + "9/2/2013", + "10/14/2013", + "11/11/2013", + "11/28/2013", + "1/20/2014", + "2/17/2014", + "5/26/2014", + "7/4/2014", + "9/1/2014", + "10/13/2014", + "11/11/2014", + "11/27/2014", + "12/25/2014", + "1/1/2015", + "1/19/2015", + "2/16/2015", + "5/25/2015", + "7/3/2015", + "9/7/2015", + "10/12/2015", + "11/11/2015", + "11/26/2015", + "1/18/2016", + "2/15/2016", + "5/30/2016", + "7/4/2016", + "9/5/2016", + "10/10/2016", + "11/11/2016", + "11/24/2016", + "12/26/2016", + "1/2/2017", + "1/16/2017", + "2/20/2017", + "5/29/2017", + "7/4/2017", + "9/4/2017", + "10/9/2017", + "11/10/2017", + "11/23/2017", + "12/25/2017", + "1/1/2018", + "1/15/2018", + "2/19/2018", + "5/28/2018", + "7/4/2018", + "9/3/2018", + "10/8/2018", + "11/12/2018", + "11/22/2018", + "12/25/2018", + "1/1/2019", + "1/21/2019", + "2/18/2019", + "5/27/2019", + "7/4/2019", + "9/2/2019", + "10/14/2019", + "11/11/2019", + "11/28/2019", + "12/25/2019", + "1/1/2020", + "1/20/2020", + "2/17/2020", + "5/25/2020", + "7/3/2020", + "9/7/2020", + "10/12/2020", + "11/11/2020", + "11/26/2020", + "1/18/2021", + "2/15/2021", + "5/31/2021", + "7/5/2021", + "9/6/2021", + "10/11/2021", + "11/11/2021", + "11/25/2021", + "12/31/2021", + "1/17/2022", + "2/21/2022", + "5/30/2022", + "6/20/2022", + "7/4/2022", + "9/5/2022", + "10/10/2022", + "11/11/2022", + "11/24/2022", + "12/26/2022", + "1/2/2023", + "1/16/2023", + "2/20/2023", + "5/29/2023", + "6/19/2023", + "7/4/2023", + "9/4/2023", + "10/9/2023", + "11/11/2023", + "11/23/2023", + "12/25/2023", + "1/1/2024", + "1/15/2024", + "2/19/2024", + "5/27/2024", + "6/19/2024", + "7/4/2024", + "9/2/2024", + "10/14/2024", + "11/11/2024", + "11/28/2024", + "12/25/2024", + "1/1/2025", + "1/20/2025", + "2/17/2025", + "5/26/2025", + "6/19/2025", + "7/4/2025", + "9/1/2025", + "10/13/2025", + "11/11/2025", + "11/27/2025", + "12/25/2025", + "1/1/2026", + "1/19/2026", + "2/16/2026", + "5/25/2026", + "6/19/2026", + "6/18/2027", + "7/3/2026", + "9/7/2026", + "11/26/2026", + "1/18/2027", + "2/15/2027", + "5/31/2027", + "7/5/2027", + "9/6/2027", + "11/25/2027", + "12/31/2027" + ] + }, "Future-cme-RTY": { "dataTimeZone": "UTC", "exchangeTimeZone": "America/New_York", diff --git a/Data/symbol-properties/symbol-properties-database.csv b/Data/symbol-properties/symbol-properties-database.csv index 12b6b95df076..2120005ef7dd 100644 --- a/Data/symbol-properties/symbol-properties-database.csv +++ b/Data/symbol-properties/symbol-properties-database.csv @@ -303,6 +303,7 @@ cme,MSF,future,Micro Swiss Franc/U.S. Dollar (CHF/USD) Futures,USD,12500,0.0001, cme,NIY,future,Nikkei/YEN Futures,JPY,500.0,5.0,1.0 cme,NKD,future,Nikkei/USD Futures,USD,5.0,5.0,1.0 cme,NQ,future,E-mini Nasdaq-100 Futures,USD,20.0,0.25,1.0 +cme,QNDX,future,Spot-Quoted Nasdaq-100 Futures,USD,0.1,1.0,1.0 cme,RS1,future,E-mini Russell 1000 future,USD,50.0,0.1,1.0 cme,RTY,future,E-mini Russell 2000 Index Futures,USD,50.0,0.1,1.0 cme,RX,future,DJRE Futures,USD,100.0,0.1,1.0 diff --git a/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs b/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs index 54af6f7f141e..a0a3113420ed 100644 --- a/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs +++ b/Tests/Common/Securities/Futures/FuturesExpiryFunctionsTests.cs @@ -156,6 +156,17 @@ public void MicroUltraTreasuriesRollForwardToQuarterlyContractMonth(string ticke Assert.AreEqual(new DateTime(2025, 2, 27, 19, 0, 0), expiration(new DateTime(2025, 1, 1))); } + [Test] + public void SpotQuotedNasdaq100RollsForwardToListedContractMonth() + { + var canonical = Symbol.Create(QuantConnect.Securities.Futures.Indices.SpotQuotedNasdaq100, SecurityType.Future, Market.CME); + var expiration = FuturesExpiryFunctions.FuturesExpiryDictionary[canonical]; + + // Only June is listed, so any other month rolls forward to the next June + Assert.AreEqual(new DateTime(2027, 6, 11, 20, 0, 0), expiration(new DateTime(2027, 6, 1))); + Assert.AreEqual(new DateTime(2027, 6, 11, 20, 0, 0), expiration(new DateTime(2026, 7, 1))); + } + [Test] public void FuturesExpiryFunction_MissingSymbol_ShouldThrowArgumentException() {