Lean  $LEAN_TAG$
Program.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;
18 using QuantConnect.Logging;
22 using QuantConnect.Util;
23 using System;
24 using System.Collections.Generic;
25 using System.IO;
26 using System.Linq;
27 using System.Threading;
28 
30 {
31  public class Program
32  {
33  public static void Main(string[] args)
34  {
35  // Parse report arguments and merge with config to use in the optimizer
36  if (args.Length > 0)
37  {
39  }
40 
41  using var endedEvent = new ManualResetEvent(false);
42 
43  try
44  {
45  Log.DebuggingEnabled = Config.GetBool("debug-mode");
46  Log.FilePath = Path.Combine(Config.Get("results-destination-folder"), "log.txt");
47  Log.LogHandler = Composer.Instance.GetExportedValueByTypeName<ILogHandler>(Config.Get("log-handler", "CompositeLogHandler"));
48 
49  var optimizationStrategyName = Config.Get("optimization-strategy",
50  "QuantConnect.Optimizer.GridSearchOptimizationStrategy");
51  var channel = Config.Get("data-channel");
52  var optimizationId = Config.Get("optimization-id", Guid.NewGuid().ToString());
53  var packet = new OptimizationNodePacket
54  {
55  OptimizationId = optimizationId,
56  OptimizationStrategy = optimizationStrategyName,
58  "optimization-strategy-settings",
59  "{\"$type\":\"QuantConnect.Optimizer.Strategies.OptimizationStrategySettings, QuantConnect.Optimizer\"}"), new JsonSerializerSettings(){TypeNameHandling = TypeNameHandling.All}),
60  Criterion = JsonConvert.DeserializeObject<Target>(Config.Get("optimization-criterion", "{\"target\":\"Statistics.TotalProfit\", \"extremum\": \"max\"}")),
61  Constraints = JsonConvert.DeserializeObject<List<Constraint>>(Config.Get("constraints", "[]")).AsReadOnly(),
62  OptimizationParameters = JsonConvert.DeserializeObject<HashSet<OptimizationParameter>>(Config.Get("parameters", "[]")),
63  MaximumConcurrentBacktests = Config.GetInt("maximum-concurrent-backtests", Math.Max(1, Environment.ProcessorCount / 2)),
64  Channel = channel,
65  };
66 
67  var outOfSampleMaxEndDate = Config.Get("out-of-sample-max-end-date");
68  if (!string.IsNullOrEmpty(outOfSampleMaxEndDate))
69  {
70  packet.OutOfSampleMaxEndDate = Time.ParseDate(outOfSampleMaxEndDate);
71  }
72  packet.OutOfSampleDays = Config.GetInt("out-of-sample-days");
73 
74  var optimizerType = Config.Get("optimization-launcher", typeof(ConsoleLeanOptimizer).Name);
75  var optimizer = (LeanOptimizer)Activator.CreateInstance(Composer.Instance.GetExportedTypes<LeanOptimizer>().Single(x => x.Name == optimizerType), packet);
76 
77  if (Config.GetBool("estimate", false))
78  {
79  var backtestsCount = optimizer.GetCurrentEstimate();
80  Log.Trace($"Optimization estimate: {backtestsCount}");
81 
82  optimizer.DisposeSafely();
83  endedEvent.Set();
84  }
85  else
86  {
87  optimizer.Start();
88 
89  optimizer.Ended += (s, e) =>
90  {
91  optimizer.DisposeSafely();
92  endedEvent.Set();
93  };
94  }
95  }
96  catch (Exception e)
97  {
98  Log.Error(e);
99  }
100 
101  // Wait until the optimizer has stopped running before exiting
102  endedEvent.WaitOne();
103  }
104  }
105 }