Lean  $LEAN_TAG$
ConstituentsUniverse.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 System.Collections.Generic;
18 using System.Linq;
19 using Python.Runtime;
20 
22 {
23  /// <summary>
24  /// ConstituentsUniverse allows to perform universe selection based on an
25  /// already preselected set of <see cref="Symbol"/>.
26  /// </summary>
27  /// <remarks>Using this class allows a performance improvement, since there is no
28  /// runtime logic computation required for selecting the <see cref="Symbol"/></remarks>
29  public class ConstituentsUniverse<T> : FuncUniverse<T>
30  where T : BaseData
31  {
32  /// <summary>
33  /// Creates a new instance of the <see cref="ConstituentsUniverse"/>
34  /// </summary>
35  /// <param name="symbol">The universe symbol</param>
36  /// <param name="universeSettings">The universe settings to use</param>
37  /// <param name="constituentsFilter">User-provided function to filter constituents universe with</param>
39  Symbol symbol,
40  UniverseSettings universeSettings,
41  Func<IEnumerable<T>, IEnumerable<Symbol>> constituentsFilter = null)
42  : this(new SubscriptionDataConfig(typeof(T),
43  symbol,
45  TimeZones.NewYork,
46  TimeZones.NewYork,
47  false,
48  false,
49  true,
50  true),
51  universeSettings,
52  constituentsFilter)
53  {
54  }
55 
56  /// <summary>
57  /// Creates a new instance of the <see cref="ConstituentsUniverse"/>
58  /// </summary>
59  /// <param name="symbol">The universe symbol</param>
60  /// <param name="universeSettings">The universe settings to use</param>
61  /// <param name="constituentsFilter">User-provided function to filter constituents universe with</param>
63  Symbol symbol,
64  UniverseSettings universeSettings,
65  PyObject constituentsFilter = null)
66  : this(symbol, universeSettings, constituentsFilter.ConvertPythonUniverseFilterFunction<T>())
67  {
68  }
69 
70  /// <summary>
71  /// Creates a new instance of the <see cref="ConstituentsUniverse"/>
72  /// </summary>
73  /// <param name="subscriptionDataConfig">The universe configuration to use</param>
74  /// <param name="universeSettings">The universe settings to use</param>
75  /// <param name="constituentsFilter">User-provided function to filter constituents universe with</param>
77  SubscriptionDataConfig subscriptionDataConfig,
78  UniverseSettings universeSettings,
79  Func<IEnumerable<T>, IEnumerable<Symbol>> constituentsFilter = null)
80  : base(subscriptionDataConfig,
81  universeSettings,
82  constituentsFilter ?? (constituents =>
83  {
84  var symbols = constituents.Select(baseData => baseData.Symbol).ToList();
85  // for performance, just compare to Symbol.None if we have 1 Symbol
86  if (symbols.Count == 1 && symbols[0] == Symbol.None)
87  {
88  // no symbol selected
89  return Enumerable.Empty<Symbol>();
90  }
91 
92  return symbols;
93  }))
94  {
95  if (!subscriptionDataConfig.IsCustomData)
96  {
97  throw new InvalidOperationException($"{typeof(T).Name} {nameof(SubscriptionDataConfig)}" +
98  $" only supports custom data property set to 'true'");
99  }
100  }
101 
102  /// <summary>
103  /// Constituent universe for a Python function
104  /// </summary>
105  /// <param name="subscriptionDataConfig">The universe configuration to use</param>
106  /// <param name="universeSettings">The universe settings to use</param>
107  /// <param name="constituentsFilter">User-provided function to filter constituents universe with</param>
109  SubscriptionDataConfig subscriptionDataConfig,
110  UniverseSettings universeSettings,
111  PyObject constituentsFilter = null)
112  : this(subscriptionDataConfig, universeSettings, constituentsFilter.ConvertPythonUniverseFilterFunction<T>())
113  {
114  }
115  }
116 
117  /// <summary>
118  /// ConstituentsUniverse allows to perform universe selection based on an
119  /// already preselected set of <see cref="Symbol"/>.
120  /// </summary>
121  /// <remarks>Using this class allows a performance improvement, since there is no
122  /// runtime logic computation required for selecting the <see cref="Symbol"/></remarks>
123  public class ConstituentsUniverse : ConstituentsUniverse<ConstituentsUniverseData>
124  {
125  /// <summary>
126  /// Creates a new instance of the <see cref="ConstituentsUniverse"/>
127  /// </summary>
128  /// <param name="symbol">The universe symbol</param>
129  /// <param name="universeSettings">The universe settings to use</param>
130  /// <param name="filterFunc">The constituents filter function</param>
131  public ConstituentsUniverse(Symbol symbol, UniverseSettings universeSettings, Func<IEnumerable<ConstituentsUniverseData>, IEnumerable<Symbol>> filterFunc)
132  : base(symbol, universeSettings, filterFunc)
133  {
134  }
135 
136  /// <summary>
137  /// Creates a new instance of the <see cref="ConstituentsUniverse"/>
138  /// </summary>
139  /// <param name="symbol">The universe symbol</param>
140  /// <param name="universeSettings">The universe settings to use</param>
141  public ConstituentsUniverse(Symbol symbol, UniverseSettings universeSettings)
142  : base(symbol, universeSettings, (Func<IEnumerable<ConstituentsUniverseData>, IEnumerable<Symbol>>)null)
143  {
144  }
145 
146  /// <summary>
147  /// Creates a new instance of the <see cref="ConstituentsUniverse"/>
148  /// </summary>
149  /// <param name="symbol">The universe symbol</param>
150  /// <param name="universeSettings">The universe settings to use</param>
151  /// <param name="filterFunc">The constituents filter function</param>
152  public ConstituentsUniverse(Symbol symbol, UniverseSettings universeSettings, PyObject filterFunc)
153  : base(symbol, universeSettings, filterFunc)
154  {
155  }
156  }
157 }