Lean  $LEAN_TAG$
AlgoSeekFuturesProgram.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 QuantConnect.Logging;
18 using System.Diagnostics;
19 using System.Globalization;
21 using System.Linq;
22 using System.IO;
23 
25 {
26  /// <summary>
27  /// AlgoSeek Options Converter: Convert raw OPRA channel files into QuantConnect Options Data Format.
28  /// </summary>
29  public static class AlgoSeekFuturesProgram
30  {
31  public static void AlgoSeekFuturesConverter(string date)
32  {
33  // There are practical file limits we need to override for this to work.
34  // By default programs are only allowed 1024 files open; for futures parsing we need 100k
35  Environment.SetEnvironmentVariable("MONO_MANAGED_WATCHER", "disabled");
36  Log.LogHandler = new CompositeLogHandler(new ILogHandler[] { new ConsoleLogHandler(), new FileLogHandler("log.txt") });
37 
38  // Directory for the data, output and processed cache:
39  var remoteDirectory = Config.Get("futures-remote-directory").Replace("{0}", date);
40  var sourceDirectory = Config.Get("futures-source-directory").Replace("{0}", date);
41  var dataDirectory = Globals.DataFolder;
42  var resolutions = Config.Get("resolutions");
43  var cleanSourceDirectory = Config.GetBool("clean-source-directory", false);
44 
45  Log.Trace("CONFIGURATION:");
46  Log.Trace("Processor Count: " + Environment.ProcessorCount);
47  Log.Trace("Remote Directory: " + remoteDirectory);
48  Log.Trace("Source Directory: " + sourceDirectory);
49  Log.Trace("Destination Directory: " + dataDirectory);
50 
51  // Date for the option bz files.
52  var referenceDate = DateTime.ParseExact(date, DateFormat.EightCharacter, CultureInfo.InvariantCulture);
53 
54  Log.Trace("DateTime: " + referenceDate.Date.ToStringInvariant());
55 
56  // checking if remote folder exists
57  if(!Directory.Exists(remoteDirectory))
58  {
59  Log.Error("Remote Directory doesn't exist: " + remoteDirectory);
60  return;
61  }
62 
63  // prepare tick types
64  var resolutionList = new[] { Resolution.Minute };
65 
66  if (!string.IsNullOrEmpty(resolutions))
67  {
68  var names = resolutions.Split(new[] { ';' });
69  resolutionList =
70  names
71  .Where(x => !string.IsNullOrEmpty(x))
72  .Select(name => (Resolution)Enum.Parse(typeof(Resolution), name, true)).ToArray();
73  }
74 
75  Log.Trace("Resolutions: " + string.Join(";", resolutionList.Select(x => x.ToString()).ToArray()));
76 
77  // Convert the date:
78  var timer = Stopwatch.StartNew();
79  var converter = new AlgoSeekFuturesConverter(resolutionList.ToList() , referenceDate, remoteDirectory, sourceDirectory, dataDirectory);
80  converter.Convert();
81  Log.Trace($"AlgoSeekFuturesConverter.Main(): {referenceDate.ToStringInvariant()} Conversion finished in time: {timer.Elapsed.ToStringInvariant(null)}");
82 
83  // Compress the memory cache to zips.
84  timer.Restart();
85  converter.Package(referenceDate);
86  Log.Trace($"AlgoSeekFuturesConverter.Main(): {referenceDate.ToStringInvariant()} Compression finished in time: {timer.Elapsed.ToStringInvariant(null)}");
87 
88  if (cleanSourceDirectory)
89  {
90  Log.Trace($"AlgoSeekFuturesConverter.Main(): Cleaning source directory: {sourceDirectory}");
91 
92  try
93  {
94  Directory.Delete(sourceDirectory, true);
95  }
96  catch(Exception err)
97  {
98  Log.Trace($"AlgoSeekFuturesConverter.Main(): Error while cleaning source directory {err.Message}");
99  }
100  }
101  }
102  }
103 }