Lean  $LEAN_TAG$
OptimizationParameterJsonConverter.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 Newtonsoft.Json;
17 using Newtonsoft.Json.Linq;
18 using System;
19 using System.Reflection;
20 
22 {
23  /// <summary>
24  /// Override <see cref="OptimizationParameter"/> deserialization method.
25  /// Can handle <see cref="OptimizationArrayParameter"/> and <see cref="OptimizationStepParameter"/> instances
26  /// </summary>
27  public class OptimizationParameterJsonConverter : JsonConverter
28  {
29  public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
30  {
31  JObject jo = new JObject();
32  Type type = value.GetType();
33 
34  foreach (PropertyInfo prop in type.GetProperties())
35  {
36  if (prop.CanRead)
37  {
38  var attribute = prop.GetCustomAttribute<JsonPropertyAttribute>();
39  object propVal = prop.GetValue(value, null);
40  if (propVal != null)
41  {
42  jo.Add(attribute.PropertyName ?? prop.Name, JToken.FromObject(propVal, serializer));
43  }
44  }
45  }
46  jo.WriteTo(writer);
47  }
48 
49  public override object ReadJson(
50  JsonReader reader,
51  Type objectType,
52  object existingValue,
53  JsonSerializer serializer
54  )
55  {
56  JObject token = JObject.Load(reader);
57  var parameterName = token.GetValue("name", StringComparison.OrdinalIgnoreCase)?.Value<string>();
58  if (string.IsNullOrEmpty(parameterName))
59  {
60  throw new ArgumentException(Messages.OptimizationParameterJsonConverter.OptimizationParameterNotSpecified);
61  }
62 
63  JToken value;
64  JToken minToken;
65  JToken maxToken;
66  OptimizationParameter optimizationParameter = null;
67  if (token.TryGetValue("value", StringComparison.OrdinalIgnoreCase, out value))
68  {
69  optimizationParameter = new StaticOptimizationParameter(parameterName, value.Value<string>());
70  }
71  else if (token.TryGetValue("min", StringComparison.OrdinalIgnoreCase, out minToken) &&
72  token.TryGetValue("max", StringComparison.OrdinalIgnoreCase, out maxToken))
73  {
74  var stepToken = token.GetValue("step", StringComparison.OrdinalIgnoreCase)?.Value<decimal>();
75  var minStepToken = token.GetValue("minStep", StringComparison.OrdinalIgnoreCase)?.Value<decimal>() ?? token.GetValue("min-step", StringComparison.OrdinalIgnoreCase)?.Value<decimal>();
76  if (stepToken.HasValue)
77  {
78  if (minStepToken.HasValue)
79  {
80  optimizationParameter = new OptimizationStepParameter(parameterName,
81  minToken.Value<decimal>(),
82  maxToken.Value<decimal>(),
83  stepToken.Value,
84  minStepToken.Value);
85  }
86  else
87  {
88  optimizationParameter = new OptimizationStepParameter(parameterName,
89  minToken.Value<decimal>(),
90  maxToken.Value<decimal>(),
91  stepToken.Value);
92  }
93  }
94  else
95  {
96  optimizationParameter = new OptimizationStepParameter(parameterName,
97  minToken.Value<decimal>(),
98  maxToken.Value<decimal>());
99  }
100  }
101 
102  if (optimizationParameter == null)
103  {
104  throw new ArgumentException(Messages.OptimizationParameterJsonConverter.OptimizationParameterNotSupported);
105  }
106 
107  return optimizationParameter;
108  }
109 
110  public override bool CanConvert(Type objectType) => typeof(OptimizationParameter).IsAssignableFrom(objectType);
111  }
112 }