1919using NUnit . Framework ;
2020using Python . Runtime ;
2121using QuantConnect . Algorithm ;
22- using QuantConnect . Data ;
2322using QuantConnect . Data . Market ;
24- using QuantConnect . Interfaces ;
2523using QuantConnect . Lean . Engine . DataFeeds ;
2624using QuantConnect . Securities ;
2725using QuantConnect . Tests . Engine . DataFeeds ;
@@ -211,37 +209,65 @@ private static PyObject GetCanonicalSubDataFrame(PyObject dataFrame, Symbol symb
211209 private static IEnumerable < TestCaseData > GetOptionChainApisTestData ( )
212210 {
213211 var indexSymbol = Symbols . SPX ;
214- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 23 , 23 , 0 , 0 ) ) ;
215- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 0 , 0 , 0 ) ) ;
216- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 1 , 0 , 0 ) ) ;
217- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 2 , 0 , 0 ) ) ;
218- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 6 , 0 , 0 ) ) ;
219- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 12 , 0 , 0 ) ) ;
220- yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 16 , 0 , 0 ) ) ;
221-
222212 var equitySymbol = Symbols . GOOG ;
223- yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 0 , 0 , 0 ) ) ;
224- yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 1 , 0 , 0 ) ) ;
225- yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 2 , 0 , 0 ) ) ;
226- yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 6 , 0 , 0 ) ) ;
227- yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 12 , 0 , 0 ) ) ;
228- yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 16 , 0 , 0 ) ) ;
229-
230213 var futureSymbol = Symbol . CreateFuture ( Futures . Indices . SP500EMini , Market . CME , new DateTime ( 2020 , 6 , 19 ) ) ;
231- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 04 , 23 , 0 , 0 ) ) ;
232- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 0 , 0 , 0 ) ) ;
233- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 1 , 0 , 0 ) ) ;
234- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 2 , 0 , 0 ) ) ;
235- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 6 , 0 , 0 ) ) ;
236- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 12 , 0 , 0 ) ) ;
237- yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 16 , 0 , 0 ) ) ;
214+
215+ foreach ( var withSecurityAdded in new [ ] { true , false } )
216+ {
217+ var extendedMarketHoursCases = withSecurityAdded ? [ true , false ] : new [ ] { false } ;
218+ foreach ( var withExtendedMarketHours in extendedMarketHoursCases )
219+ {
220+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 23 , 23 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
221+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 0 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
222+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 1 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
223+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 2 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
224+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 6 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
225+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 12 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
226+ yield return new TestCaseData ( indexSymbol , new DateTime ( 2015 , 12 , 24 , 16 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
227+
228+ yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 0 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
229+ yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 1 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
230+ yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 2 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
231+ yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 6 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
232+ yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 12 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
233+ yield return new TestCaseData ( equitySymbol , new DateTime ( 2015 , 12 , 24 , 16 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
234+
235+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 04 , 23 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
236+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 0 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
237+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 1 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
238+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 2 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
239+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 6 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
240+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 12 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
241+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 05 , 16 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
242+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 06 , 0 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
243+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 06 , 1 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
244+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 06 , 2 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
245+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 06 , 6 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
246+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 06 , 12 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
247+ yield return new TestCaseData ( futureSymbol , new DateTime ( 2020 , 01 , 06 , 16 , 0 , 0 ) , withSecurityAdded , withExtendedMarketHours ) ;
248+ }
249+ }
238250 }
239251
240252 [ TestCaseSource ( nameof ( GetOptionChainApisTestData ) ) ]
241- public void OptionChainApisAreConsistent ( Symbol symbol , DateTime dateTime )
253+ public void OptionChainApisAreConsistent ( Symbol symbol , DateTime dateTime , bool withSecurityAdded , bool withExtendedMarketHours )
242254 {
243255 _algorithm . SetDateTime ( dateTime . ConvertToUtc ( _algorithm . TimeZone ) ) ;
244256
257+ if ( withSecurityAdded )
258+ {
259+ if ( symbol . SecurityType == SecurityType . Future )
260+ {
261+ var future = _algorithm . AddFuture ( symbol . ID . Symbol , extendedMarketHours : withExtendedMarketHours ) ;
262+ _algorithm . AddFutureOption ( future . Symbol ) ;
263+ _algorithm . AddFutureContract ( symbol , extendedMarketHours : withExtendedMarketHours ) ;
264+ }
265+ else
266+ {
267+ _algorithm . AddSecurity ( symbol , extendedMarketHours : withExtendedMarketHours ) ;
268+ }
269+ }
270+
245271 var exchange = MarketHoursDatabase . FromDataFolder ( ) . GetExchangeHours ( symbol . ID . Market , symbol , symbol . SecurityType ) ;
246272 var chainFromAlgorithmApi = _algorithm . OptionChain ( symbol ) . Select ( x => x . Symbol ) . ToList ( ) ;
247273 var chainFromChainProviderApi = _optionChainProvider . GetOptionContractList ( symbol ,
@@ -262,26 +288,30 @@ private static IEnumerable<TestCaseData> GetFutureChainApisTestData()
262288 {
263289 foreach ( var withFutureAdded in new [ ] { true , false } )
264290 {
265- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 06 , 23 , 0 , 0 ) , withFutureAdded ) ;
266- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 0 , 0 , 0 ) , withFutureAdded ) ;
267- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 1 , 0 , 0 ) , withFutureAdded ) ;
268- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 2 , 0 , 0 ) , withFutureAdded ) ;
269- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 6 , 0 , 0 ) , withFutureAdded ) ;
270- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 12 , 0 , 0 ) , withFutureAdded ) ;
271- yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 16 , 0 , 0 ) , withFutureAdded ) ;
291+ var extendedMarketHoursCases = withFutureAdded ? [ true , false ] : new [ ] { false } ;
292+ foreach ( var withExtendedMarketHours in extendedMarketHoursCases )
293+ {
294+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 06 , 23 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
295+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 0 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
296+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 1 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
297+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 2 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
298+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 6 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
299+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 12 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
300+ yield return new TestCaseData ( symbol , new DateTime ( 2013 , 10 , 07 , 16 , 0 , 0 ) , withFutureAdded , withExtendedMarketHours ) ;
301+ }
272302 }
273303 }
274304 }
275305
276306 [ TestCaseSource ( nameof ( GetFutureChainApisTestData ) ) ]
277- public void FuturesChainApisAreConsistent ( Symbol symbol , DateTime dateTime , bool withFutureAdded )
307+ public void FuturesChainApisAreConsistent ( Symbol symbol , DateTime dateTime , bool withFutureAdded , bool withExtendedMarketHours )
278308 {
279309 _algorithm . SetDateTime ( dateTime . ConvertToUtc ( _algorithm . TimeZone ) ) ;
280310
281311 if ( withFutureAdded )
282312 {
283313 // It should work regardless of whether the future is added to the algorithm
284- _algorithm . AddFuture ( "ES" ) ;
314+ _algorithm . AddFuture ( symbol . ID . Symbol , extendedMarketHours : withExtendedMarketHours ) ;
285315 }
286316
287317 var exchange = MarketHoursDatabase . FromDataFolder ( ) . GetExchangeHours ( symbol . ID . Market , symbol , symbol . SecurityType ) ;
0 commit comments