Lean  $LEAN_TAG$
BacktestResultPacket.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15 */
16 
17 using System;
18 using Newtonsoft.Json;
19 using QuantConnect.Orders;
20 using QuantConnect.Logging;
22 using System.Collections.Generic;
23 
24 namespace QuantConnect.Packets
25 {
26  /// <summary>
27  /// Backtest result packet: send backtest information to GUI for user consumption.
28  /// </summary>
30  {
31  /// <summary>
32  /// User Id placing this task
33  /// </summary>
34  public int UserId { get; set; }
35 
36  /// <summary>
37  /// Project Id of the this task.
38  /// </summary>
39  public int ProjectId { get; set; }
40 
41  /// <summary>
42  /// User Session Id
43  /// </summary>
44  public string SessionId { get; set; } = string.Empty;
45 
46  /// <summary>
47  /// BacktestId for this result packet
48  /// </summary>
49  public string BacktestId { get; set; } = string.Empty;
50 
51  /// <summary>
52  /// OptimizationId for this result packet if any
53  /// </summary>
54  public string OptimizationId { get; set; }
55 
56  /// <summary>
57  /// Compile Id for the algorithm which generated this result packet.
58  /// </summary>
59  public string CompileId { get; set; } = string.Empty;
60 
61  /// <summary>
62  /// Start of the backtest period as defined in Initialize() method.
63  /// </summary>
64  public DateTime PeriodStart { get; set; }
65 
66  /// <summary>
67  /// End of the backtest period as defined in the Initialize() method.
68  /// </summary>
69  public DateTime PeriodFinish { get; set; }
70 
71  /// <summary>
72  /// DateTime (EST) the user requested this backtest.
73  /// </summary>
74  public DateTime DateRequested { get; set; }
75 
76  /// <summary>
77  /// DateTime (EST) when the backtest was completed.
78  /// </summary>
79  public DateTime DateFinished { get; set; }
80 
81  /// <summary>
82  /// Progress of the backtest as a percentage from 0-1 based on the days lapsed from start-finish.
83  /// </summary>
84  public decimal Progress { get; set; }
85 
86  /// <summary>
87  /// Name of this backtest.
88  /// </summary>
89  public string Name { get; set; } = string.Empty;
90 
91  /// <summary>
92  /// Result data object for this backtest
93  /// </summary>
94  public BacktestResult Results { get; set; } = new ();
95 
96  /// <summary>
97  /// Processing time of the algorithm (from moment the algorithm arrived on the algorithm node)
98  /// </summary>
99  public double ProcessingTime { get; set; }
100 
101  /// <summary>
102  /// Estimated number of tradeable days in the backtest based on the start and end date or the backtest
103  /// </summary>
104  public int TradeableDates { get; set; }
105 
106  /// <summary>
107  /// Default constructor for JSON Serialization
108  /// </summary>
110  : base(PacketType.BacktestResult)
111  {
112  PeriodStart = PeriodFinish = DateRequested = DateFinished = DateTime.UtcNow;
113  }
114 
115  /// <summary>
116  /// Compose the packet from a JSON string:
117  /// </summary>
118  public BacktestResultPacket(string json)
119  : base (PacketType.BacktestResult)
120  {
121  try
122  {
123  var packet = JsonConvert.DeserializeObject<BacktestResultPacket>(json, new JsonSerializerSettings
124  {
125  TypeNameHandling = TypeNameHandling.Auto
126  });
127  CompileId = packet.CompileId;
128  Channel = packet.Channel;
129  PeriodFinish = packet.PeriodFinish;
130  PeriodStart = packet.PeriodStart;
131  Progress = packet.Progress;
132  SessionId = packet.SessionId;
133  BacktestId = packet.BacktestId;
134  Type = packet.Type;
135  UserId = packet.UserId;
136  DateFinished = packet.DateFinished;
137  DateRequested = packet.DateRequested;
138  Name = packet.Name;
139  ProjectId = packet.ProjectId;
140  Results = packet.Results;
141  ProcessingTime = packet.ProcessingTime;
142  TradeableDates = packet.TradeableDates;
143  OptimizationId = packet.OptimizationId;
144  }
145  catch (Exception err)
146  {
147  Log.Trace($"BacktestResultPacket(): Error converting json: {err}");
148  }
149  }
150 
151 
152  /// <summary>
153  /// Compose result data packet - with tradable dates from the backtest job task and the partial result packet.
154  /// </summary>
155  /// <param name="job">Job that started this request</param>
156  /// <param name="results">Results class for the Backtest job</param>
157  /// <param name="endDate">The algorithms backtest end date</param>
158  /// <param name="startDate">The algorithms backtest start date</param>
159  /// <param name="progress">Progress of the packet. For the packet we assume progess of 100%.</param>
160  public BacktestResultPacket(BacktestNodePacket job, BacktestResult results, DateTime endDate, DateTime startDate, decimal progress = 1m)
161  : this()
162  {
163  try
164  {
165  Progress = Math.Round(progress, 3);
166  SessionId = job.SessionId;
167  PeriodFinish = endDate;
168  PeriodStart = startDate;
169  CompileId = job.CompileId;
170  Channel = job.Channel;
171  BacktestId = job.BacktestId;
173  Results = results;
174  Name = job.Name;
175  UserId = job.UserId;
176  ProjectId = job.ProjectId;
177  SessionId = job.SessionId;
179  }
180  catch (Exception err) {
181  Log.Error(err);
182  }
183  }
184 
185  /// <summary>
186  /// Creates an empty result packet, useful when the algorithm fails to initialize
187  /// </summary>
188  /// <param name="job">The associated job packet</param>
189  /// <returns>An empty result packet</returns>
191  {
193  new Dictionary<string, Chart>(), new Dictionary<int, Order>(), new Dictionary<DateTime, decimal>(),
194  new Dictionary<string, string>(), new SortedDictionary<string, string>(), new Dictionary<string, AlgorithmPerformance>(),
195  new List<OrderEvent>(), new AlgorithmPerformance(), new AlgorithmConfiguration(), new Dictionary<string, string>()
196  )), DateTime.UtcNow, DateTime.UtcNow);
197  }
198  } // End Queue Packet:
199 
200 
201  /// <summary>
202  /// Backtest results object class - result specific items from the packet.
203  /// </summary>
204  public class BacktestResult : Result
205  {
206  /// <summary>
207  /// Rolling window detailed statistics.
208  /// </summary>
209  public Dictionary<string, AlgorithmPerformance> RollingWindow { get; set; } = new Dictionary<string, AlgorithmPerformance>();
210 
211  /// <summary>
212  /// Rolling window detailed statistics.
213  /// </summary>
215 
216  /// <summary>
217  /// Default Constructor
218  /// </summary>
219  public BacktestResult()
220  {
221  }
222 
223  /// <summary>
224  /// Constructor for the result class using dictionary objects.
225  /// </summary>
226  public BacktestResult(BacktestResultParameters parameters) : base(parameters)
227  {
228  RollingWindow = parameters.RollingWindow;
229  TotalPerformance = parameters.TotalPerformance;
230  }
231  }
232 } // End of Namespace: