/// <summary> /// Scan for past events that didn't fire because there was no data at the scheduled time. /// </summary> /// <param name="time">Current time.</param> public void ScanPastEvents(DateTime time) { foreach (var scheduledEvent in GetScheduledEventsSortedByTime()) { while (scheduledEvent.NextEventUtcTime < time) { Algorithm.SetDateTime(scheduledEvent.NextEventUtcTime); try { scheduledEvent.Scan(scheduledEvent.NextEventUtcTime); } catch (ScheduledEventException scheduledEventException) { var errorMessage = $"BacktestingRealTimeHandler.Run(): There was an error in a scheduled event {scheduledEvent.Name}. The error was {scheduledEventException.Message}"; Log.Error(scheduledEventException, errorMessage); ResultHandler.RuntimeError(errorMessage); // Errors in scheduled event should be treated as runtime error // Runtime errors should end Lean execution Algorithm.RunTimeError = scheduledEventException; } } } }
/// <summary> /// Scan for past events that didn't fire because there was no data at the scheduled time. /// </summary> /// <param name="time">Current time.</param> public void ScanPastEvents(DateTime time) { var scheduledEvents = GetScheduledEventsSortedByTime(); // the first element is always the next while (scheduledEvents.Count > 0 && scheduledEvents[0].NextEventUtcTime < time) { var scheduledEvent = scheduledEvents[0]; var nextEventUtcTime = scheduledEvent.NextEventUtcTime; Algorithm.SetDateTime(nextEventUtcTime); try { _isolatorLimitProvider.Consume(scheduledEvent, nextEventUtcTime, _timeMonitor); } catch (ScheduledEventException scheduledEventException) { var errorMessage = $"BacktestingRealTimeHandler.Run(): There was an error in a scheduled event {scheduledEvent.Name}. The error was {scheduledEventException.Message}"; Log.Error(scheduledEventException, errorMessage); ResultHandler.RuntimeError(errorMessage); // Errors in scheduled event should be treated as runtime error // Runtime errors should end Lean execution Algorithm.RunTimeError = scheduledEventException; } SortFirstElement(scheduledEvents); } }
/// <summary> /// Execute the live realtime event thread montioring. /// It scans every second monitoring for an event trigger. /// </summary> public void Run() { IsActive = true; // continue thread until cancellation is requested while (!_cancellationTokenSource.IsCancellationRequested) { var time = DateTime.UtcNow; // pause until the next second var nextSecond = time.RoundUp(TimeSpan.FromSeconds(1)); var delay = Convert.ToInt32((nextSecond - time).TotalMilliseconds); Thread.Sleep(delay < 0 ? 1 : delay); // poke each event to see if it should fire, we order by unique id to be deterministic foreach (var kvp in ScheduledEvents.OrderBy(pair => pair.Value)) { var scheduledEvent = kvp.Key; try { _isolatorLimitProvider.Consume(scheduledEvent, time); } catch (ScheduledEventException scheduledEventException) { var errorMessage = "LiveTradingRealTimeHandler.Run(): There was an error in a scheduled " + $"event {scheduledEvent.Name}. The error was {scheduledEventException.Message}"; Log.Error(scheduledEventException, errorMessage); ResultHandler.RuntimeError(errorMessage); // Errors in scheduled event should be treated as runtime error // Runtime errors should end Lean execution Algorithm.RunTimeError = new Exception(errorMessage); } } } IsActive = false; Log.Trace("LiveTradingRealTimeHandler.Run(): Exiting thread... Exit triggered: " + _cancellationTokenSource.IsCancellationRequested); }