Lean  $LEAN_TAG$
UniversePythonWrapper.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 using System;
16 using System.Collections.Concurrent;
17 using System.Collections.Generic;
18 using Python.Runtime;
20 using QuantConnect.Python;
22 
24 {
25  /// <summary>
26  /// Provides an implementation of <see cref="Universe"/> that wraps a <see cref="PyObject"/> object
27  /// </summary>
29  {
30  private readonly BasePythonWrapper<Universe> _model;
31 
32  /// <summary>
33  /// Gets the settings used for subscriptions added for this universe
34  /// </summary>
35  public override UniverseSettings UniverseSettings
36  {
37  get
38  {
39  return _model.GetProperty<UniverseSettings>(nameof(UniverseSettings));
40  }
41  set
42  {
43  _model.SetProperty(nameof(UniverseSettings), value);
44  }
45  }
46 
47  /// <summary>
48  /// Flag indicating if disposal of this universe has been requested
49  /// </summary>
50  public override bool DisposeRequested
51  {
52  get
53  {
54  return _model.GetProperty<bool>(nameof(DisposeRequested));
55  }
56  protected set
57  {
58  _model.SetProperty(nameof(DisposeRequested), value);
59  }
60  }
61 
62  /// <summary>
63  /// Gets the configuration used to get universe data
64  /// </summary>
66  {
67  get
68  {
69  return _model.GetProperty<SubscriptionDataConfig>(nameof(Configuration));
70  }
71  }
72 
73  /// <summary>
74  /// Gets the internal security collection used to define membership in this universe
75  /// </summary>
76  public override ConcurrentDictionary<Symbol, Member> Securities
77  {
78  get
79  {
80  return _model.GetProperty<ConcurrentDictionary<Symbol, Member>>(nameof(Securities));
81  }
82  }
83 
84  /// <summary>
85  /// Initializes a new instance of the <see cref="UniversePythonWrapper"/> class
86  /// </summary>
87  public UniversePythonWrapper(PyObject universe) : base(null)
88  {
89  _model = new BasePythonWrapper<Universe>(universe, false);
90  }
91 
92  /// <summary>
93  /// Performs universe selection using the data specified
94  /// </summary>
95  /// <param name="utcTime">The current utc time</param>
96  /// <param name="data">The symbols to remain in the universe</param>
97  /// <returns>The data that passes the filter</returns>
98  public override IEnumerable<Symbol> SelectSymbols(DateTime utcTime, BaseDataCollection data)
99  {
100  using (Py.GIL())
101  {
102  var symbols = _model.InvokeMethod(nameof(SelectSymbols), utcTime, data);
103  var iterator = symbols.GetIterator();
104  foreach (PyObject symbol in iterator)
105  {
106  yield return symbol.GetAndDispose<Symbol>();
107  }
108  iterator.Dispose();
109  symbols.Dispose();
110  }
111  }
112 
113  /// <summary>
114  /// Gets the subscription requests to be added for the specified security
115  /// </summary>
116  /// <param name="security">The security to get subscriptions for</param>
117  /// <param name="currentTimeUtc">The current time in utc. This is the frontier time of the algorithm</param>
118  /// <param name="maximumEndTimeUtc">The max end time</param>
119  /// <param name="subscriptionService">Instance which implements <see cref="ISubscriptionDataConfigService"/> interface</param>
120  /// <returns>All subscriptions required by this security</returns>
121  public override IEnumerable<SubscriptionRequest> GetSubscriptionRequests(Security security, DateTime currentTimeUtc, DateTime maximumEndTimeUtc,
122  ISubscriptionDataConfigService subscriptionService)
123  {
124  using (Py.GIL())
125  {
126  var subscriptionRequests = _model.InvokeMethod(nameof(GetSubscriptionRequests), security, currentTimeUtc,
127  maximumEndTimeUtc, subscriptionService);
128  var iterator = subscriptionRequests.GetIterator();
129  foreach (PyObject request in iterator)
130  {
131  var subscriptionRequest = request.GetAndDispose<SubscriptionRequest>();
132  yield return new SubscriptionRequest(subscriptionRequest, universe:this);
133  }
134  iterator.Dispose();
135  subscriptionRequests.Dispose();
136  }
137  }
138  }
139 }