/// <summary> /// Compose Live Result Data Packet - With tradable dates /// </summary> /// <param name="job">Job that started this request</param> /// <param name="results">Results class for the Backtest job</param> public LiveResultPacket(LiveNodePacket job, LiveResult results) : base(PacketType.LiveResult) { try { SessionId = job.SessionId; CompileId = job.CompileId; DeployId = job.DeployId; Results = results; UserId = job.UserId; ProjectId = job.ProjectId; SessionId = job.SessionId; Channel = job.Channel; } catch (Exception err) { Log.Error(err); } }
/// <summary> /// Compose the packet from a JSON string: /// </summary> public LiveResultPacket(string json) : base(PacketType.LiveResult) { try { var packet = JsonConvert.DeserializeObject <LiveResultPacket>(json); CompileId = packet.CompileId; Channel = packet.Channel; SessionId = packet.SessionId; DeployId = packet.DeployId; Type = packet.Type; UserId = packet.UserId; ProjectId = packet.ProjectId; Results = packet.Results; ProcessingTime = packet.ProcessingTime; } catch (Exception err) { Log.Trace($"LiveResultPacket(): Error converting json: {err}"); } }
/// <summary> /// Truncates the chart and order data in the result packet to within the specified time frame /// </summary> private static void Truncate(LiveResult result, DateTime start, DateTime stop) { var unixDateStart = Time.DateTimeToUnixTimeStamp(start); var unixDateStop = Time.DateTimeToUnixTimeStamp(stop); //Log.Trace("LiveTradingResultHandler.Truncate: Start: " + start.ToString("u") + " Stop : " + stop.ToString("u")); //Log.Trace("LiveTradingResultHandler.Truncate: Truncate Delta: " + (unixDateStop - unixDateStart) + " Incoming Points: " + result.Charts["Strategy Equity"].Series["Equity"].Values.Count); var charts = new Dictionary<string, Chart>(); foreach (var kvp in result.Charts) { var chart = kvp.Value; var newChart = new Chart(chart.Name, chart.ChartType); charts.Add(kvp.Key, newChart); foreach (var series in chart.Series.Values) { var newSeries = new Series(series.Name, series.SeriesType); newSeries.Values.AddRange(series.Values.Where(chartPoint => chartPoint.x >= unixDateStart && chartPoint.x <= unixDateStop)); newChart.AddSeries(newSeries); } } result.Charts = charts; result.Orders = result.Orders.Values.Where(x => x.Time >= start && x.Time <= stop).ToDictionary(x => x.Id); //Log.Trace("LiveTradingResultHandler.Truncate: Truncate Outgoing: " + result.Charts["Strategy Equity"].Series["Equity"].Values.Count); //For live charting convert to UTC foreach (var order in result.Orders) { order.Value.Time = order.Value.Time.ToUniversalTime(); } }
/// <summary> /// Save the snapshot of the total results to storage. /// </summary> /// <param name="packet">Packet to store.</param> /// <param name="async">Store the packet asyncronously to speed up the thread.</param> /// <remarks> /// Async creates crashes in Mono 3.10 if the thread disappears before the upload is complete so it is disabled for now. /// For live trading we're making assumption its a long running task and safe to async save large files. /// </remarks> public void StoreResult(Packet packet, bool async = true) { // this will hold all the serialized data and the keys to be stored var data_keys = Enumerable.Range(0, 0).Select(x => new { Key = (string)null, Serialized = (string)null }).ToList(); try { Log.Debug("LiveTradingResultHandler.StoreResult(): Begin store result sampling"); lock (_chartLock) { // Make sure this is the right type of packet: if (packet.Type != PacketType.LiveResult) return; // Port to packet format: var live = packet as LiveResultPacket; if (live != null) { // we need to down sample var start = DateTime.UtcNow.Date; var stop = start.AddDays(1); // truncate to just today, we don't need more than this for anyone Truncate(live.Results, start, stop); var highResolutionCharts = new Dictionary<string, Chart>(live.Results.Charts); // 10 minute resolution data, save today var tenminuteSampler = new SeriesSampler(TimeSpan.FromMinutes(10)); var tenminuteCharts = tenminuteSampler.SampleCharts(live.Results.Charts, start, stop); live.Results.Charts = tenminuteCharts; data_keys.Add(new { Key = CreateKey("10minute"), Serialized = JsonConvert.SerializeObject(live.Results) }); // minute resoluton data, save today var minuteSampler = new SeriesSampler(TimeSpan.FromMinutes(1)); var minuteCharts = minuteSampler.SampleCharts(live.Results.Charts, start, stop); // swap out our charts with the sampeld data live.Results.Charts = minuteCharts; data_keys.Add(new { Key = CreateKey("minute"), Serialized = JsonConvert.SerializeObject(live.Results) }); // high resolution data, we only want to save an hour live.Results.Charts = highResolutionCharts; start = DateTime.UtcNow.RoundDown(TimeSpan.FromHours(1)); stop = DateTime.UtcNow.RoundUp(TimeSpan.FromHours(1)); Truncate(live.Results, start, stop); foreach (var name in live.Results.Charts.Keys) { var newPacket = new LiveResult(); newPacket.Orders = new Dictionary<int, Order>(live.Results.Orders); newPacket.Holdings = new Dictionary<string, Holding>(live.Results.Holdings); newPacket.Charts = new Dictionary<string, Chart>(); newPacket.Charts.Add(name, live.Results.Charts[name]); data_keys.Add(new { Key = CreateKey("second_" + Uri.EscapeUriString(name), "yyyy-MM-dd-HH"), Serialized = JsonConvert.SerializeObject(newPacket) }); } } else { Log.Error("LiveResultHandler.StoreResult(): Result Null."); } } Log.Debug("LiveTradingResultHandler.StoreResult(): End store result sampling"); // Upload Results Portion foreach (var dataKey in data_keys) { _api.Store(dataKey.Serialized, dataKey.Key, StoragePermissions.Authenticated, async); } } catch (Exception err) { Log.Error(err); } }
/// <summary> /// Compose Live Result Data Packet - With tradable dates /// </summary> /// <param name="job">Job that started this request</param> /// <param name="results">Results class for the Backtest job</param> public LiveResultPacket(LiveNodePacket job, LiveResult results) : base(PacketType.LiveResult) { try { SessionId = job.SessionId; CompileId = job.CompileId; DeployId = job.DeployId; Results = results; UserId = job.UserId; ProjectId = job.ProjectId; SessionId = job.SessionId; Channel = job.Channel; } catch (Exception err) { Log.Error("LiveResultPacket.Constructor: " + err.Message); } }
/// <summary> /// Compose the packet from a JSON string: /// </summary> public LiveResultPacket(string json) : base(PacketType.LiveResult) { try { var packet = JsonConvert.DeserializeObject<LiveResultPacket>(json); CompileId = packet.CompileId; Channel = packet.Channel; SessionId = packet.SessionId; DeployId = packet.DeployId; Type = packet.Type; UserId = packet.UserId; ProjectId = packet.ProjectId; Results = packet.Results; ProcessingTime = packet.ProcessingTime; } catch (Exception err) { Log.Trace("LiveResultPacket(): Error converting json: " + err.Message); } }