Lean  $LEAN_TAG$
ETFConstituentsUniverseSelectionModel.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 Python.Runtime;
18 using System.Collections.Generic;
20 
22 {
23  /// <summary>
24  /// Universe selection model that selects the constituents of an ETF.
25  /// </summary>
27  {
28  private readonly Symbol _etfSymbol;
29  private readonly UniverseSettings _universeSettings;
30  private readonly Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> _universeFilterFunc;
31  private Universe _universe;
32 
33  /// <summary>
34  /// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
35  /// </summary>
36  /// <param name="etfSymbol">Symbol of the ETF to get constituents for</param>
37  /// <param name="universeSettings">Universe settings</param>
38  /// <param name="universeFilterFunc">Function to filter universe results</param>
40  Symbol etfSymbol,
41  UniverseSettings universeSettings,
42  Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
43  {
44  _etfSymbol = etfSymbol;
45  _universeSettings = universeSettings;
46  _universeFilterFunc = universeFilterFunc;
47  }
48 
49  /// <summary>
50  /// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
51  /// </summary>
52  /// <param name="etfSymbol">Symbol of the ETF to get constituents for</param>
53  /// <param name="universeFilterFunc">Function to filter universe results</param>
55  Symbol etfSymbol,
56  Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
57  : this(etfSymbol, null, universeFilterFunc)
58  { }
59 
60  /// <summary>
61  /// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
62  /// </summary>
63  /// <param name="etfSymbol">Symbol of the ETF to get constituents for</param>
64  /// <param name="universeSettings">Universe settings</param>
65  /// <param name="universeFilterFunc">Function to filter universe results</param>
67  Symbol etfSymbol,
68  UniverseSettings universeSettings = null,
69  PyObject universeFilterFunc = null) :
70  this(etfSymbol, universeSettings, universeFilterFunc.ConvertPythonUniverseFilterFunction<ETFConstituentUniverse>())
71  { }
72 
73  /// <summary>
74  /// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
75  /// </summary>
76  /// <param name="etfTicker">The string ETF ticker symbol</param>
77  /// <param name="universeSettings">Universe settings</param>
78  /// <param name="universeFilterFunc">Function to filter universe results</param>
80  string etfTicker,
81  UniverseSettings universeSettings,
82  Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
83  {
84  _etfSymbol = SymbolCache.TryGetSymbol(etfTicker, out var symbol)
85  && symbol.SecurityType == SecurityType.Equity
86  ? symbol : Symbol.Create(etfTicker, SecurityType.Equity, Market.USA);
87 
88  _universeSettings = universeSettings;
89  _universeFilterFunc = universeFilterFunc;
90  }
91 
92  /// <summary>
93  /// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
94  /// </summary>
95  /// <param name="etfTicker">The string ETF ticker symbol</param>
96  /// <param name="universeFilterFunc">Function to filter universe results</param>
98  string etfTicker,
99  Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
100  : this(etfTicker, null, universeFilterFunc)
101  { }
102 
103 
104  /// <summary>
105  /// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
106  /// </summary>
107  /// <param name="etfTicker">The string ETF ticker symbol</param>
108  /// <param name="universeSettings">Universe settings</param>
109  /// <param name="universeFilterFunc">Function to filter universe results</param>
111  string etfTicker,
112  UniverseSettings universeSettings = null,
113  PyObject universeFilterFunc = null) :
114  this(etfTicker, universeSettings, universeFilterFunc.ConvertPythonUniverseFilterFunction<ETFConstituentUniverse>())
115  { }
116 
117  /// <summary>
118  /// Creates a new ETF constituents universe using this class's selection function
119  /// </summary>
120  /// <param name="algorithm">The algorithm instance to create universes for</param>
121  /// <returns>The universe defined by this model</returns>
122  public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm)
123  {
124  _universe ??= algorithm?.Universe.ETF(_etfSymbol, _universeSettings, _universeFilterFunc);
125  return new[] { _universe };
126  }
127  }
128 }