/// <summary> /// Initializes the real time handler for the specified algorithm and job /// </summary> public void Setup(IAlgorithm algorithm, AlgorithmNodePacket job, IResultHandler resultHandler, IApi api, IIsolatorLimitResultProvider isolatorLimitProvider) { //Initialize: Algorithm = algorithm; ResultHandler = resultHandler; _isolatorLimitProvider = isolatorLimitProvider; _cancellationTokenSource = new CancellationTokenSource(); _marketHoursDatabase = MarketHoursDatabase.FromDataFolder(); var todayInAlgorithmTimeZone = DateTime.UtcNow.ConvertFromUtc(Algorithm.TimeZone).Date; // refresh the market hours for today explicitly, and then set up an event to refresh them each day at midnight RefreshMarketHoursToday(todayInAlgorithmTimeZone); // every day at midnight from tomorrow until the end of time var times = from date in Time.EachDay(todayInAlgorithmTimeZone.AddDays(1), Time.EndOfTime) select date.ConvertToUtc(Algorithm.TimeZone); Add(new ScheduledEvent("RefreshMarketHours", times, (name, triggerTime) => { // refresh market hours from api every day RefreshMarketHoursToday(triggerTime.ConvertFromUtc(Algorithm.TimeZone).Date); })); base.Setup(todayInAlgorithmTimeZone, Time.EndOfTime, job.Language, DateTime.UtcNow); foreach (var scheduledEvent in ScheduledEvents) { // zoom past old events scheduledEvent.Key.SkipEventsUntil(algorithm.UtcTime); // set logging accordingly scheduledEvent.Key.IsLoggingEnabled = Log.DebuggingEnabled; } }
/// <summary> /// Convenience method for invoking a scheduled event's Scan method inside the <see cref="IsolatorLimitResultProvider"/> /// </summary> public static void Consume( this IIsolatorLimitResultProvider isolatorLimitProvider, ScheduledEvent scheduledEvent, DateTime scanTimeUtc ) { // perform initial filtering to prevent starting a task when not necessary if (scheduledEvent.NextEventUtcTime > scanTimeUtc) { return; } var timeProvider = RealTimeProvider.Instance; isolatorLimitProvider.Consume(timeProvider, () => scheduledEvent.Scan(scanTimeUtc)); }
/// <summary> /// Executes the provided code block and while the code block is running, continually consume from /// the limit result provided one token each minute. This function allows the code to run for the /// first full minute without requesting additional time from the provider. Following that, every /// minute an additional one minute will be requested from the provider. /// </summary> /// <remarks> /// This method exists to support scheduled events, and as such, intercepts any errors raised via the /// provided code and wraps them in a <see cref="ScheduledEventException"/>. If in the future this is /// usable elsewhere, consider refactoring to handle the errors in a different fashion. /// </remarks> public static void Consume( this IIsolatorLimitResultProvider isolatorLimitProvider, ITimeProvider timeProvider, Action code, TimeMonitor timeMonitor ) { var consumer = new TimeConsumer { IsolatorLimitProvider = isolatorLimitProvider, TimeProvider = timeProvider }; timeMonitor.Add(consumer); code(); consumer.Finished = true; }
/// <summary> /// Initializes the real time handler for the specified algorithm and job /// </summary> public void Setup(IAlgorithm algorithm, AlgorithmNodePacket job, IResultHandler resultHandler, IApi api, IIsolatorLimitResultProvider isolatorLimitProvider) { //Initialize: Algorithm = algorithm; ResultHandler = resultHandler; _isolatorLimitProvider = isolatorLimitProvider; // create events for algorithm's end of tradeable dates // set up the events for each security to fire every tradeable date before market close base.Setup(Algorithm.StartDate, Algorithm.EndDate); foreach (var scheduledEvent in GetScheduledEventsSortedByTime()) { // zoom past old events scheduledEvent.SkipEventsUntil(algorithm.UtcTime); // set logging accordingly scheduledEvent.IsLoggingEnabled = Log.DebuggingEnabled; } }
/// <summary> /// Executes the provided code block and while the code block is running, continually consume from /// the limit result provided one token each minute. This function allows the code to run for the /// first full minute without requesting additional time from the provider. Following that, every /// minute an additional one minute will be requested from the provider. /// </summary> /// <remarks> /// This method exists to support scheduled events, and as such, intercepts any errors raised via the /// provided code and wraps them in a <see cref="ScheduledEventException"/>. If in the future this is /// usable elsewhere, consider refactoring to handle the errors in a different fashion. /// </remarks> public static void Consume( this IIsolatorLimitResultProvider isolatorLimitProvider, ITimeProvider timeProvider, Action code ) { var finished = 0L; Task.Run(async() => { if (Interlocked.Read(ref finished) != 0L) { // case when the code block has virtually no code in it and // was able to complete faster than the task was able to start return; } var next = timeProvider.GetUtcNow().AddMinutes(1); while (Interlocked.Read(ref finished) == 0L) { if (timeProvider.GetUtcNow() >= next) { // each minute request additional time from the isolator next = next.AddMinutes(1); // this will throw and notify the isolator that we've exceed the limits isolatorLimitProvider.RequestAdditionalTime(minutes: 1); } await Task.Delay(5).ConfigureAwait(false); } }); code(); Interlocked.Increment(ref finished); }
public void Setup(IAlgorithm algorithm, AlgorithmNodePacket job, IResultHandler resultHandler, IApi api, IIsolatorLimitResultProvider isolatorLimitProvider) { }
/// <summary> /// Initializes the real time handler for the specified algorithm and job /// </summary> public override void Setup(IAlgorithm algorithm, AlgorithmNodePacket job, IResultHandler resultHandler, IApi api, IIsolatorLimitResultProvider isolatorLimitProvider) { // create events for algorithm's end of tradeable dates // set up the events for each security to fire every tradeable date before market close base.Setup(algorithm, job, resultHandler, api, isolatorLimitProvider); foreach (var scheduledEvent in GetScheduledEventsSortedByTime()) { // zoom past old events scheduledEvent.SkipEventsUntil(algorithm.UtcTime); // set logging accordingly scheduledEvent.IsLoggingEnabled = Log.DebuggingEnabled; } // after skipping events we should re order _sortingScheduledEventsRequired = true; }