|
15 | 15 |
|
16 | 16 | using System;
|
17 | 17 | using Newtonsoft.Json;
|
| 18 | +using Newtonsoft.Json.Linq; |
| 19 | +using System.ComponentModel; |
18 | 20 | using QuantConnect.Securities;
|
19 | 21 | using Newtonsoft.Json.Converters;
|
20 | 22 | using System.Runtime.Serialization;
|
@@ -60,48 +62,104 @@ public static class DateFormat
|
60 | 62 | /// <summary>
|
61 | 63 | /// Singular holding of assets from backend live nodes:
|
62 | 64 | /// </summary>
|
63 |
| - [JsonObject] |
| 65 | + [JsonConverter(typeof(HoldingJsonConverter))] |
64 | 66 | public class Holding
|
65 | 67 | {
|
| 68 | + private decimal? _conversionRate; |
| 69 | + private decimal _marketValue; |
| 70 | + private decimal _unrealizedPnl; |
| 71 | + private decimal _unrealizedPnLPercent; |
| 72 | + |
66 | 73 | /// Symbol of the Holding:
|
67 |
| - [JsonProperty(PropertyName = "symbol")] |
| 74 | + [JsonIgnore] |
68 | 75 | public Symbol Symbol { get; set; } = Symbol.Empty;
|
69 | 76 |
|
70 | 77 | /// Type of the security
|
71 |
| - [JsonProperty(PropertyName = "type")] |
| 78 | + [JsonIgnore] |
72 | 79 | public SecurityType Type => Symbol.SecurityType;
|
73 | 80 |
|
74 | 81 | /// The currency symbol of the holding, such as $
|
75 |
| - [JsonProperty(PropertyName = "currencySymbol")] |
| 82 | + [DefaultValue("$")] |
| 83 | + [JsonProperty(PropertyName = "c", DefaultValueHandling = DefaultValueHandling.Ignore)] |
76 | 84 | public string CurrencySymbol { get; set; }
|
77 | 85 |
|
78 | 86 | /// Average Price of our Holding in the currency the symbol is traded in
|
79 |
| - [JsonProperty(PropertyName = "averagePrice", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 87 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 88 | + [JsonProperty(PropertyName = "a", DefaultValueHandling = DefaultValueHandling.Ignore)] |
80 | 89 | public decimal AveragePrice { get; set; }
|
81 | 90 |
|
82 | 91 | /// Quantity of Symbol We Hold.
|
83 |
| - [JsonProperty(PropertyName = "quantity", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 92 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 93 | + [JsonProperty(PropertyName = "q", DefaultValueHandling = DefaultValueHandling.Ignore)] |
84 | 94 | public decimal Quantity { get; set; }
|
85 | 95 |
|
86 | 96 | /// Current Market Price of the Asset in the currency the symbol is traded in
|
87 |
| - [JsonProperty(PropertyName = "marketPrice", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 97 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 98 | + [JsonProperty(PropertyName = "p", DefaultValueHandling = DefaultValueHandling.Ignore)] |
88 | 99 | public decimal MarketPrice { get; set; }
|
89 | 100 |
|
90 | 101 | /// Current market conversion rate into the account currency
|
91 |
| - [JsonProperty(PropertyName = "conversionRate", DefaultValueHandling = DefaultValueHandling.Ignore)] |
92 |
| - public decimal? ConversionRate { get; set; } |
| 102 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 103 | + [JsonProperty(PropertyName = "r", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 104 | + public decimal? ConversionRate |
| 105 | + { |
| 106 | + get |
| 107 | + { |
| 108 | + return _conversionRate; |
| 109 | + } |
| 110 | + set |
| 111 | + { |
| 112 | + if (value != 1) |
| 113 | + { |
| 114 | + _conversionRate = value; |
| 115 | + } |
| 116 | + } |
| 117 | + } |
93 | 118 |
|
94 | 119 | /// Current market value of the holding
|
95 |
| - [JsonProperty(PropertyName = "marketValue", DefaultValueHandling = DefaultValueHandling.Ignore)] |
96 |
| - public decimal MarketValue { get; set; } |
| 120 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 121 | + [JsonProperty(PropertyName = "v", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 122 | + public decimal MarketValue |
| 123 | + { |
| 124 | + get |
| 125 | + { |
| 126 | + return _marketValue; |
| 127 | + } |
| 128 | + set |
| 129 | + { |
| 130 | + _marketValue = value.SmartRoundingShort(); |
| 131 | + } |
| 132 | + } |
97 | 133 |
|
98 | 134 | /// Current unrealized P/L of the holding
|
99 |
| - [JsonProperty(PropertyName = "unrealizedPnl", DefaultValueHandling = DefaultValueHandling.Ignore)] |
100 |
| - public decimal UnrealizedPnL { get; set; } |
| 135 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 136 | + [JsonProperty(PropertyName = "u", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 137 | + public decimal UnrealizedPnL |
| 138 | + { |
| 139 | + get |
| 140 | + { |
| 141 | + return _unrealizedPnl; |
| 142 | + } |
| 143 | + set |
| 144 | + { |
| 145 | + _unrealizedPnl = value.SmartRoundingShort(); |
| 146 | + } |
| 147 | + } |
101 | 148 |
|
102 | 149 | /// Current unrealized P/L % of the holding
|
103 |
| - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] |
104 |
| - public decimal UnrealizedPnLPercent { get; set; } |
| 150 | + [JsonConverter(typeof(DecimalJsonConverter))] |
| 151 | + [JsonProperty(PropertyName = "up", DefaultValueHandling = DefaultValueHandling.Ignore)] |
| 152 | + public decimal UnrealizedPnLPercent |
| 153 | + { |
| 154 | + get |
| 155 | + { |
| 156 | + return _unrealizedPnLPercent; |
| 157 | + } |
| 158 | + set |
| 159 | + { |
| 160 | + _unrealizedPnLPercent = value.SmartRoundingShort(); |
| 161 | + } |
| 162 | + } |
105 | 163 |
|
106 | 164 | /// Create a new default holding:
|
107 | 165 | public Holding()
|
@@ -159,6 +217,54 @@ public override string ToString()
|
159 | 217 | {
|
160 | 218 | return Messages.Holding.ToString(this);
|
161 | 219 | }
|
| 220 | + |
| 221 | + private class DecimalJsonConverter : JsonConverter |
| 222 | + { |
| 223 | + public override bool CanRead => false; |
| 224 | + public override bool CanConvert(Type objectType) => typeof(decimal) == objectType; |
| 225 | + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) |
| 226 | + { |
| 227 | + writer.WriteRawValue(((decimal)value).NormalizeToStr()); |
| 228 | + } |
| 229 | + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) |
| 230 | + { |
| 231 | + throw new NotImplementedException(); |
| 232 | + } |
| 233 | + } |
| 234 | + private class HoldingJsonConverter : JsonConverter |
| 235 | + { |
| 236 | + public override bool CanWrite => false; |
| 237 | + public override bool CanConvert(Type objectType) => typeof(Holding) == objectType; |
| 238 | + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) |
| 239 | + { |
| 240 | + var jObject = JObject.Load(reader); |
| 241 | + var result = new Holding |
| 242 | + { |
| 243 | + Symbol = jObject["symbol"]?.ToObject<Symbol>() ?? jObject["Symbol"]?.ToObject<Symbol>() ?? Symbol.Empty, |
| 244 | + CurrencySymbol = jObject["c"]?.Value<string>() ?? jObject["currencySymbol"]?.Value<string>() ?? jObject["CurrencySymbol"]?.Value<string>() ?? string.Empty, |
| 245 | + AveragePrice = jObject["a"]?.Value<decimal>() ?? jObject["averagePrice"]?.Value<decimal>() ?? jObject["AveragePrice"]?.Value<decimal>() ?? 0, |
| 246 | + Quantity = jObject["q"]?.Value<decimal>() ?? jObject["quantity"]?.Value<decimal>() ?? jObject["Quantity"]?.Value<decimal>() ?? 0, |
| 247 | + MarketPrice = jObject["p"]?.Value<decimal>() ?? jObject["marketPrice"]?.Value<decimal>() ?? jObject["MarketPrice"]?.Value<decimal>() ?? 0, |
| 248 | + ConversionRate = jObject["r"]?.Value<decimal>() ?? jObject["conversionRate"]?.Value<decimal>() ?? jObject["ConversionRate"]?.Value<decimal>() ?? null, |
| 249 | + MarketValue = jObject["v"]?.Value<decimal>() ?? jObject["marketValue"]?.Value<decimal>() ?? jObject["MarketValue"]?.Value<decimal>() ?? 0, |
| 250 | + UnrealizedPnL = jObject["u"]?.Value<decimal>() ?? jObject["unrealizedPnl"]?.Value<decimal>() ?? jObject["UnrealizedPnl"]?.Value<decimal>() ?? 0, |
| 251 | + UnrealizedPnLPercent = jObject["up"]?.Value<decimal>() ?? jObject["unrealizedPnLPercent"]?.Value<decimal>() ?? jObject["UnrealizedPnLPercent"]?.Value<decimal>() ?? 0, |
| 252 | + }; |
| 253 | + if (!result.ConversionRate.HasValue) |
| 254 | + { |
| 255 | + result.ConversionRate = 1; |
| 256 | + } |
| 257 | + if (string.IsNullOrEmpty(result.CurrencySymbol)) |
| 258 | + { |
| 259 | + result.CurrencySymbol = "$"; |
| 260 | + } |
| 261 | + return result; |
| 262 | + } |
| 263 | + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) |
| 264 | + { |
| 265 | + throw new NotImplementedException(); |
| 266 | + } |
| 267 | + } |
162 | 268 | }
|
163 | 269 |
|
164 | 270 | /// <summary>
|
|
0 commit comments