Ejemplo n.º 1
0
        private IEnumerable <TimeSlice> Stream(IAlgorithm algorithm, ISynchronizer synchronizer, IResultHandler results, CancellationToken cancellationToken)
        {
            var nextWarmupStatusTime = DateTime.MinValue;
            var warmingUp            = algorithm.IsWarmingUp;
            var warmingUpPercent     = 0;

            if (warmingUp)
            {
                nextWarmupStatusTime = DateTime.UtcNow.AddSeconds(1);
                algorithm.Debug("Algorithm starting warm up...");
                results.SendStatusUpdate(AlgorithmStatus.History, $"{warmingUpPercent}");
            }
            else
            {
                results.SendStatusUpdate(AlgorithmStatus.Running);
                // let's be polite, and call warmup finished even though there was no warmup period and avoid algorithms having to handle it instead.
                // we trigger this callback here and not internally in the algorithm so that we can go through python if required
                algorithm.OnWarmupFinished();
            }

            // bellow we compare with slice.Time which is in UTC
            var startTimeTicks = algorithm.UtcTime.Ticks;
            var warmupEndTicks = algorithm.StartDate.ConvertToUtc(algorithm.TimeZone).Ticks;

            // fulfilling history requirements of volatility models in live mode
            if (algorithm.LiveMode)
            {
                warmupEndTicks = DateTime.UtcNow.Ticks;
                ProcessVolatilityHistoryRequirements(algorithm);
            }

            foreach (var timeSlice in synchronizer.StreamData(cancellationToken))
            {
                if (algorithm.IsWarmingUp)
                {
                    var now = DateTime.UtcNow;
                    if (now > nextWarmupStatusTime)
                    {
                        // send some status to the user letting them know we're done history, but still warming up,
                        // catching up to real time data
                        nextWarmupStatusTime = now.AddSeconds(2);
                        var newPercent = (int)(100 * (timeSlice.Time.Ticks - startTimeTicks) / (double)(warmupEndTicks - startTimeTicks));
                        // if there isn't any progress don't send the same update many times
                        if (newPercent != warmingUpPercent)
                        {
                            warmingUpPercent = newPercent;
                            algorithm.Debug($"Processing algorithm warm-up request {warmingUpPercent}%...");
                            results.SendStatusUpdate(AlgorithmStatus.History, $"{warmingUpPercent}");
                        }
                    }
                }
                else if (warmingUp)
                {
                    // warmup finished, send an update
                    warmingUp = false;
                    // we trigger this callback here and not internally in the algorithm so that we can go through python if required
                    algorithm.OnWarmupFinished();
                    algorithm.Debug("Algorithm finished warming up.");
                    results.SendStatusUpdate(AlgorithmStatus.Running, "100");
                }
                yield return(timeSlice);
            }
        }