/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using Newtonsoft.Json; using QuantConnect.Orders; using QuantConnect.Logging; using QuantConnect.Statistics; using System.Collections.Generic; namespace QuantConnect.Packets { /// /// Backtest result packet: send backtest information to GUI for user consumption. /// public class BacktestResultPacket : Packet { /// /// User Id placing this task /// public int UserId { get; set; } /// /// Project Id of the this task. /// public int ProjectId { get; set; } /// /// User Session Id /// public string SessionId { get; set; } = string.Empty; /// /// BacktestId for this result packet /// public string BacktestId { get; set; } = string.Empty; /// /// OptimizationId for this result packet if any /// public string OptimizationId { get; set; } /// /// Compile Id for the algorithm which generated this result packet. /// public string CompileId { get; set; } = string.Empty; /// /// Start of the backtest period as defined in Initialize() method. /// public DateTime PeriodStart { get; set; } /// /// End of the backtest period as defined in the Initialize() method. /// public DateTime PeriodFinish { get; set; } /// /// DateTime (EST) the user requested this backtest. /// public DateTime DateRequested { get; set; } /// /// DateTime (EST) when the backtest was completed. /// public DateTime DateFinished { get; set; } /// /// Progress of the backtest as a percentage from 0-1 based on the days lapsed from start-finish. /// public decimal Progress { get; set; } /// /// Name of this backtest. /// public string Name { get; set; } = string.Empty; /// /// Result data object for this backtest /// public BacktestResult Results { get; set; } = new (); /// /// Processing time of the algorithm (from moment the algorithm arrived on the algorithm node) /// public double ProcessingTime { get; set; } /// /// Estimated number of tradeable days in the backtest based on the start and end date or the backtest /// public int TradeableDates { get; set; } /// /// Default constructor for JSON Serialization /// public BacktestResultPacket() : base(PacketType.BacktestResult) { PeriodStart = PeriodFinish = DateRequested = DateFinished = DateTime.UtcNow; } /// /// Compose the packet from a JSON string: /// public BacktestResultPacket(string json) : base (PacketType.BacktestResult) { try { var packet = JsonConvert.DeserializeObject(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}"); } } /// /// Compose result data packet - with tradable dates from the backtest job task and the partial result packet. /// /// Job that started this request /// Results class for the Backtest job /// The algorithms backtest end date /// The algorithms backtest start date /// Progress of the packet. For the packet we assume progess of 100%. public BacktestResultPacket(BacktestNodePacket job, BacktestResult results, DateTime endDate, DateTime startDate, decimal progress = 1m) : this() { try { Progress = Math.Round(progress, 3); SessionId = job.SessionId; PeriodFinish = endDate; PeriodStart = startDate; CompileId = job.CompileId; Channel = job.Channel; BacktestId = job.BacktestId; OptimizationId = job.OptimizationId; Results = results; Name = job.Name; UserId = job.UserId; ProjectId = job.ProjectId; SessionId = job.SessionId; TradeableDates = job.TradeableDates; } catch (Exception err) { Log.Error(err); } } /// /// Creates an empty result packet, useful when the algorithm fails to initialize /// /// The associated job packet /// An empty result packet public static BacktestResultPacket CreateEmpty(BacktestNodePacket job) { return new BacktestResultPacket(job, new BacktestResult(new BacktestResultParameters( new Dictionary(), new Dictionary(), new Dictionary(), new Dictionary(), new SortedDictionary(), new Dictionary(), new List(), new AlgorithmPerformance(), new AlgorithmConfiguration(), new Dictionary() )), DateTime.UtcNow, DateTime.UtcNow); } } // End Queue Packet: /// /// Backtest results object class - result specific items from the packet. /// public class BacktestResult : Result { /// /// Rolling window detailed statistics. /// public Dictionary RollingWindow { get; set; } = new Dictionary(); /// /// Rolling window detailed statistics. /// public AlgorithmPerformance TotalPerformance { get; set; } /// /// Default Constructor /// public BacktestResult() { } /// /// Constructor for the result class using dictionary objects. /// public BacktestResult(BacktestResultParameters parameters) : base(parameters) { RollingWindow = parameters.RollingWindow; TotalPerformance = parameters.TotalPerformance; } } } // End of Namespace: