Lean  $LEAN_TAG$
SymbolJsonConverter.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 Newtonsoft.Json.Linq;
20 
21 namespace QuantConnect
22 {
23  /// <summary>
24  /// Defines a <see cref="JsonConverter"/> to be used when deserializing to
25  /// the <see cref="Symbol"/> class.
26  /// </summary>
27  public class SymbolJsonConverter : JsonConverter
28  {
29  /// <summary>
30  /// Writes the JSON representation of the object.
31  /// </summary>
32  /// <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>
33  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
34  {
35  var symbol = value as Symbol;
36  if (ReferenceEquals(symbol, null)) return;
37 
38  writer.WriteStartObject();
39  writer.WritePropertyName("value");
40  writer.WriteValue(symbol.Value);
41  writer.WritePropertyName("id");
42  writer.WriteValue(symbol.ID.ToString());
43  writer.WritePropertyName("permtick");
44  writer.WriteValue(symbol.Value);
45  if (symbol.HasUnderlying)
46  {
47  writer.WritePropertyName("underlying");
48  WriteJson(writer, symbol.Underlying, serializer);
49  }
50  writer.WriteEndObject();
51  }
52 
53  /// <summary>
54  /// Reads the JSON representation of the object.
55  /// </summary>
56  /// <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>
57  /// <returns>
58  /// The object value.
59  /// </returns>
60  public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
61  {
62  var jobject = JObject.Load(reader);
63 
64  if (jobject.TryGetValue("type", StringComparison.InvariantCultureIgnoreCase, out var type))
65  {
66  return BuildSymbolFromUserFriendlyValue(jobject);
67  }
68  return ReadSymbolFromJson(jobject);
69  }
70 
71  /// <summary>
72  /// Determines whether this instance can convert the specified object type.
73  /// </summary>
74  /// <param name="objectType">Type of the object.</param>
75  /// <returns>
76  /// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
77  /// </returns>
78  public override bool CanConvert(Type objectType)
79  {
80  return objectType == typeof (Symbol);
81  }
82 
83  private Symbol ReadSymbolFromJson(JObject jObject)
84  {
85  JToken symbolId;
86  JToken value;
87 
88  if ((jObject.TryGetValue("ID", StringComparison.InvariantCultureIgnoreCase, out symbolId)
89  && jObject.TryGetValue("Value", StringComparison.InvariantCultureIgnoreCase, out value))
90  || (jObject.TryGetValue("id", StringComparison.InvariantCultureIgnoreCase, out symbolId)
91  && jObject.TryGetValue("value", StringComparison.InvariantCultureIgnoreCase, out value)))
92  {
93  Symbol underlyingSymbol = null;
94  JToken underlying;
95  if (jObject.TryGetValue("Underlying", StringComparison.InvariantCultureIgnoreCase, out underlying)
96  || jObject.TryGetValue("underlying", StringComparison.InvariantCultureIgnoreCase, out underlying))
97  {
98  underlyingSymbol = ReadSymbolFromJson(underlying as JObject);
99  }
100 
101  return new Symbol(SecurityIdentifier.Parse(symbolId.ToString()), value.ToString(), underlyingSymbol);
102  }
103  return null;
104  }
105 
106  /// <summary>
107  /// Creates a symbol from the user friendly string representation
108  /// </summary>
109  private Symbol BuildSymbolFromUserFriendlyValue(JObject jObject)
110  {
111  if (jObject.TryGetValue("value", StringComparison.InvariantCultureIgnoreCase, out var value)
112  && jObject.TryGetValue("type", StringComparison.InvariantCultureIgnoreCase, out var securityTypeToken)
113  && securityTypeToken.ToString().TryParseSecurityType(out var securityType))
114  {
115  if (securityType == SecurityType.Option)
116  {
117  return SymbolRepresentation.ParseOptionTickerOSI(value.ToString());
118  }
119  else if (securityType == SecurityType.Future)
120  {
121  return SymbolRepresentation.ParseFutureSymbol(value.ToString());
122  }
123  else if(securityType == SecurityType.FutureOption)
124  {
125  return SymbolRepresentation.ParseFutureOptionSymbol(value.ToString());
126  }
127  else if (securityType == SecurityType.IndexOption)
128  {
129  return SymbolRepresentation.ParseOptionTickerOSI(value.ToString(), securityType: securityType);
130  }
131 
132  if (!jObject.TryGetValue("market", StringComparison.InvariantCultureIgnoreCase, out var market))
133  {
134  market = Market.USA;
135  }
136  return Symbol.Create(value.ToString(), securityType, market.ToString());
137  }
138  return null;
139  }
140  }
141 }