Skip to content

Commit 387b56b

Browse files
Minor fix for schedule universe to always be 8 am ny (#9427)
- Avoid schedule universe running 7 or 8 NY depending on daylight savings, now will always run 8 am NY. Adding unit tests
1 parent 1f0e12e commit 387b56b

2 files changed

Lines changed: 30 additions & 6 deletions

File tree

Engine/DataFeeds/LiveTradingDataFeed.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,12 @@ public class LiveTradingDataFeed : FileSystemDataFeed
5555
private SubscriptionCollection _subscriptions;
5656
private IFactorFileProvider _factorFileProvider;
5757
private IDataChannelProvider _channelProvider;
58-
// in live trading we delay scheduled universe selection between 11 & 12 hours after midnight UTC so that we allow new selection data to be piped in
59-
// NY goes from -4/-5 UTC time, so:
60-
// 11 UTC - 4 => 7am NY
61-
// 12 UTC - 4 => 8am NY
62-
private readonly TimeSpan _scheduledUniverseUtcTimeShift = TimeSpan.FromMinutes(11 * 60 + DateTime.UtcNow.Second);
6358
private readonly HashSet<string> _unsupportedConfigurations = new();
6459

60+
// in live trading we delay scheduled universe selection to 8 am NY, but NY goes from -4/-5 UTC time, so we adjust it
61+
private static ReferenceWrapper<DateTime> _lastUtcDateShiftUpdate;
62+
private static ReferenceWrapper<TimeSpan> _scheduledUniverseUtcTimeShift;
63+
6564
/// <summary>
6665
/// Public flag indicator that the thread is still busy.
6766
/// </summary>
@@ -389,7 +388,7 @@ request.Universe is OptionChainUniverse ||
389388

390389
enumerator = AddScheduleWrapper(request, enumerator, new PredicateTimeProvider(_frontierTimeProvider, (currentUtcDateTime) => {
391390
// will only let time advance after it's passed the live time shift frontier
392-
return currentUtcDateTime.TimeOfDay > _scheduledUniverseUtcTimeShift;
391+
return currentUtcDateTime.TimeOfDay > GetScheduledUniverseUtcTimeShift(currentUtcDateTime);
393392
}));
394393

395394
enumerator = GetWarmupEnumerator(request, enumerator);
@@ -402,6 +401,20 @@ request.Universe is OptionChainUniverse ||
402401
return subscription;
403402
}
404403

404+
public static TimeSpan GetScheduledUniverseUtcTimeShift(DateTime currentUtcDateTime)
405+
{
406+
var currentDate = currentUtcDateTime.Date;
407+
if (currentDate != _lastUtcDateShiftUpdate?.Value)
408+
{
409+
// on every date change, we will update the scheduled time shift to be 8am NY time, which is 12-13 UTC depending on DST
410+
_lastUtcDateShiftUpdate = new(currentDate);
411+
_scheduledUniverseUtcTimeShift = new(currentDate.ConvertFromUtc(TimeZones.NewYork).Date.AddHours(8).ConvertToUtc(TimeZones.NewYork).TimeOfDay
412+
// some minor randomness
413+
+ TimeSpan.FromSeconds(DateTime.UtcNow.Second));
414+
}
415+
return _scheduledUniverseUtcTimeShift.Value;
416+
}
417+
405418
/// <summary>
406419
/// Build and apply the warmup enumerators when required
407420
/// </summary>

Tests/Engine/DataFeeds/LiveTradingDataFeedTests.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,6 +2899,17 @@ public void FillForwardsWarmUpDataToLiveFeed(
28992899
}
29002900
}
29012901

2902+
[TestCase(0, 13)]
2903+
[TestCase(2, 13)]
2904+
[TestCase(10, 12)]
2905+
[TestCase(100, 12)]
2906+
[TestCase(280, 13)]
2907+
public void UniverseScheduleUtcShitft(int dateShitft, int expectedTimeShift)
2908+
{
2909+
var result = LiveTradingDataFeed.GetScheduledUniverseUtcTimeShift(new DateTime(2026, 3, 1).AddDays(dateShitft));
2910+
Assert.AreEqual(expectedTimeShift, (int)result.TotalHours);
2911+
}
2912+
29022913
private IDataFeed RunDataFeed(Resolution resolution = Resolution.Second, List<string> equities = null, List<string> forex = null, List<string> crypto = null,
29032914
Func<FuncDataQueueHandler, IEnumerable<BaseData>> getNextTicksFunction = null,
29042915
Func<Symbol, bool, string, IEnumerable<Symbol>> lookupSymbolsFunction = null,

0 commit comments

Comments
 (0)