Lean  $LEAN_TAG$
LiveAlgorithmResultsJsonConverter.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 using System;
17 using System.Linq;
18 using Newtonsoft.Json;
19 using QuantConnect.Util;
20 using QuantConnect.Orders;
21 using Newtonsoft.Json.Linq;
22 using QuantConnect.Packets;
24 using System.Collections.Generic;
25 
26 namespace QuantConnect.Api
27 {
28  /// <summary>
29  /// Custom JsonConverter for LiveResults data for live algorithms
30  /// </summary>
31  public class LiveAlgorithmResultsJsonConverter : JsonConverter
32  {
33  /// <summary>
34  /// Gets a value indicating whether this <see cref="T:Newtonsoft.Json.JsonConverter"/> can write JSON.
35  /// </summary>
36  /// <value>
37  /// <c>true</c> if this <see cref="T:Newtonsoft.Json.JsonConverter"/> can write JSON; otherwise, <c>false</c>.
38  /// </value>
39  public override bool CanWrite
40  {
41  get { return false; }
42  }
43 
44  /// <summary>
45  /// Writes the JSON representation of the object.
46  /// </summary>
47  /// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param><param name="value">The value.</param><param name="serializer">The calling serializer.</param>
48  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
49  {
50  throw new NotImplementedException("The LiveAlgorithmResultsJsonConverter does not implement a WriteJson method.");
51  }
52 
53  /// <summary>
54  /// Determines whether this instance can convert the specified object type.
55  /// </summary>
56  /// <param name="objectType">Type of the object.</param>
57  /// <returns>
58  /// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
59  /// </returns>
60  public override bool CanConvert(Type objectType)
61  {
62  return typeof(LiveAlgorithmResults).IsAssignableFrom(objectType);
63  }
64 
65 
66  /// <summary>
67  /// Reads the JSON representation of the object.
68  /// </summary>
69  /// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param><param name="objectType">Type of the object.</param><param name="existingValue">The existing value of object being read.</param><param name="serializer">The calling serializer.</param>
70  /// <returns>
71  /// The object value.
72  /// </returns>
73  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
74  {
75  var jObject = JObject.Load(reader);
76 
77  // We don't deserialize the json object directly since it contains properties such as `files` and `charts`
78  // that need to be deserialized in a different way
79  var liveAlgoResults = new LiveAlgorithmResults
80  {
81  Message = jObject["message"].Value<string>(),
82  Status = jObject["status"].Value<string>(),
83  DeployId = jObject["deployId"].Value<string>(),
84  CloneId = jObject["cloneId"].Value<int>(),
85  Launched = jObject["launched"].Value<DateTime>(),
86  Stopped = jObject["stopped"].Value<DateTime?>(),
87  Brokerage = jObject["brokerage"].Value<string>(),
88  SecurityTypes = jObject["securityTypes"].Value<string>(),
89  ProjectName = jObject["projectName"].Value<string>(),
90  Datacenter = jObject["datacenter"].Value<string>(),
91  Public = jObject["public"].Value<bool>(),
92  Success = jObject["success"].Value<bool>()
93  };
94 
95  if (!liveAlgoResults.Success)
96  {
97  // Either there was an error in the running algorithm or the algorithm hasn't started
98  liveAlgoResults.Errors = jObject.Last.Children().Select(error => error.ToString()).ToList();
99  return liveAlgoResults;
100  }
101 
102  // Deserialize charting data
103  var chartDictionary = new Dictionary<string, Chart>();
104  var charts = jObject["charts"] ?? jObject["Charts"];
105  if (charts != null)
106  {
107  var stringCharts = jObject["charts"]?.ToString() ?? jObject["Charts"].ToString();
108  if(!string.IsNullOrEmpty(stringCharts))
109  {
110  chartDictionary = JsonConvert.DeserializeObject<Dictionary<string, Chart>>(stringCharts);
111  }
112  }
113 
114  // Deserialize files data
115  var projectFiles = new List<ProjectFile>();
116  var files = jObject["files"] ?? jObject["Files"];
117  if (files != null)
118  {
119  var stringFiles = jObject["files"]?.ToString() ?? jObject["Files"].ToString();
120  if (!string.IsNullOrEmpty(stringFiles))
121  {
122  projectFiles = JsonConvert.DeserializeObject<List<ProjectFile>>(stringFiles);
123  }
124  }
125 
126  liveAlgoResults.Charts = chartDictionary;
127  liveAlgoResults.Files = projectFiles;
128 
129  return liveAlgoResults;
130  }
131  }
132 }