1414 */
1515
1616using System ;
17- using System . Linq ;
1817using NUnit . Framework ;
1918using System . Threading ;
2019using QuantConnect . Data ;
@@ -37,15 +36,23 @@ public class PolygonOpenInterestProcessorManagerTests : PolygonDataProviderBaseT
3736
3837 private readonly ManualTimeProvider _timeProviderInstance = new ( ) ;
3938
40- private readonly Lock _locker = new ( ) ;
39+ private readonly EventBasedDataQueueHandlerSubscriptionManager _subscriptionManager = new ( )
40+ {
41+ SubscribeImpl = ( symbols , _ ) => { return true ; } ,
42+ UnsubscribeImpl = ( symbols , _ ) => { return true ; }
43+ } ;
44+
45+ private object _locker = new ( ) ;
4146
42- [ Test ]
43- public void GetOpenInterestOfOptionSymbolsByPolygonOpenInterestProcessorManager ( )
47+ [ TestCase ( "2024-09-16T09:30:59" , true , Description = "Market: After Opening" ) ]
48+ [ TestCase ( "2024-09-16T15:28:59" , true , Description = "Market: Before Closing" ) ]
49+ [ TestCase ( "2024-09-16T16:28:59" , false , Description = "Market: Closed" ) ]
50+ public void GetOpenInterestInDifferentTimeExchangeTime ( string mockDateTime , bool isShouldReturnData )
4451 {
45- var resetEvent = new ManualResetEvent ( false ) ;
52+ var waitOneDelay = isShouldReturnData ? TimeSpan . FromSeconds ( 30 ) : TimeSpan . FromSeconds ( 5 ) ;
53+ var resetEvent = new AutoResetEvent ( false ) ;
4654 var cancellationTokenSource = new CancellationTokenSource ( ) ;
4755 var optionContractsConfigs = GetConfigs ( ) ;
48- var amountOfConfigs = optionContractsConfigs . Count ;
4956
5057 var symbolOpenInterest = new ConcurrentDictionary < Symbol , decimal > ( ) ;
5158 Action < BaseData > callback = ( baseData ) =>
@@ -59,42 +66,41 @@ public void GetOpenInterestOfOptionSymbolsByPolygonOpenInterestProcessorManager(
5966 {
6067 symbolOpenInterest [ baseData . Symbol ] = baseData . Value ;
6168
62- if ( symbolOpenInterest . Count == amountOfConfigs )
69+ if ( symbolOpenInterest . Count > 5 )
6370 {
6471 resetEvent . Set ( ) ;
6572 }
6673 }
6774 } ;
6875
69- _timeProviderInstance . SetCurrentTimeUtc ( DateTime . UtcNow . ConvertFromUtc ( TimeZones . NewYork ) . Date . AddHours ( 8 ) . AddSeconds ( - 5 ) . ConvertToUtc ( TimeZones . NewYork ) ) ;
70- var processor = new PolygonOpenInterestProcessorManager ( _timeProviderInstance , _restApiClient , symbolMapper , dataAggregator , GetTickTime ) ;
71-
72- processor . AddSymbols ( [ .. optionContractsConfigs . Select ( x => x . Symbol ) ] ) ;
73-
7476 foreach ( var config in optionContractsConfigs )
7577 {
78+ _subscriptionManager . Subscribe ( config ) ;
7679 ProcessFeed (
7780 Subscribe ( dataAggregator , config , ( sender , args ) => { } ) ,
7881 cancellationTokenSource . Token ,
7982 callback : callback
8083 ) ;
8184 }
8285
83- // Internal delay to respect the 1-minute request interval for OpenInterest data.
84- resetEvent . WaitOne ( TimeSpan . FromSeconds ( 70 ) , cancellationTokenSource . Token ) ;
85-
86- Assert . Greater ( symbolOpenInterest . Count , 0 ) ;
87-
88- // Advance the current UTC time by 1 day to simulate the next day.
89- // This ensures that any new OpenInterest requests are validated against the updated time.
90- _timeProviderInstance . SetCurrentTimeUtc ( DateTime . UtcNow . AddDays ( 1 ) ) ;
91-
92- resetEvent . Reset ( ) ;
93- symbolOpenInterest . Clear ( ) ;
86+ var mockDateTimeAfterOpenExchange = DateTime . Parse ( mockDateTime ) . ConvertTo ( TimeZones . NewYork , TimeZones . Utc ) ;
87+ _timeProviderInstance . SetCurrentTimeUtc ( mockDateTimeAfterOpenExchange ) ;
88+ var processor = new PolygonOpenInterestProcessorManager ( _timeProviderInstance , _restApiClient , symbolMapper , _subscriptionManager , dataAggregator , GetTickTime ) ;
89+ processor . ScheduleNextRun ( ) ;
90+ resetEvent . WaitOne ( waitOneDelay , cancellationTokenSource . Token ) ;
9491
95- resetEvent . WaitOne ( TimeSpan . FromSeconds ( 30 ) , cancellationTokenSource . Token ) ;
96-
97- Assert . Greater ( symbolOpenInterest . Count , 0 ) ;
92+ if ( isShouldReturnData )
93+ {
94+ Assert . Greater ( symbolOpenInterest . Count , 0 ) ;
95+ foreach ( var ( symbol , openInterest ) in symbolOpenInterest )
96+ {
97+ Assert . Greater ( openInterest , 0 ) ;
98+ }
99+ }
100+ else
101+ {
102+ Assert . Zero ( symbolOpenInterest . Count ) ;
103+ }
98104
99105 cancellationTokenSource . Cancel ( ) ;
100106 cancellationTokenSource . Dispose ( ) ;
@@ -106,7 +112,7 @@ protected override List<SubscriptionDataConfig> GetConfigs(Resolution resolution
106112 {
107113 var configs = new List < SubscriptionDataConfig > ( ) ;
108114
109- var expiryContractDate = new DateTime ( 2025 , 05 , 16 ) ;
115+ var expiryContractDate = new DateTime ( 2024 , 09 , 20 ) ;
110116 var strikesAAPL = new decimal [ ] { 100m , 105m , 110m , 115m , 120m , 125m , 130m , 135m , 140m , 145m } ;
111117
112118 foreach ( var strike in strikesAAPL )
0 commit comments