/// <summary> /// Compose the packet from a JSON string: /// </summary> public BacktestResultPacket(string json) : base(PacketType.BacktestResult) { try { var packet = JsonConvert.DeserializeObject <BacktestResultPacket>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); CompileId = packet.CompileId; Channel = packet.Channel; PeriodFinish = packet.PeriodFinish; PeriodStart = packet.PeriodStart; Progress = packet.Progress; SessionId = packet.SessionId; BacktestId = packet.BacktestId; Type = packet.Type; UserId = packet.UserId; DateFinished = packet.DateFinished; DateRequested = packet.DateRequested; Name = packet.Name; ProjectId = packet.ProjectId; Results = packet.Results; ProcessingTime = packet.ProcessingTime; TradeableDates = packet.TradeableDates; OptimizationId = packet.OptimizationId; } catch (Exception err) { Log.Trace($"BacktestResultPacket(): Error converting json: {err}"); } }
/// <summary> /// Compose the packet from a JSON string: /// </summary> public BacktestResultPacket(string json) : base(PacketType.BacktestResult) { try { var packet = JsonConvert.DeserializeObject <BacktestResultPacket>(json); CompileId = packet.CompileId; Channel = packet.Channel; PeriodFinish = packet.PeriodFinish; PeriodStart = packet.PeriodStart; Progress = packet.Progress; SessionId = packet.SessionId; BacktestId = packet.BacktestId; Type = packet.Type; UserId = packet.UserId; DateFinished = packet.DateFinished; DateRequested = packet.DateRequested; Name = packet.Name; ProjectId = packet.ProjectId; RunMode = packet.RunMode; Results = packet.Results; ProcessingTime = packet.ProcessingTime; TradeableDates = packet.TradeableDates; } catch (Exception err) { Log.Trace("BacktestResultPacket(): Error converting json: " + err.Message); } }
/// <summary> /// Compose result data packet - with tradable dates from the backtest job task and the partial result packet. /// </summary> /// <param name="job">Job that started this request</param> /// <param name="results">Results class for the Backtest job</param> /// <param name="progress">Progress of the packet. For the packet we assume progess of 100%.</param> public BacktestResultPacket(BacktestNodePacket job, BacktestResult results, decimal progress = 1m) : base(PacketType.BacktestResult) { try { Progress = Math.Round(progress, 3); SessionId = job.SessionId; PeriodFinish = job.PeriodFinish; PeriodStart = job.PeriodStart; CompileId = job.CompileId; Channel = job.Channel; BacktestId = job.BacktestId; Results = results; Name = job.Name; UserId = job.UserId; ProjectId = job.ProjectId; SessionId = job.SessionId; TradeableDates = job.TradeableDates; } catch (Exception err) { Log.Error(err); } }
/// <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 == null || Algorithm.Transactions == null || _processingFinalPacket) { return; } if (DateTime.Now <= _nextUpdate || !(_daysProcessed > (_lastDaysProcessed + 1))) return; //Extract the orders since last update var deltaOrders = new Dictionary<int, Order>(); try { deltaOrders = (from order in Algorithm.Transactions.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("BacktestingResultHandler().Update(): Transactions: " + err.Message); } //Limit length of orders we pass back dynamically to avoid flooding. if (deltaOrders.Count > 50) deltaOrders.Clear(); //Reset loop variables: try { _lastUpdate = DataStream.AlorithmTime.Date; _lastDaysProcessed = _daysProcessed; _nextUpdate = DateTime.Now.AddSeconds(0.5); } catch (Exception err) { Log.Error("BacktestingResultHandler.Update(): Can't update variables: " + err.Message); } var deltaCharts = new Dictionary<string, Chart>(); lock (_chartLock) { //Get the updates since the last chart foreach (var chart in Charts.Values) { deltaCharts.Add(chart.Name, chart.GetUpdates()); } } //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: var completeResult = new BacktestResult(Charts, Algorithm.Transactions.Orders, Algorithm.Transactions.TransactionRecord, new Dictionary<string, string>()); var complete = new BacktestResultPacket(_job, completeResult, progress); if (DateTime.Now > _nextS3Update) { _nextS3Update = DateTime.Now.AddSeconds(30); StoreResult(complete, false); } //2. Backtest Update -> Send the truncated packet to the backtester: var splitPackets = SplitPackets(deltaCharts, deltaOrders, progress); foreach (var backtestingPacket in splitPackets) { Engine.Notify.Send(backtestingPacket); } } catch (Exception err) { Log.Error("BacktestingResultHandler().Update(): " + err.Message + " >> " + err.StackTrace ); } }
} // 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 == null || Algorithm.Transactions == null || _processingFinalPacket) { return; } if (DateTime.Now <= _nextUpdate || !(_daysProcessed > (_lastDaysProcessed + 1))) 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.Time.Date; _lastDaysProcessed = _daysProcessed; _nextUpdate = DateTime.Now.AddSeconds(0.5); } catch (Exception err) { Log.Error(err, "Can't update variables"); } var deltaCharts = new Dictionary<string, Chart>(); lock (_chartLock) { //Get the updates since the last chart foreach (var chart in Charts.Values) { deltaCharts.Add(chart.Name, chart.GetUpdates()); } } //Get the runtime statistics from the user algorithm: var runtimeStatistics = new Dictionary<string, string>(); lock (_runtimeLock) { foreach (var pair in _runtimeStatistics) { runtimeStatistics.Add(pair.Key, pair.Value); } } runtimeStatistics.Add("Unrealized", "$" + _algorithm.Portfolio.TotalUnrealizedProfit.ToString("N2")); runtimeStatistics.Add("Fees", "-$" + _algorithm.Portfolio.TotalFees.ToString("N2")); runtimeStatistics.Add("Net Profit", "$" + _algorithm.Portfolio.TotalProfit.ToString("N2")); runtimeStatistics.Add("Return", ((_algorithm.Portfolio.TotalPortfolioValue - _setupHandler.StartingPortfolioValue) / _setupHandler.StartingPortfolioValue).ToString("P")); runtimeStatistics.Add("Equity", "$" + _algorithm.Portfolio.TotalPortfolioValue.ToString("N2")); //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: var completeResult = new BacktestResult(Charts, _transactionHandler.Orders, Algorithm.Transactions.TransactionRecord, new Dictionary<string, string>(), runtimeStatistics, new Dictionary<string, AlgorithmPerformance>()); var complete = new BacktestResultPacket(_job, completeResult, progress); if (DateTime.Now > _nextS3Update) { _nextS3Update = DateTime.Now.AddSeconds(30); StoreResult(complete, false); } //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); } }
/// <summary> /// Compose result data packet - with tradable dates from the backtest job task and the partial result packet. /// </summary> /// <param name="job">Job that started this request</param> /// <param name="results">Results class for the Backtest job</param> /// <param name="progress">Progress of the packet. For the packet we assume progess of 100%.</param> public BacktestResultPacket(BacktestNodePacket job, BacktestResult results, decimal progress = 1m) : base(PacketType.BacktestResult) { try { Progress = Math.Round(progress, 3); SessionId = job.SessionId; PeriodFinish = job.PeriodFinish; PeriodStart = job.PeriodStart; CompileId = job.CompileId; Channel = job.Channel; BacktestId = job.BacktestId; Results = results; Name = job.Name; UserId = job.UserId; ProjectId = job.ProjectId; SessionId = job.SessionId; TradeableDates = job.TradeableDates; } catch (Exception err) { Log.Error("BacktestResultPacket.Constructor: " + err.Message); } }
/// <summary> /// Compose the packet from a JSON string: /// </summary> public BacktestResultPacket(string json) : base(PacketType.BacktestResult) { try { var packet = JsonConvert.DeserializeObject<BacktestResultPacket>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); CompileId = packet.CompileId; Channel = packet.Channel; PeriodFinish = packet.PeriodFinish; PeriodStart = packet.PeriodStart; Progress = packet.Progress; SessionId = packet.SessionId; BacktestId = packet.BacktestId; Type = packet.Type; UserId = packet.UserId; DateFinished = packet.DateFinished; DateRequested = packet.DateRequested; Name = packet.Name; ProjectId = packet.ProjectId; Results = packet.Results; ProcessingTime = packet.ProcessingTime; TradeableDates = packet.TradeableDates; } catch (Exception err) { Log.Trace("BacktestResultPacket(): Error converting json: " + err.Message); } }