Lean  $LEAN_TAG$
ETFConstituentsUniverseFactory.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  /// Creates a universe based on an ETF's holdings at a given date
25  /// </summary>
26  public class ETFConstituentsUniverseFactory : ConstituentsUniverse<ETFConstituentUniverse>
27  {
28  private const string _etfConstituentsUniverseIdentifier = "qc-universe-etf-constituents";
29 
30  /// <summary>
31  /// Creates a new universe for the constituents of the ETF provided as <paramref name="symbol"/>
32  /// </summary>
33  /// <param name="symbol">The ETF to load constituents for</param>
34  /// <param name="universeSettings">Universe settings</param>
35  /// <param name="constituentsFilter">The filter function used to filter out ETF constituents from the universe</param>
36  public ETFConstituentsUniverseFactory(Symbol symbol, UniverseSettings universeSettings, Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> constituentsFilter = null)
37  : base(CreateConstituentUniverseETFSymbol(symbol), universeSettings, constituentsFilter ?? (constituents => constituents.Select(c => c.Symbol)))
38  {
39  }
40 
41  /// <summary>
42  /// Creates a new universe for the constituents of the ETF provided as <paramref name="symbol"/>
43  /// </summary>
44  /// <param name="symbol">The ETF to load constituents for</param>
45  /// <param name="universeSettings">Universe settings</param>
46  /// <param name="constituentsFilter">The filter function used to filter out ETF constituents from the universe</param>
47  public ETFConstituentsUniverseFactory(Symbol symbol, UniverseSettings universeSettings, PyObject constituentsFilter)
48  : this(symbol, universeSettings, constituentsFilter.ConvertPythonUniverseFilterFunction<ETFConstituentUniverse>())
49  {
50  }
51 
52  /// <summary>
53  /// Creates a universe Symbol for constituent ETFs
54  /// </summary>
55  /// <param name="compositeSymbol">The Symbol of the ETF</param>
56  /// <returns>Universe Symbol with ETF set as underlying</returns>
57  private static Symbol CreateConstituentUniverseETFSymbol(Symbol compositeSymbol)
58  {
59  var guid = Guid.NewGuid().ToString();
60  var universeTicker = _etfConstituentsUniverseIdentifier + '-' + guid;
61 
62  return new Symbol(
64  universeTicker,
65  compositeSymbol.SecurityType,
66  compositeSymbol.ID.Market),
67  universeTicker,
68  compositeSymbol);
69  }
70  }
71 }