Example #1
0
        } // End Run();

        /// <summary>
        /// Send a backtest update to the browser taking a latest snapshot of the charting data.
        /// </summary>
        public void Update()
        {
            try
            {
                //Sometimes don't run the update, if not ready or we're ending.
                if (Algorithm?.Transactions == null || _processingFinalPacket)
                {
                    return;
                }

                if (DateTime.UtcNow <= _nextUpdate || _daysProcessed < _daysProcessedFrontier)
                {
                    return;
                }

                //Extract the orders since last update
                var deltaOrders = new Dictionary <int, Order>();

                try
                {
                    deltaOrders = (from order in TransactionHandler.Orders
                                   where order.Value.Time.Date >= _lastUpdate && order.Value.Status == OrderStatus.Filled
                                   select order).ToDictionary(t => t.Key, t => t.Value);
                }
                catch (Exception err)
                {
                    Log.Error(err, "Transactions");
                }

                //Limit length of orders we pass back dynamically to avoid flooding.
                if (deltaOrders.Count > 50)
                {
                    deltaOrders.Clear();
                }

                //Reset loop variables:
                try
                {
                    _lastUpdate            = Algorithm.UtcTime.Date;
                    _daysProcessedFrontier = _daysProcessed + 1;
                    _nextUpdate            = DateTime.UtcNow.AddSeconds(2);
                }
                catch (Exception err)
                {
                    Log.Error(err, "Can't update variables");
                }

                var deltaCharts = new Dictionary <string, Chart>();

                var performanceCharts = new Dictionary <string, Chart>();
                lock (ChartLock)
                {
                    //Get the updates since the last chart
                    foreach (var kvp in Charts)
                    {
                        var chart = kvp.Value;

                        deltaCharts.Add(chart.Name, chart.GetUpdates());

                        if (AlgorithmPerformanceCharts.Contains(kvp.Key))
                        {
                            performanceCharts[kvp.Key] = chart.Clone();
                        }
                    }
                }

                //Get the runtime statistics from the user algorithm:
                var runtimeStatistics = new Dictionary <string, string>();
                lock (RuntimeStatistics)
                {
                    foreach (var pair in RuntimeStatistics)
                    {
                        runtimeStatistics.Add(pair.Key, pair.Value);
                    }
                }
                var summary = GenerateStatisticsResults(performanceCharts).Summary;
                GetAlgorithmRuntimeStatistics(summary, runtimeStatistics);

                //Profit Loss Changes:
                var progress = Convert.ToDecimal(_daysProcessed / _jobDays);
                if (progress > 0.999m)
                {
                    progress = 0.999m;
                }

                //1. Cloud Upload -> Upload the whole packet to S3  Immediately:
                if (DateTime.UtcNow > _nextS3Update)
                {
                    // For intermediate backtesting results, we truncate the order list to include only the last 100 orders
                    // The final packet will contain the full list of orders.
                    const int maxOrders  = 100;
                    var       orderCount = TransactionHandler.Orders.Count;

                    var completeResult = new BacktestResult(
                        Charts,
                        orderCount > maxOrders ? TransactionHandler.Orders.Skip(orderCount - maxOrders).ToDictionary() : TransactionHandler.Orders.ToDictionary(),
                        Algorithm.Transactions.TransactionRecord,
                        new Dictionary <string, string>(),
                        runtimeStatistics,
                        new Dictionary <string, AlgorithmPerformance>());

                    StoreResult(new BacktestResultPacket(_job, completeResult, progress));

                    _nextS3Update = DateTime.UtcNow.AddSeconds(30);
                }

                //2. Backtest Update -> Send the truncated packet to the backtester:
                var splitPackets = SplitPackets(deltaCharts, deltaOrders, runtimeStatistics, progress);

                foreach (var backtestingPacket in splitPackets)
                {
                    MessagingHandler.Send(backtestingPacket);
                }
            }
            catch (Exception err)
            {
                Log.Error(err);
            }
        }
Example #2
0
        } // End Run();

        /// <summary>
        /// Send a backtest update to the browser taking a latest snapshot of the charting data.
        /// </summary>
        private void Update()
        {
            try
            {
                //Sometimes don't run the update, if not ready or we're ending.
                if (Algorithm?.Transactions == null || ExitTriggered)
                {
                    return;
                }

                var utcNow = DateTime.UtcNow;
                if (utcNow <= _nextUpdate || _daysProcessed < _daysProcessedFrontier)
                {
                    return;
                }

                var deltaOrders = GetDeltaOrders(LastDeltaOrderPosition, shouldStop: orderCount => orderCount >= 50);
                // Deliberately skip to the end of order event collection to prevent overloading backtesting UX
                LastDeltaOrderPosition = TransactionHandler.OrderEvents.Count();

                //Reset loop variables:
                try
                {
                    _daysProcessedFrontier = _daysProcessed + 1;
                    _nextUpdate            = utcNow.AddSeconds(3);
                }
                catch (Exception err)
                {
                    Log.Error(err, "Can't update variables");
                }

                var deltaCharts       = new Dictionary <string, Chart>();
                var serverStatistics  = GetServerStatistics(utcNow);
                var performanceCharts = new Dictionary <string, Chart>();
                lock (ChartLock)
                {
                    //Get the updates since the last chart
                    foreach (var kvp in Charts)
                    {
                        var chart = kvp.Value;

                        var updates = chart.GetUpdates();
                        if (!updates.IsEmpty())
                        {
                            deltaCharts.Add(chart.Name, updates);
                        }

                        if (AlgorithmPerformanceCharts.Contains(kvp.Key))
                        {
                            performanceCharts[kvp.Key] = chart.Clone();
                        }
                    }
                }

                //Get the runtime statistics from the user algorithm:
                var runtimeStatistics = new Dictionary <string, string>();
                lock (RuntimeStatistics)
                {
                    foreach (var pair in RuntimeStatistics)
                    {
                        runtimeStatistics.Add(pair.Key, pair.Value);
                    }
                }
                var summary = GenerateStatisticsResults(performanceCharts).Summary;
                GetAlgorithmRuntimeStatistics(summary, runtimeStatistics);

                //Profit Loss Changes:
                var progress = Convert.ToDecimal(_daysProcessed / _jobDays);
                if (progress > 0.999m)
                {
                    progress = 0.999m;
                }

                //1. Cloud Upload -> Upload the whole packet to S3  Immediately:
                if (utcNow > _nextS3Update)
                {
                    // For intermediate backtesting results, we truncate the order list to include only the last 100 orders
                    // The final packet will contain the full list of orders.
                    const int maxOrders  = 100;
                    var       orderCount = TransactionHandler.Orders.Count;

                    var completeResult = new BacktestResult(new BacktestResultParameters(
                                                                Charts,
                                                                orderCount > maxOrders ? TransactionHandler.Orders.Skip(orderCount - maxOrders).ToDictionary() : TransactionHandler.Orders.ToDictionary(),
                                                                Algorithm.Transactions.TransactionRecord,
                                                                new Dictionary <string, string>(),
                                                                runtimeStatistics,
                                                                new Dictionary <string, AlgorithmPerformance>(),
                                                                // we store the last 100 order events, the final packet will contain the full list
                                                                TransactionHandler.OrderEvents.Reverse().Take(100).ToList()));

                    StoreResult(new BacktestResultPacket(_job, completeResult, Algorithm.EndDate, Algorithm.StartDate, progress));

                    _nextS3Update = DateTime.UtcNow.AddSeconds(30);
                }

                //2. Backtest Update -> Send the truncated packet to the backtester:
                var splitPackets = SplitPackets(deltaCharts, deltaOrders, runtimeStatistics, progress, serverStatistics);

                foreach (var backtestingPacket in splitPackets)
                {
                    MessagingHandler.Send(backtestingPacket);
                }

                // let's re update this value after we finish just in case, so we don't re enter in the next loop
                _nextUpdate = DateTime.UtcNow.AddSeconds(3);
            }
            catch (Exception err)
            {
                Log.Error(err);
            }
        }