Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions Engine/DataFeeds/LiveTradingDataFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,12 @@ public class LiveTradingDataFeed : FileSystemDataFeed
private SubscriptionCollection _subscriptions;
private IFactorFileProvider _factorFileProvider;
private IDataChannelProvider _channelProvider;
// 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
// NY goes from -4/-5 UTC time, so:
// 11 UTC - 4 => 7am NY
// 12 UTC - 4 => 8am NY
private readonly TimeSpan _scheduledUniverseUtcTimeShift = TimeSpan.FromMinutes(11 * 60 + DateTime.UtcNow.Second);
private readonly HashSet<string> _unsupportedConfigurations = new();

// in live trading we delay scheduled universe selection to 8 am NY, but NY goes from -4/-5 UTC time, so we adjust it
private static ReferenceWrapper<DateTime> _lastUtcDateShiftUpdate;
private static ReferenceWrapper<TimeSpan> _scheduledUniverseUtcTimeShift;

/// <summary>
/// Public flag indicator that the thread is still busy.
/// </summary>
Expand Down Expand Up @@ -389,7 +388,7 @@ request.Universe is OptionChainUniverse ||

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

enumerator = GetWarmupEnumerator(request, enumerator);
Expand All @@ -402,6 +401,20 @@ request.Universe is OptionChainUniverse ||
return subscription;
}

public static TimeSpan GetScheduledUniverseUtcTimeShift(DateTime currentUtcDateTime)
{
var currentDate = currentUtcDateTime.Date;
if (currentDate != _lastUtcDateShiftUpdate?.Value)
{
// on every date change, we will update the scheduled time shift to be 8am NY time, which is 12-13 UTC depending on DST
_lastUtcDateShiftUpdate = new(currentDate);
_scheduledUniverseUtcTimeShift = new(currentDate.ConvertFromUtc(TimeZones.NewYork).Date.AddHours(8).ConvertToUtc(TimeZones.NewYork).TimeOfDay
// some minor randomness
+ TimeSpan.FromSeconds(DateTime.UtcNow.Second));
}
return _scheduledUniverseUtcTimeShift.Value;
}

/// <summary>
/// Build and apply the warmup enumerators when required
/// </summary>
Expand Down
11 changes: 11 additions & 0 deletions Tests/Engine/DataFeeds/LiveTradingDataFeedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2899,6 +2899,17 @@ public void FillForwardsWarmUpDataToLiveFeed(
}
}

[TestCase(0, 13)]
[TestCase(2, 13)]
[TestCase(10, 12)]
[TestCase(100, 12)]
[TestCase(280, 13)]
public void UniverseScheduleUtcShitft(int dateShitft, int expectedTimeShift)
{
var result = LiveTradingDataFeed.GetScheduledUniverseUtcTimeShift(new DateTime(2026, 3, 1).AddDays(dateShitft));
Assert.AreEqual(expectedTimeShift, (int)result.TotalHours);
}

private IDataFeed RunDataFeed(Resolution resolution = Resolution.Second, List<string> equities = null, List<string> forex = null, List<string> crypto = null,
Func<FuncDataQueueHandler, IEnumerable<BaseData>> getNextTicksFunction = null,
Func<Symbol, bool, string, IEnumerable<Symbol>> lookupSymbolsFunction = null,
Expand Down
Loading