chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Portfolio selection model that uses coarse selectors. For US equities only.
|
||||
/// </summary>
|
||||
public class CoarseFundamentalUniverseSelectionModel : FundamentalUniverseSelectionModel
|
||||
{
|
||||
private readonly Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> _coarseSelector;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoarseFundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="coarseSelector">Selects symbols from the provided coarse data set</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public CoarseFundamentalUniverseSelectionModel(
|
||||
Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> coarseSelector,
|
||||
UniverseSettings universeSettings = null
|
||||
)
|
||||
: base(false, universeSettings)
|
||||
{
|
||||
_coarseSelector = coarseSelector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CoarseFundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="coarseSelector">Selects symbols from the provided coarse data set</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public CoarseFundamentalUniverseSelectionModel(
|
||||
PyObject coarseSelector,
|
||||
UniverseSettings universeSettings = null
|
||||
)
|
||||
: base(false, universeSettings)
|
||||
{
|
||||
if (coarseSelector.TrySafeAs<Func<IEnumerable<CoarseFundamental>, object>>(out var func))
|
||||
{
|
||||
_coarseSelector = func.ConvertToUniverseSelectionSymbolDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectCoarse), out IEnumerable<Symbol> result, algorithm, coarse))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return _coarseSelector(coarse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Python.Runtime;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe selection model that selects the constituents of an ETF.
|
||||
/// </summary>
|
||||
public class ETFConstituentsUniverseSelectionModel : UniverseSelectionModel
|
||||
{
|
||||
private readonly Symbol _etfSymbol;
|
||||
private readonly UniverseSettings _universeSettings;
|
||||
private readonly Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> _universeFilterFunc;
|
||||
private Universe _universe;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="etfSymbol">Symbol of the ETF to get constituents for</param>
|
||||
/// <param name="universeSettings">Universe settings</param>
|
||||
/// <param name="universeFilterFunc">Function to filter universe results</param>
|
||||
public ETFConstituentsUniverseSelectionModel(
|
||||
Symbol etfSymbol,
|
||||
UniverseSettings universeSettings,
|
||||
Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
|
||||
{
|
||||
_etfSymbol = etfSymbol;
|
||||
_universeSettings = universeSettings;
|
||||
_universeFilterFunc = universeFilterFunc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="etfSymbol">Symbol of the ETF to get constituents for</param>
|
||||
/// <param name="universeFilterFunc">Function to filter universe results</param>
|
||||
public ETFConstituentsUniverseSelectionModel(
|
||||
Symbol etfSymbol,
|
||||
Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
|
||||
: this(etfSymbol, null, universeFilterFunc)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="etfSymbol">Symbol of the ETF to get constituents for</param>
|
||||
/// <param name="universeSettings">Universe settings</param>
|
||||
/// <param name="universeFilterFunc">Function to filter universe results</param>
|
||||
public ETFConstituentsUniverseSelectionModel(
|
||||
Symbol etfSymbol,
|
||||
UniverseSettings universeSettings = null,
|
||||
PyObject universeFilterFunc = null) :
|
||||
this(etfSymbol, universeSettings, universeFilterFunc.ConvertPythonUniverseFilterFunction<ETFConstituentUniverse>())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="etfTicker">The string ETF ticker symbol</param>
|
||||
/// <param name="universeSettings">Universe settings</param>
|
||||
/// <param name="universeFilterFunc">Function to filter universe results</param>
|
||||
public ETFConstituentsUniverseSelectionModel(
|
||||
string etfTicker,
|
||||
UniverseSettings universeSettings,
|
||||
Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
|
||||
{
|
||||
_etfSymbol = SymbolCache.TryGetSymbol(etfTicker, out var symbol)
|
||||
&& symbol.SecurityType == SecurityType.Equity
|
||||
? symbol : Symbol.Create(etfTicker, SecurityType.Equity, Market.USA);
|
||||
|
||||
_universeSettings = universeSettings;
|
||||
_universeFilterFunc = universeFilterFunc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="etfTicker">The string ETF ticker symbol</param>
|
||||
/// <param name="universeFilterFunc">Function to filter universe results</param>
|
||||
public ETFConstituentsUniverseSelectionModel(
|
||||
string etfTicker,
|
||||
Func<IEnumerable<ETFConstituentUniverse>, IEnumerable<Symbol>> universeFilterFunc)
|
||||
: this(etfTicker, null, universeFilterFunc)
|
||||
{ }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ETFConstituentsUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="etfTicker">The string ETF ticker symbol</param>
|
||||
/// <param name="universeSettings">Universe settings</param>
|
||||
/// <param name="universeFilterFunc">Function to filter universe results</param>
|
||||
public ETFConstituentsUniverseSelectionModel(
|
||||
string etfTicker,
|
||||
UniverseSettings universeSettings = null,
|
||||
PyObject universeFilterFunc = null) :
|
||||
this(etfTicker, universeSettings, universeFilterFunc.ConvertPythonUniverseFilterFunction<ETFConstituentUniverse>())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new ETF constituents universe using this class's selection function
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance to create universes for</param>
|
||||
/// <returns>The universe defined by this model</returns>
|
||||
public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm)
|
||||
{
|
||||
_universe ??= algorithm?.Universe.ETF(_etfSymbol, _universeSettings, _universeFilterFunc);
|
||||
return new[] { _universe };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from AlgorithmImports import *
|
||||
from Selection.UniverseSelectionModel import UniverseSelectionModel
|
||||
|
||||
class ETFConstituentsUniverseSelectionModel(UniverseSelectionModel):
|
||||
'''Universe selection model that selects the constituents of an ETF.'''
|
||||
|
||||
def __init__(self,
|
||||
etf_symbol,
|
||||
universe_settings = None,
|
||||
universe_filter_func = None):
|
||||
'''Initializes a new instance of the ETFConstituentsUniverseSelectionModel class
|
||||
Args:
|
||||
etfSymbol: Symbol of the ETF to get constituents for
|
||||
universeSettings: Universe settings
|
||||
universeFilterFunc: Function to filter universe results'''
|
||||
if type(etf_symbol) is str:
|
||||
symbol = SymbolCache.try_get_symbol(etf_symbol, None)
|
||||
if symbol[0] and symbol[1].security_type == SecurityType.EQUITY:
|
||||
self.etf_symbol = symbol[1]
|
||||
else:
|
||||
self.etf_symbol = Symbol.create(etf_symbol, SecurityType.EQUITY, Market.USA)
|
||||
else:
|
||||
self.etf_symbol = etf_symbol
|
||||
self.universe_settings = universe_settings
|
||||
self.universe_filter_function = universe_filter_func
|
||||
|
||||
self.universe = None
|
||||
|
||||
def create_universes(self, algorithm: QCAlgorithm) -> list[Universe]:
|
||||
'''Creates a new ETF constituents universe using this class's selection function
|
||||
Args:
|
||||
algorithm: The algorithm instance to create universes for
|
||||
Returns:
|
||||
The universe defined by this model'''
|
||||
if self.universe is None:
|
||||
self.universe = algorithm.universe.etf(self.etf_symbol, self.universe_settings, self.universe_filter_function)
|
||||
return [self.universe]
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Indicators;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an implementation of <see cref="FundamentalUniverseSelectionModel"/> that subscribes
|
||||
/// to symbols with the larger delta by percentage between the two exponential moving average
|
||||
/// </summary>
|
||||
public class EmaCrossUniverseSelectionModel : FundamentalUniverseSelectionModel
|
||||
{
|
||||
private const decimal _tolerance = 0.01m;
|
||||
private readonly int _fastPeriod;
|
||||
private readonly int _slowPeriod;
|
||||
private readonly int _universeCount;
|
||||
|
||||
// holds our coarse fundamental indicators by symbol
|
||||
private readonly ConcurrentDictionary<Symbol, SelectionData> _averages;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EmaCrossUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="fastPeriod">Fast EMA period</param>
|
||||
/// <param name="slowPeriod">Slow EMA period</param>
|
||||
/// <param name="universeCount">Maximum number of members of this universe selection</param>
|
||||
/// <param name="universeSettings">The settings used when adding symbols to the algorithm, specify null to use algorithm.UniverseSettings</param>
|
||||
public EmaCrossUniverseSelectionModel(
|
||||
int fastPeriod = 100,
|
||||
int slowPeriod = 300,
|
||||
int universeCount = 500,
|
||||
UniverseSettings universeSettings = null)
|
||||
: base(false, universeSettings)
|
||||
{
|
||||
_fastPeriod = fastPeriod;
|
||||
_slowPeriod = slowPeriod;
|
||||
_universeCount = universeCount;
|
||||
_averages = new ConcurrentDictionary<Symbol, SelectionData>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the coarse fundamental selection function.
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance</param>
|
||||
/// <param name="coarse">The coarse fundamental data used to perform filtering</param>
|
||||
/// <returns>An enumerable of symbols passing the filter</returns>
|
||||
public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectCoarse), out IEnumerable<Symbol> result, algorithm, coarse))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return (from cf in coarse
|
||||
// grab th SelectionData instance for this symbol
|
||||
let avg = _averages.GetOrAdd(cf.Symbol, sym => new SelectionData(_fastPeriod, _slowPeriod))
|
||||
// Update returns true when the indicators are ready, so don't accept until they are
|
||||
where avg.Update(cf.EndTime, cf.AdjustedPrice)
|
||||
// only pick symbols who have their _fastPeriod-day ema over their _slowPeriod-day ema
|
||||
where avg.Fast > avg.Slow * (1 + _tolerance)
|
||||
// prefer symbols with a larger delta by percentage between the two averages
|
||||
orderby avg.ScaledDelta descending
|
||||
// we only need to return the symbol and return 'Count' symbols
|
||||
select cf.Symbol).Take(_universeCount);
|
||||
}
|
||||
|
||||
// class used to improve readability of the coarse selection function
|
||||
private class SelectionData
|
||||
{
|
||||
public readonly ExponentialMovingAverage Fast;
|
||||
public readonly ExponentialMovingAverage Slow;
|
||||
|
||||
public SelectionData(int fastPeriod, int slowPeriod)
|
||||
{
|
||||
Fast = new ExponentialMovingAverage(fastPeriod);
|
||||
Slow = new ExponentialMovingAverage(slowPeriod);
|
||||
}
|
||||
|
||||
// computes an object score of how much large the fast is than the slow
|
||||
public decimal ScaledDelta => (Fast - Slow) / ((Fast + Slow) / 2m);
|
||||
|
||||
// updates the EMAFast and EMASlow indicators, returning true when they're both ready
|
||||
public bool Update(DateTime time, decimal value) => Fast.Update(time, value) & Slow.Update(time, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from AlgorithmImports import *
|
||||
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
|
||||
|
||||
class EmaCrossUniverseSelectionModel(FundamentalUniverseSelectionModel):
|
||||
'''Provides an implementation of FundamentalUniverseSelectionModel that subscribes to
|
||||
symbols with the larger delta by percentage between the two exponential moving average'''
|
||||
|
||||
def __init__(self,
|
||||
fastPeriod = 100,
|
||||
slowPeriod = 300,
|
||||
universeCount = 500,
|
||||
universeSettings = None):
|
||||
'''Initializes a new instance of the EmaCrossUniverseSelectionModel class
|
||||
Args:
|
||||
fastPeriod: Fast EMA period
|
||||
slowPeriod: Slow EMA period
|
||||
universeCount: Maximum number of members of this universe selection
|
||||
universeSettings: The settings used when adding symbols to the algorithm, specify null to use algorithm.UniverseSettings'''
|
||||
super().__init__(False, universeSettings)
|
||||
self.fast_period = fastPeriod
|
||||
self.slow_period = slowPeriod
|
||||
self.universe_count = universeCount
|
||||
self.tolerance = 0.01
|
||||
# holds our coarse fundamental indicators by symbol
|
||||
self.averages = {}
|
||||
|
||||
def select_coarse(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]) -> list[Symbol]:
|
||||
'''Defines the coarse fundamental selection function.
|
||||
Args:
|
||||
algorithm: The algorithm instance
|
||||
fundamental: The coarse fundamental data used to perform filtering</param>
|
||||
Returns:
|
||||
An enumerable of symbols passing the filter'''
|
||||
filtered = []
|
||||
|
||||
for cf in fundamental:
|
||||
if cf.symbol not in self.averages:
|
||||
self.averages[cf.symbol] = self.SelectionData(cf.symbol, self.fast_period, self.slow_period)
|
||||
|
||||
# grab th SelectionData instance for this symbol
|
||||
avg = self.averages.get(cf.symbol)
|
||||
|
||||
# Update returns true when the indicators are ready, so don't accept until they are
|
||||
# and only pick symbols who have their fastPeriod-day ema over their slowPeriod-day ema
|
||||
if avg.update(cf.end_time, cf.adjusted_price) and avg.fast > avg.slow * (1 + self.tolerance):
|
||||
filtered.append(avg)
|
||||
|
||||
# prefer symbols with a larger delta by percentage between the two averages
|
||||
filtered = sorted(filtered, key=lambda avg: avg.scaled_delta, reverse = True)
|
||||
|
||||
# we only need to return the symbol and return 'universeCount' symbols
|
||||
return [x.symbol for x in filtered[:self.universe_count]]
|
||||
|
||||
# class used to improve readability of the coarse selection function
|
||||
class SelectionData:
|
||||
def __init__(self, symbol, fast_period, slow_period):
|
||||
self.symbol = symbol
|
||||
self.fast_ema = ExponentialMovingAverage(fast_period)
|
||||
self.slow_ema = ExponentialMovingAverage(slow_period)
|
||||
|
||||
@property
|
||||
def fast(self):
|
||||
return float(self.fast_ema.current.value)
|
||||
|
||||
@property
|
||||
def slow(self):
|
||||
return float(self.slow_ema.current.value)
|
||||
|
||||
# computes an object score of how much large the fast is than the slow
|
||||
@property
|
||||
def scaled_delta(self):
|
||||
return (self.fast - self.slow) / ((self.fast + self.slow) / 2)
|
||||
|
||||
# updates the EMAFast and EMASlow indicators, returning true when they're both ready
|
||||
def update(self, time, value):
|
||||
return self.slow_ema.update(time, value) & self.fast_ema.update(time, value)
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following Energy ETFs at their inception date
|
||||
/// 1998-12-22 XLE Energy Select Sector SPDR Fund
|
||||
/// 2000-06-16 IYE iShares U.S. Energy ETF
|
||||
/// 2004-09-29 VDE Vanguard Energy ETF
|
||||
/// 2006-04-10 USO United States Oil Fund
|
||||
/// 2006-06-22 XES SPDR S&P Oil & Gas Equipment & Services ETF
|
||||
/// 2006-06-22 XOP SPDR S&P Oil & Gas Exploration & Production ETF
|
||||
/// 2007-04-18 UNG United States Natural Gas Fund
|
||||
/// 2008-06-25 ICLN iShares Global Clean Energy ETF
|
||||
/// 2008-11-06 ERX Direxion Daily Energy Bull 3X Shares
|
||||
/// 2008-11-06 ERY Direxion Daily Energy Bear 3x Shares
|
||||
/// 2008-11-25 SCO ProShares UltraShort Bloomberg Crude Oil
|
||||
/// 2008-11-25 UCO ProShares Ultra Bloomberg Crude Oil
|
||||
/// 2009-06-02 AMJ JPMorgan Alerian MLP Index ETN
|
||||
/// 2010-06-02 BNO United States Brent Oil Fund
|
||||
/// 2010-08-25 AMLP Alerian MLP ETF
|
||||
/// 2011-12-21 OIH VanEck Vectors Oil Services ETF
|
||||
/// 2012-02-08 DGAZ VelocityShares 3x Inverse Natural Gas
|
||||
/// 2012-02-08 UGAZ VelocityShares 3x Long Natural Gas
|
||||
/// 2012-02-15 TAN Invesco Solar ETF
|
||||
/// </summary>
|
||||
public class EnergyETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the EnergyETFUniverse class
|
||||
/// </summary>
|
||||
public EnergyETFUniverse() :
|
||||
base(
|
||||
"qc-energy-etf-basket",
|
||||
new Dictionary<string, DateTime>()
|
||||
{
|
||||
{"XLE", new DateTime(1998, 12, 22)},
|
||||
{"IYE", new DateTime(2000, 6, 16)},
|
||||
{"VDE", new DateTime(2004, 9, 29)},
|
||||
{"USO", new DateTime(2006, 4, 10)},
|
||||
{"XES", new DateTime(2006, 6, 22)},
|
||||
{"XOP", new DateTime(2006, 6, 22)},
|
||||
{"UNG", new DateTime(2007, 4, 18)},
|
||||
{"ICLN", new DateTime(2008, 6, 25)},
|
||||
{"ERX", new DateTime(2008, 11, 6)},
|
||||
{"ERY", new DateTime(2008, 11, 6)},
|
||||
{"SCO", new DateTime(2008, 11, 25)},
|
||||
{"UCO", new DateTime(2008, 11, 25)},
|
||||
{"AMJ", new DateTime(2009, 6, 2)},
|
||||
{"BNO", new DateTime(2010, 6, 2)},
|
||||
{"AMLP", new DateTime(2010, 8, 25)},
|
||||
{"OIH", new DateTime(2011, 12, 21)},
|
||||
{"DGAZ", new DateTime(2012, 2, 8)},
|
||||
{"UGAZ", new DateTime(2012, 2, 8)},
|
||||
{"TAN", new DateTime(2012, 2, 15)}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Data.Fundamental;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Portfolio selection model that uses coarse/fine selectors. For US equities only.
|
||||
/// </summary>
|
||||
public class FineFundamentalUniverseSelectionModel : FundamentalUniverseSelectionModel
|
||||
{
|
||||
private readonly Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> _coarseSelector;
|
||||
private readonly Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>> _fineSelector;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FineFundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="coarseSelector">Selects symbols from the provided coarse data set</param>
|
||||
/// <param name="fineSelector">Selects symbols from the provided fine data set (this set has already been filtered according to the coarse selection)</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FineFundamentalUniverseSelectionModel(
|
||||
Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> coarseSelector,
|
||||
Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>> fineSelector,
|
||||
UniverseSettings universeSettings = null)
|
||||
: base(true, universeSettings)
|
||||
{
|
||||
_coarseSelector = coarseSelector;
|
||||
_fineSelector = fineSelector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FineFundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="coarseSelector">Selects symbols from the provided coarse data set</param>
|
||||
/// <param name="fineSelector">Selects symbols from the provided fine data set (this set has already been filtered according to the coarse selection)</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FineFundamentalUniverseSelectionModel(
|
||||
PyObject coarseSelector,
|
||||
PyObject fineSelector,
|
||||
UniverseSettings universeSettings = null
|
||||
)
|
||||
: base(true, universeSettings)
|
||||
{
|
||||
Func<IEnumerable<FineFundamental>, object> fineFunc;
|
||||
Func<IEnumerable<CoarseFundamental>, object> coarseFunc;
|
||||
if (fineSelector.TrySafeAs(out fineFunc) &&
|
||||
coarseSelector.TrySafeAs(out coarseFunc))
|
||||
{
|
||||
_fineSelector = fineFunc.ConvertToUniverseSelectionSymbolDelegate();
|
||||
_coarseSelector = coarseFunc.ConvertToUniverseSelectionSymbolDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectCoarse), out IEnumerable<Symbol> result, algorithm, coarse))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return _coarseSelector(coarse);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectFine), out IEnumerable<Symbol> result, algorithm, fine))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return _fineSelector(fine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Securities;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data.Fundamental;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for defining equity coarse/fine fundamental selection models
|
||||
/// </summary>
|
||||
public class FundamentalUniverseSelectionModel : UniverseSelectionModel
|
||||
{
|
||||
private readonly string _market;
|
||||
private readonly bool _fundamentalData;
|
||||
private readonly bool _filterFineData;
|
||||
private readonly UniverseSettings _universeSettings;
|
||||
private readonly Func<IEnumerable<Fundamental>, IEnumerable<Symbol>> _selector;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
public FundamentalUniverseSelectionModel()
|
||||
: this(Market.USA, null)
|
||||
{
|
||||
_fundamentalData = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="market">The target market</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FundamentalUniverseSelectionModel(string market, UniverseSettings universeSettings)
|
||||
{
|
||||
_market = market;
|
||||
_fundamentalData = true;
|
||||
_universeSettings = universeSettings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FundamentalUniverseSelectionModel(UniverseSettings universeSettings)
|
||||
: this(Market.USA, universeSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="market">The target market</param>
|
||||
/// <param name="selector">Selects symbols from the provided fundamental data set</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FundamentalUniverseSelectionModel(string market, Func<IEnumerable<Fundamental>, IEnumerable<Symbol>> selector, UniverseSettings universeSettings = null)
|
||||
{
|
||||
_market = market;
|
||||
_selector = selector;
|
||||
_fundamentalData = true;
|
||||
_universeSettings = universeSettings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="selector">Selects symbols from the provided fundamental data set</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FundamentalUniverseSelectionModel(Func<IEnumerable<Fundamental>, IEnumerable<Symbol>> selector, UniverseSettings universeSettings = null)
|
||||
: this(Market.USA, selector, universeSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="market">The target market</param>
|
||||
/// <param name="selector">Selects symbols from the provided fundamental data set</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FundamentalUniverseSelectionModel(string market, PyObject selector, UniverseSettings universeSettings = null) : this(universeSettings)
|
||||
{
|
||||
_market = market;
|
||||
Func<IEnumerable<Fundamental>, object> selectorFunc;
|
||||
if (selector.TrySafeAs(out selectorFunc))
|
||||
{
|
||||
_selector = selectorFunc.ConvertToUniverseSelectionSymbolDelegate();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="selector">Selects symbols from the provided fundamental data set</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FundamentalUniverseSelectionModel(PyObject selector, UniverseSettings universeSettings = null)
|
||||
: this(Market.USA, selector, universeSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="filterFineData">True to also filter using fine fundamental data, false to only filter on coarse data</param>
|
||||
[Obsolete("Fine and Coarse selection are merged, please use 'FundamentalUniverseSelectionModel()'")]
|
||||
protected FundamentalUniverseSelectionModel(bool filterFineData)
|
||||
: this(filterFineData, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FundamentalUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="filterFineData">True to also filter using fine fundamental data, false to only filter on coarse data</param>
|
||||
/// <param name="universeSettings">The settings used when adding symbols to the algorithm, specify null to use algorithm.UniverseSettings</param>
|
||||
[Obsolete("Fine and Coarse selection are merged, please use 'FundamentalUniverseSelectionModel(UniverseSettings)'")]
|
||||
protected FundamentalUniverseSelectionModel(bool filterFineData, UniverseSettings universeSettings)
|
||||
{
|
||||
_market = Market.USA;
|
||||
_filterFineData = filterFineData;
|
||||
_universeSettings = universeSettings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new fundamental universe using this class's selection functions
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance to create universes for</param>
|
||||
/// <returns>The universe defined by this model</returns>
|
||||
public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm)
|
||||
{
|
||||
if (_fundamentalData)
|
||||
{
|
||||
var universeSettings = _universeSettings ?? algorithm.UniverseSettings;
|
||||
yield return new FundamentalUniverseFactory(_market, universeSettings, fundamental => Select(algorithm, fundamental));
|
||||
}
|
||||
else
|
||||
{
|
||||
// for backwards compatibility
|
||||
var universe = CreateCoarseFundamentalUniverse(algorithm);
|
||||
if (_filterFineData)
|
||||
{
|
||||
if (universe.UniverseSettings.Asynchronous.HasValue && universe.UniverseSettings.Asynchronous.Value)
|
||||
{
|
||||
throw new ArgumentException("Asynchronous universe setting is not supported for coarse & fine selections, please use the new Fundamental single pass selection");
|
||||
}
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
universe = new FineFundamentalFilteredUniverse(universe, fine => SelectFine(algorithm, fine));
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
yield return universe;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the coarse fundamental universe object.
|
||||
/// This is provided to allow more flexibility when creating coarse universe.
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance</param>
|
||||
/// <returns>The coarse fundamental universe</returns>
|
||||
public virtual Universe CreateCoarseFundamentalUniverse(QCAlgorithm algorithm)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(CreateCoarseFundamentalUniverse), out Universe result, algorithm))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var universeSettings = _universeSettings ?? algorithm.UniverseSettings;
|
||||
return new CoarseFundamentalUniverse(universeSettings, coarse =>
|
||||
{
|
||||
// if we're using fine fundamental selection than exclude symbols without fine data
|
||||
if (_filterFineData)
|
||||
{
|
||||
coarse = coarse.Where(c => c.HasFundamentalData);
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
return SelectCoarse(algorithm, coarse);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the fundamental selection function.
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance</param>
|
||||
/// <param name="fundamental">The fundamental data used to perform filtering</param>
|
||||
/// <returns>An enumerable of symbols passing the filter</returns>
|
||||
public virtual IEnumerable<Symbol> Select(QCAlgorithm algorithm, IEnumerable<Fundamental> fundamental)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(Select), out IEnumerable<Symbol> result, algorithm, fundamental))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (_selector == null)
|
||||
{
|
||||
throw new NotImplementedException("If inheriting, please override the 'Select' fundamental function, else provide it as a constructor parameter");
|
||||
}
|
||||
return _selector(fundamental);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the coarse fundamental selection function.
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance</param>
|
||||
/// <param name="coarse">The coarse fundamental data used to perform filtering</param>
|
||||
/// <returns>An enumerable of symbols passing the filter</returns>
|
||||
[Obsolete("Fine and Coarse selection are merged, please use 'Select(QCAlgorithm, IEnumerable<Fundamental>)'")]
|
||||
public virtual IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectCoarse), out IEnumerable<Symbol> result, algorithm, coarse))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new NotImplementedException("Please override the 'Select' fundamental function");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the fine fundamental selection function.
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance</param>
|
||||
/// <param name="fine">The fine fundamental data used to perform filtering</param>
|
||||
/// <returns>An enumerable of symbols passing the filter</returns>
|
||||
[Obsolete("Fine and Coarse selection are merged, please use 'Select(QCAlgorithm, IEnumerable<Fundamental>)'")]
|
||||
public virtual IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectFine), out IEnumerable<Symbol> result, algorithm, fine))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// default impl performs no filtering of fine data
|
||||
return fine.Select(f => f.Symbol);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method for creating a selection model that uses only coarse data
|
||||
/// </summary>
|
||||
/// <param name="coarseSelector">Selects symbols from the provided coarse data set</param>
|
||||
/// <returns>A new universe selection model that will select US equities according to the selection function specified</returns>
|
||||
[Obsolete("Fine and Coarse selection are merged, please use 'Fundamental(Func<IEnumerable<Fundamental>, IEnumerable<Symbol>>)'")]
|
||||
public static IUniverseSelectionModel Coarse(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> coarseSelector)
|
||||
{
|
||||
return new CoarseFundamentalUniverseSelectionModel(coarseSelector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method for creating a selection model that uses coarse and fine data
|
||||
/// </summary>
|
||||
/// <param name="coarseSelector">Selects symbols from the provided coarse data set</param>
|
||||
/// <param name="fineSelector">Selects symbols from the provided fine data set (this set has already been filtered according to the coarse selection)</param>
|
||||
/// <returns>A new universe selection model that will select US equities according to the selection functions specified</returns>
|
||||
[Obsolete("Fine and Coarse selection are merged, please use 'Fundamental(Func<IEnumerable<Fundamental>, IEnumerable<Symbol>>)'")]
|
||||
public static IUniverseSelectionModel Fine(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>> coarseSelector, Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>> fineSelector)
|
||||
{
|
||||
return new FineFundamentalUniverseSelectionModel(coarseSelector, fineSelector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convenience method for creating a selection model that uses fundamental data
|
||||
/// </summary>
|
||||
/// <param name="selector">Selects symbols from the provided fundamental data set</param>
|
||||
/// <returns>A new universe selection model that will select US equities according to the selection functions specified</returns>
|
||||
public static IUniverseSelectionModel Fundamental(Func<IEnumerable<Fundamental>, IEnumerable<Symbol>> selector)
|
||||
{
|
||||
return new FundamentalUniverseSelectionModel(selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from AlgorithmImports import *
|
||||
|
||||
class FundamentalUniverseSelectionModel:
|
||||
'''Provides a base class for defining equity coarse/fine fundamental selection models'''
|
||||
|
||||
def __init__(self,
|
||||
filter_fine_data = None,
|
||||
universe_settings = None):
|
||||
'''Initializes a new instance of the FundamentalUniverseSelectionModel class
|
||||
Args:
|
||||
filter_fine_data: [Obsolete] Fine and Coarse selection are merged
|
||||
universeSettings: The settings used when adding symbols to the algorithm, specify null to use algorithm.universe_settings'''
|
||||
self.filter_fine_data = filter_fine_data
|
||||
if self.filter_fine_data == None:
|
||||
self.fundamental_data = True
|
||||
else:
|
||||
self.fundamental_data = False
|
||||
self.market = Market.USA
|
||||
self.universe_settings = universe_settings
|
||||
|
||||
|
||||
def create_universes(self, algorithm: QCAlgorithm) -> list[Universe]:
|
||||
'''Creates a new fundamental universe using this class's selection functions
|
||||
Args:
|
||||
algorithm: The algorithm instance to create universes for
|
||||
Returns:
|
||||
The universe defined by this model'''
|
||||
if self.fundamental_data:
|
||||
universe_settings = algorithm.universe_settings if self.universe_settings is None else self.universe_settings
|
||||
# handle both 'Select' and 'select' for backwards compatibility
|
||||
selection = lambda fundamental: self.select(algorithm, fundamental)
|
||||
if hasattr(self, "Select") and callable(self.Select):
|
||||
selection = lambda fundamental: self.Select(algorithm, fundamental)
|
||||
universe = FundamentalUniverseFactory(self.market, universe_settings, selection)
|
||||
return [universe]
|
||||
else:
|
||||
universe = self.create_coarse_fundamental_universe(algorithm)
|
||||
if self.filter_fine_data:
|
||||
if universe.universe_settings.asynchronous:
|
||||
raise ValueError("Asynchronous universe setting is not supported for coarse & fine selections, please use the new Fundamental single pass selection")
|
||||
selection = lambda fine: self.select_fine(algorithm, fine)
|
||||
if hasattr(self, "SelectFine") and callable(self.SelectFine):
|
||||
selection = lambda fine: self.SelectFine(algorithm, fine)
|
||||
universe = FineFundamentalFilteredUniverse(universe, selection)
|
||||
return [universe]
|
||||
|
||||
|
||||
def create_coarse_fundamental_universe(self, algorithm: QCAlgorithm) -> Universe:
|
||||
'''Creates the coarse fundamental universe object.
|
||||
This is provided to allow more flexibility when creating coarse universe.
|
||||
Args:
|
||||
algorithm: The algorithm instance
|
||||
Returns:
|
||||
The coarse fundamental universe'''
|
||||
universe_settings = algorithm.universe_settings if self.universe_settings is None else self.universe_settings
|
||||
return CoarseFundamentalUniverse(universe_settings, lambda coarse: self.filtered_select_coarse(algorithm, coarse))
|
||||
|
||||
|
||||
def filtered_select_coarse(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]) -> list[Symbol]:
|
||||
'''Defines the coarse fundamental selection function.
|
||||
If we're using fine fundamental selection than exclude symbols without fine data
|
||||
Args:
|
||||
algorithm: The algorithm instance
|
||||
coarse: The coarse fundamental data used to perform filtering
|
||||
Returns:
|
||||
An enumerable of symbols passing the filter'''
|
||||
if self.filter_fine_data:
|
||||
fundamental = filter(lambda c: c.has_fundamental_data, fundamental)
|
||||
if hasattr(self, "SelectCoarse") and callable(self.SelectCoarse):
|
||||
# handle both 'select_coarse' and 'SelectCoarse' for backwards compatibility
|
||||
return self.SelectCoarse(algorithm, fundamental)
|
||||
return self.select_coarse(algorithm, fundamental)
|
||||
|
||||
|
||||
def select(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]) -> list[Symbol]:
|
||||
'''Defines the fundamental selection function.
|
||||
Args:
|
||||
algorithm: The algorithm instance
|
||||
fundamental: The fundamental data used to perform filtering
|
||||
Returns:
|
||||
An enumerable of symbols passing the filter'''
|
||||
raise NotImplementedError("Please overrride the 'select' fundamental function")
|
||||
|
||||
|
||||
def select_coarse(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]) -> list[Symbol]:
|
||||
'''Defines the coarse fundamental selection function.
|
||||
Args:
|
||||
algorithm: The algorithm instance
|
||||
coarse: The coarse fundamental data used to perform filtering
|
||||
Returns:
|
||||
An enumerable of symbols passing the filter'''
|
||||
raise NotImplementedError("Please overrride the 'select' fundamental function")
|
||||
|
||||
|
||||
def select_fine(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]) -> list[Symbol]:
|
||||
'''Defines the fine fundamental selection function.
|
||||
Args:
|
||||
algorithm: The algorithm instance
|
||||
fine: The fine fundamental data used to perform filtering
|
||||
Returns:
|
||||
An enumerable of symbols passing the filter'''
|
||||
return [f.symbol for f in fundamental]
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
using System.Collections.Generic;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using Python.Runtime;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an implementation of <see cref="IUniverseSelectionModel"/> that subscribes to future chains
|
||||
/// </summary>
|
||||
public class FutureUniverseSelectionModel : UniverseSelectionModel
|
||||
{
|
||||
private DateTime _nextRefreshTimeUtc;
|
||||
private readonly TimeSpan _refreshInterval;
|
||||
private readonly UniverseSettings _universeSettings;
|
||||
private readonly Func<DateTime, IEnumerable<Symbol>> _futureChainSymbolSelector;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes.
|
||||
/// </summary>
|
||||
public override DateTime GetNextRefreshTimeUtc() => _nextRefreshTimeUtc;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FutureUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>
|
||||
public FutureUniverseSelectionModel(TimeSpan refreshInterval, Func<DateTime, IEnumerable<Symbol>> futureChainSymbolSelector)
|
||||
: this(refreshInterval, futureChainSymbolSelector, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FutureUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>\
|
||||
public FutureUniverseSelectionModel(TimeSpan refreshInterval, PyObject futureChainSymbolSelector)
|
||||
: this(refreshInterval, futureChainSymbolSelector.SafeAs<Func<DateTime, IEnumerable<Symbol>>>(), null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FutureUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>\
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FutureUniverseSelectionModel(TimeSpan refreshInterval, PyObject futureChainSymbolSelector, UniverseSettings universeSettings)
|
||||
: this(refreshInterval, futureChainSymbolSelector.SafeAs<Func<DateTime, IEnumerable<Symbol>>>(), universeSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FutureUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FutureUniverseSelectionModel(
|
||||
TimeSpan refreshInterval,
|
||||
Func<DateTime, IEnumerable<Symbol>> futureChainSymbolSelector,
|
||||
UniverseSettings universeSettings
|
||||
)
|
||||
{
|
||||
_nextRefreshTimeUtc = DateTime.MinValue;
|
||||
|
||||
_refreshInterval = refreshInterval;
|
||||
_universeSettings = universeSettings;
|
||||
_futureChainSymbolSelector = futureChainSymbolSelector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the universes for this algorithm. Called once after <see cref="IAlgorithm.Initialize"/>
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance to create universes for</param>
|
||||
/// <returns>The universes to be used by the algorithm</returns>
|
||||
public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm)
|
||||
{
|
||||
_nextRefreshTimeUtc = algorithm.UtcTime + _refreshInterval;
|
||||
|
||||
var uniqueSymbols = new HashSet<Symbol>();
|
||||
foreach (var futureSymbol in _futureChainSymbolSelector(algorithm.UtcTime))
|
||||
{
|
||||
if (futureSymbol.SecurityType != SecurityType.Future)
|
||||
{
|
||||
throw new ArgumentException("FutureChainSymbolSelector must return future symbols.");
|
||||
}
|
||||
|
||||
// prevent creating duplicate future chains -- one per symbol
|
||||
if (uniqueSymbols.Add(futureSymbol))
|
||||
{
|
||||
foreach (var universe in algorithm.CreateFutureChain(futureSymbol, Filter, _universeSettings))
|
||||
{
|
||||
yield return universe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the future chain universe filter
|
||||
/// </summary>
|
||||
protected virtual FutureFilterUniverse Filter(FutureFilterUniverse filter)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(Filter), out FutureFilterUniverse result, filter))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
// NOP
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides an implementation of <see cref="IUniverseSelectionModel"/> that subscribes to future chains
|
||||
/// </summary>
|
||||
public class FuturesUniverseSelectionModel : FutureUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FutureUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>
|
||||
public FuturesUniverseSelectionModel(TimeSpan refreshInterval, Func<DateTime, IEnumerable<Symbol>> futureChainSymbolSelector)
|
||||
: base(refreshInterval, futureChainSymbolSelector)
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="FutureUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public FuturesUniverseSelectionModel(TimeSpan refreshInterval,
|
||||
Func<DateTime, IEnumerable<Symbol>> futureChainSymbolSelector,
|
||||
UniverseSettings universeSettings)
|
||||
: base(refreshInterval, futureChainSymbolSelector, universeSettings)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from AlgorithmImports import *
|
||||
|
||||
from Selection.UniverseSelectionModel import UniverseSelectionModel
|
||||
|
||||
class FutureUniverseSelectionModel(UniverseSelectionModel):
|
||||
'''Provides an implementation of IUniverseSelectionMode that subscribes to future chains'''
|
||||
def __init__(self,
|
||||
refreshInterval,
|
||||
futureChainSymbolSelector,
|
||||
universeSettings = None):
|
||||
'''Creates a new instance of FutureUniverseSelectionModel
|
||||
Args:
|
||||
refreshInterval: Time interval between universe refreshes</param>
|
||||
futureChainSymbolSelector: Selects symbols from the provided future chain
|
||||
universeSettings: Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed'''
|
||||
self.next_refresh_time_utc = datetime.min
|
||||
|
||||
self.refresh_interval = refreshInterval
|
||||
self.future_chain_symbol_selector = futureChainSymbolSelector
|
||||
self.universe_settings = universeSettings
|
||||
|
||||
def get_next_refresh_time_utc(self):
|
||||
'''Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes.'''
|
||||
return self.next_refresh_time_utc
|
||||
|
||||
def create_universes(self, algorithm: QCAlgorithm) -> list[Universe]:
|
||||
'''Creates a new fundamental universe using this class's selection functions
|
||||
Args:
|
||||
algorithm: The algorithm instance to create universes for
|
||||
Returns:
|
||||
The universe defined by this model'''
|
||||
self.next_refresh_time_utc = algorithm.utc_time + self.refresh_interval
|
||||
|
||||
unique_symbols = set()
|
||||
for future_symbol in self.future_chain_symbol_selector(algorithm.utc_time):
|
||||
if future_symbol.SecurityType != SecurityType.FUTURE:
|
||||
raise ValueError("futureChainSymbolSelector must return future symbols.")
|
||||
|
||||
# prevent creating duplicate future chains -- one per symbol
|
||||
if future_symbol not in unique_symbols:
|
||||
unique_symbols.add(future_symbol)
|
||||
selection = self.filter
|
||||
if hasattr(self, "Filter") and callable(self.Filter):
|
||||
selection = self.Filter
|
||||
for universe in Extensions.create_future_chain(algorithm, future_symbol, selection, self.universe_settings):
|
||||
yield universe
|
||||
|
||||
def filter(self, filter):
|
||||
'''Defines the future chain universe filter'''
|
||||
# NOP
|
||||
return filter
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Python.Runtime;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Inception Date Universe that accepts a Dictionary of DateTime keyed by String that represent
|
||||
/// the Inception date for each ticker
|
||||
/// </summary>
|
||||
public class InceptionDateUniverseSelectionModel : CustomUniverseSelectionModel
|
||||
{
|
||||
private readonly Queue<KeyValuePair<string, DateTime>> _queue;
|
||||
private readonly List<string> _symbols;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InceptionDateUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="name">A unique name for this universe</param>
|
||||
/// <param name="tickersByDate">Dictionary of DateTime keyed by String that represent the Inception date for each ticker</param>
|
||||
public InceptionDateUniverseSelectionModel(string name, Dictionary<string, DateTime> tickersByDate) :
|
||||
base(name, (Func<DateTime, IEnumerable<string>>)null)
|
||||
{
|
||||
_queue = new Queue<KeyValuePair<string, DateTime>>(tickersByDate);
|
||||
_symbols = new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="InceptionDateUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="name">A unique name for this universe</param>
|
||||
/// <param name="tickersByDate">Dictionary of DateTime keyed by String that represent the Inception date for each ticker</param>
|
||||
public InceptionDateUniverseSelectionModel(string name, PyObject tickersByDate) :
|
||||
this(name, tickersByDate.ConvertToDictionary<string, DateTime>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all tickers that are trading at current algorithm Time
|
||||
/// </summary>
|
||||
public override IEnumerable<string> Select(QCAlgorithm algorithm, DateTime date)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(Select), out IEnumerable<string> result, algorithm, date))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Move Symbols that are trading from the queue to a list
|
||||
var added = new List<string>();
|
||||
while (_queue.TryPeek(out var keyValuePair) && keyValuePair.Value <= date)
|
||||
{
|
||||
added.Add(_queue.Dequeue().Key);
|
||||
}
|
||||
|
||||
// If no pending for addition found, return Universe Unchanged
|
||||
// Otherwise adds to list of current tickers and return it
|
||||
if (added.Count == 0)
|
||||
{
|
||||
return Universe.Unchanged;
|
||||
}
|
||||
|
||||
_symbols.AddRange(added);
|
||||
return _symbols;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following ETFs at their inception date
|
||||
/// </summary>
|
||||
public class LiquidETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Energy ETF Category which can be used to access the list of Long and Inverse symbols
|
||||
/// </summary>
|
||||
public static readonly Grouping Energy = new Grouping(
|
||||
new[]
|
||||
{
|
||||
"VDE", "USO", "XES", "XOP", "UNG", "ICLN", "ERX",
|
||||
"UCO", "AMJ", "BNO", "AMLP", "UGAZ", "TAN"
|
||||
},
|
||||
new[] {"ERY", "SCO", "DGAZ" }
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the Metals ETF Category which can be used to access the list of Long and Inverse symbols
|
||||
/// </summary>
|
||||
public static readonly Grouping Metals = new Grouping(
|
||||
new[] {"GLD", "IAU", "SLV", "GDX", "AGQ", "PPLT", "NUGT", "USLV", "UGLD", "JNUG"},
|
||||
new[] {"DUST", "JDST"}
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the Technology ETF Category which can be used to access the list of Long and Inverse symbols
|
||||
/// </summary>
|
||||
public static readonly Grouping Technology = new Grouping(
|
||||
new[] {"QQQ", "IGV", "QTEC", "FDN", "FXL", "TECL", "SOXL", "SKYY", "KWEB"},
|
||||
new[] {"TECS", "SOXS"}
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the Treasuries ETF Category which can be used to access the list of Long and Inverse symbols
|
||||
/// </summary>
|
||||
public static readonly Grouping Treasuries = new Grouping(
|
||||
new[]
|
||||
{
|
||||
"IEF", "SHY", "TLT", "IEI", "TLH", "BIL", "SPTL",
|
||||
"TMF", "SCHO", "SCHR", "SPTS", "GOVT"
|
||||
},
|
||||
new[] {"SHV", "TBT", "TBF", "TMV"}
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the Volatility ETF Category which can be used to access the list of Long and Inverse symbols
|
||||
/// </summary>
|
||||
public static readonly Grouping Volatility = new Grouping(
|
||||
new[] {"TVIX", "VIXY", "SPLV", "UVXY", "EEMV", "EFAV", "USMV"},
|
||||
new[] {"SVXY"}
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Represents the SP500 Sectors ETF Category which can be used to access the list of Long and Inverse symbols
|
||||
/// </summary>
|
||||
public static readonly Grouping SP500Sectors = new Grouping(
|
||||
new[] {"XLB", "XLE", "XLF", "XLI", "XLK", "XLP", "XLU", "XLV", "XLY"},
|
||||
new string[0]
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LiquidETFUniverse class
|
||||
/// </summary>
|
||||
public LiquidETFUniverse() :
|
||||
base(
|
||||
"qc-liquid-etf-basket",
|
||||
SP500Sectors
|
||||
.Concat(Energy)
|
||||
.Concat(Metals)
|
||||
.Concat(Technology)
|
||||
.Concat(Treasuries)
|
||||
.Concat(Volatility)
|
||||
// Convert the concatenated list of Symbol into a Dictionary of DateTime keyed by Symbol
|
||||
// For equities, Symbol.ID is the first date the security is traded.
|
||||
.ToDictionary(x => x.Value, x => x.ID.Date)
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represent a collection of ETF symbols that is grouped according to a given criteria
|
||||
/// </summary>
|
||||
public class Grouping : List<Symbol>
|
||||
{
|
||||
/// <summary>
|
||||
/// List of Symbols that follow the components direction
|
||||
/// </summary>
|
||||
public List<Symbol> Long { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// List of Symbols that follow the components inverse direction
|
||||
/// </summary>
|
||||
public List<Symbol> Inverse { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="Grouping"/>.
|
||||
/// </summary>
|
||||
/// <param name="longTickers">List of tickers of ETFs that follows the components direction</param>
|
||||
/// <param name="inverseTickers">List of tickers of ETFs that follows the components inverse direction</param>
|
||||
public Grouping(IEnumerable<string> longTickers, IEnumerable<string> inverseTickers)
|
||||
{
|
||||
Long = longTickers.Select(x => Symbol.Create(x, SecurityType.Equity, Market.USA)).ToList();
|
||||
Inverse = inverseTickers.Select(x => Symbol.Create(x, SecurityType.Equity, Market.USA)).ToList();
|
||||
AddRange(Long);
|
||||
AddRange(Inverse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string that represents the current object.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A string that represents the current object.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
return "No Symbols";
|
||||
}
|
||||
|
||||
var longSymbols = Long.Count == 0
|
||||
? string.Empty
|
||||
: $" Long: {string.Join(",", Long.Select(x => x.Value))}";
|
||||
|
||||
var inverseSymbols = Inverse.Count == 0
|
||||
? string.Empty
|
||||
: $" Inverse: {string.Join(",", Inverse.Select(x => x.Value))}";
|
||||
|
||||
return $"{Count} symbols:{longSymbols}{inverseSymbols}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following Metals ETFs at their inception date
|
||||
/// 2004-11-18 GLD SPDR Gold Trust
|
||||
/// 2005-01-28 IAU iShares Gold Trust
|
||||
/// 2006-04-28 SLV iShares Silver Trust
|
||||
/// 2006-05-22 GDX VanEck Vectors Gold Miners ETF
|
||||
/// 2008-12-04 AGQ ProShares Ultra Silver
|
||||
/// 2009-11-11 GDXJ VanEck Vectors Junior Gold Miners ETF
|
||||
/// 2010-01-08 PPLT Aberdeen Standard Platinum Shares ETF
|
||||
/// 2010-12-08 NUGT Direxion Daily Gold Miners Bull 3X Shares
|
||||
/// 2010-12-08 DUST Direxion Daily Gold Miners Bear 3X Shares
|
||||
/// 2011-10-17 USLV VelocityShares 3x Long Silver ETN
|
||||
/// 2011-10-17 UGLD VelocityShares 3x Long Gold ETN
|
||||
/// 2013-10-03 JNUG Direxion Daily Junior Gold Miners Index Bull 3x Shares
|
||||
/// 2013-10-03 JDST Direxion Daily Junior Gold Miners Index Bear 3X Shares
|
||||
/// </summary>
|
||||
public class MetalsETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the MetalsETFUniverse class
|
||||
/// </summary>
|
||||
public MetalsETFUniverse() :
|
||||
base(
|
||||
"qc-metals-etf-basket",
|
||||
new Dictionary<string, DateTime>()
|
||||
{
|
||||
{"GLD", new DateTime(2004, 11, 18)},
|
||||
{"IAU", new DateTime(2005, 1, 28)},
|
||||
{"SLV", new DateTime(2006, 4, 28)},
|
||||
{"GDX", new DateTime(2006, 5, 22)},
|
||||
{"AGQ", new DateTime(2008, 12, 4)},
|
||||
{"GDXJ", new DateTime(2009, 11, 11)},
|
||||
{"PPLT", new DateTime(2010, 1, 8)},
|
||||
{"NUGT", new DateTime(2010, 12, 8)},
|
||||
{"DUST", new DateTime(2010, 12, 8)},
|
||||
{"USLV", new DateTime(2011, 10, 17)},
|
||||
{"UGLD", new DateTime(2011, 10, 17)},
|
||||
{"JNUG", new DateTime(2013, 10, 3)},
|
||||
{"JDST", new DateTime(2013, 10, 3)}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NodaTime;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Data;
|
||||
using QuantConnect.Data.Market;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Selects contracts in a futures universe, sorted by open interest. This allows the selection to identifiy current
|
||||
/// active contract.
|
||||
/// </summary>
|
||||
public class OpenInterestFutureUniverseSelectionModel : FutureUniverseSelectionModel
|
||||
{
|
||||
private readonly int? _chainContractsLookupLimit;
|
||||
private readonly IAlgorithm _algorithm;
|
||||
private readonly int? _resultsLimit;
|
||||
private readonly MarketHoursDatabase _marketHoursDatabase;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="OpenInterestFutureUniverseSelectionModel" />
|
||||
/// </summary>
|
||||
/// <param name="algorithm">Algorithm</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>
|
||||
/// <param name="chainContractsLookupLimit">Limit on how many contracts to query for open interest</param>
|
||||
/// <param name="resultsLimit">Limit on how many contracts will be part of the universe</param>
|
||||
public OpenInterestFutureUniverseSelectionModel(IAlgorithm algorithm, Func<DateTime, IEnumerable<Symbol>> futureChainSymbolSelector, int? chainContractsLookupLimit = 6,
|
||||
int? resultsLimit = 1) : base(TimeSpan.FromDays(1), futureChainSymbolSelector)
|
||||
{
|
||||
_marketHoursDatabase = MarketHoursDatabase.FromDataFolder();
|
||||
if (algorithm == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(algorithm));
|
||||
}
|
||||
|
||||
_algorithm = algorithm;
|
||||
_resultsLimit = resultsLimit;
|
||||
_chainContractsLookupLimit = chainContractsLookupLimit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="OpenInterestFutureUniverseSelectionModel" />
|
||||
/// </summary>
|
||||
/// <param name="algorithm">Algorithm</param>
|
||||
/// <param name="futureChainSymbolSelector">Selects symbols from the provided future chain</param>
|
||||
/// <param name="chainContractsLookupLimit">Limit on how many contracts to query for open interest</param>
|
||||
/// <param name="resultsLimit">Limit on how many contracts will be part of the universe</param>
|
||||
public OpenInterestFutureUniverseSelectionModel(IAlgorithm algorithm, PyObject futureChainSymbolSelector, int? chainContractsLookupLimit = 6,
|
||||
int? resultsLimit = 1) : this(algorithm, ConvertFutureChainSymbolSelectorToFunc(futureChainSymbolSelector), chainContractsLookupLimit, resultsLimit)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the future chain universe filter
|
||||
/// </summary>
|
||||
protected override FutureFilterUniverse Filter(FutureFilterUniverse filter)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(Filter), out FutureFilterUniverse result, filter))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// Remove duplicated keys
|
||||
return filter.Contracts(FilterByOpenInterest(
|
||||
filter.DistinctBy(x => x).ToDictionary(x => x.Symbol, x => _marketHoursDatabase.GetEntry(x.ID.Market, x, x.ID.SecurityType))));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters a set of contracts based on open interest.
|
||||
/// </summary>
|
||||
/// <param name="contracts">Contracts to filter</param>
|
||||
/// <returns>Filtered set</returns>
|
||||
public IEnumerable<Symbol> FilterByOpenInterest(IReadOnlyDictionary<Symbol, MarketHoursDatabase.Entry> contracts)
|
||||
{
|
||||
var symbols = new List<Symbol>(_chainContractsLookupLimit.HasValue ? contracts.Keys.OrderBy(x => x.ID.Date).Take(_chainContractsLookupLimit.Value) : contracts.Keys);
|
||||
var openInterest = symbols.GroupBy(x => contracts[x]).SelectMany(g => GetOpenInterest(g.Key, g.Select(i => i))).ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
if (openInterest.Count == 0)
|
||||
{
|
||||
_algorithm.Error(
|
||||
$"{nameof(OpenInterestFutureUniverseSelectionModel)}.{nameof(FilterByOpenInterest)}: Failed to get historical open interest, no symbol will be selected."
|
||||
);
|
||||
return Enumerable.Empty<Symbol>();
|
||||
}
|
||||
|
||||
var filtered = openInterest.OrderByDescending(x => x.Value).ThenBy(x => x.Key.ID.Date).Select(x => x.Key);
|
||||
if (_resultsLimit.HasValue)
|
||||
{
|
||||
filtered = filtered.Take(_resultsLimit.Value);
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private Dictionary<Symbol, decimal> GetOpenInterest(MarketHoursDatabase.Entry marketHours, IEnumerable<Symbol> symbols)
|
||||
{
|
||||
var current = _algorithm.UtcTime;
|
||||
var exchangeHours = marketHours.ExchangeHours;
|
||||
var endTime = Instant.FromDateTimeUtc(_algorithm.UtcTime).InZone(exchangeHours.TimeZone).ToDateTimeUnspecified();
|
||||
var previousDay = Time.GetStartTimeForTradeBars(exchangeHours, endTime, Time.OneDay, 1, true, marketHours.DataTimeZone);
|
||||
var requests = symbols.Select(
|
||||
symbol => new HistoryRequest(
|
||||
previousDay,
|
||||
current,
|
||||
typeof(Tick),
|
||||
symbol,
|
||||
Resolution.Tick,
|
||||
exchangeHours,
|
||||
exchangeHours.TimeZone,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
DataNormalizationMode.Raw,
|
||||
TickType.OpenInterest
|
||||
)
|
||||
)
|
||||
.ToArray();
|
||||
return _algorithm.HistoryProvider.GetHistory(requests, exchangeHours.TimeZone)
|
||||
.Where(s => s.HasData && s.Ticks.Keys.Count > 0)
|
||||
.SelectMany(s => s.Ticks.Select(x => new Tuple<Symbol, Tick>(x.Key, x.Value.LastOrDefault())))
|
||||
.GroupBy(x => x.Item1)
|
||||
.ToDictionary(x => x.Key, x => x.OrderByDescending(i => i.Item2.Time).LastOrDefault().Item2.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts future chain symbol selector, provided as a Python lambda function, to a managed func
|
||||
/// </summary>
|
||||
/// <param name="futureChainSymbolSelector">Python lambda function that selects symbols from the provided future chain</param>
|
||||
/// <returns>Given Python future chain symbol selector as a func objet</returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
private static Func<DateTime, IEnumerable<Symbol>> ConvertFutureChainSymbolSelectorToFunc(PyObject futureChainSymbolSelector)
|
||||
{
|
||||
if (futureChainSymbolSelector.TrySafeAs(out Func<DateTime, IEnumerable<Symbol>> futureSelector))
|
||||
{
|
||||
return futureSelector;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (Py.GIL())
|
||||
{
|
||||
throw new ArgumentException($"FutureUniverseSelectionModel.ConvertFutureChainSymbolSelectorToFunc: {futureChainSymbolSelector.Repr()} is not a valid argument.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides an implementation of <see cref="IUniverseSelectionModel"/> that subscribes to option chains
|
||||
/// </summary>
|
||||
public class OptionUniverseSelectionModel : UniverseSelectionModel
|
||||
{
|
||||
private DateTime _nextRefreshTimeUtc;
|
||||
private readonly TimeSpan _refreshInterval;
|
||||
private readonly UniverseSettings _universeSettings;
|
||||
private readonly Func<DateTime, IEnumerable<Symbol>> _optionChainSymbolSelector;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes.
|
||||
/// </summary>
|
||||
public override DateTime GetNextRefreshTimeUtc() => _nextRefreshTimeUtc;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="OptionUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="optionChainSymbolSelector">Selects symbols from the provided option chain</param>
|
||||
public OptionUniverseSelectionModel(TimeSpan refreshInterval, Func<DateTime, IEnumerable<Symbol>> optionChainSymbolSelector)
|
||||
: this(refreshInterval, optionChainSymbolSelector, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="OptionUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="optionChainSymbolSelector">Selects symbols from the provided option chain</param>
|
||||
public OptionUniverseSelectionModel(TimeSpan refreshInterval, PyObject optionChainSymbolSelector)
|
||||
: this(refreshInterval, optionChainSymbolSelector.SafeAs<Func<DateTime, IEnumerable<Symbol>>>(), null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="OptionUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="optionChainSymbolSelector">Selects symbols from the provided option chain</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public OptionUniverseSelectionModel(TimeSpan refreshInterval, PyObject optionChainSymbolSelector, UniverseSettings universeSettings)
|
||||
: this(refreshInterval, optionChainSymbolSelector.SafeAs<Func<DateTime, IEnumerable<Symbol>>>(), universeSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of <see cref="OptionUniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="refreshInterval">Time interval between universe refreshes</param>
|
||||
/// <param name="optionChainSymbolSelector">Selects symbols from the provided option chain</param>
|
||||
/// <param name="universeSettings">Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed</param>
|
||||
public OptionUniverseSelectionModel(
|
||||
TimeSpan refreshInterval,
|
||||
Func<DateTime, IEnumerable<Symbol>> optionChainSymbolSelector,
|
||||
UniverseSettings universeSettings
|
||||
)
|
||||
{
|
||||
_nextRefreshTimeUtc = DateTime.MinValue;
|
||||
|
||||
_refreshInterval = refreshInterval;
|
||||
_universeSettings = universeSettings;
|
||||
_optionChainSymbolSelector = optionChainSymbolSelector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the universes for this algorithm. Called once after <see cref="IAlgorithm.Initialize"/>
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance to create universes for</param>
|
||||
/// <returns>The universes to be used by the algorithm</returns>
|
||||
public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm)
|
||||
{
|
||||
_nextRefreshTimeUtc = algorithm.UtcTime + _refreshInterval;
|
||||
|
||||
var uniqueUnderlyingSymbols = new HashSet<Symbol>();
|
||||
foreach (var optionSymbol in _optionChainSymbolSelector(algorithm.UtcTime))
|
||||
{
|
||||
if (!optionSymbol.SecurityType.IsOption())
|
||||
{
|
||||
throw new ArgumentException("optionChainSymbolSelector must return option, index options, or futures options symbols.");
|
||||
}
|
||||
|
||||
// prevent creating duplicate option chains -- one per underlying
|
||||
if (uniqueUnderlyingSymbols.Add(optionSymbol.Underlying))
|
||||
{
|
||||
yield return algorithm.CreateOptionChain(optionSymbol, Filter, _universeSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the option chain universe filter
|
||||
/// </summary>
|
||||
protected virtual OptionFilterUniverse Filter(OptionFilterUniverse filter)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(Filter), out OptionFilterUniverse result, filter))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOP
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from AlgorithmImports import *
|
||||
from Selection.UniverseSelectionModel import UniverseSelectionModel
|
||||
|
||||
class OptionUniverseSelectionModel(UniverseSelectionModel):
|
||||
'''Provides an implementation of IUniverseSelectionMode that subscribes to option chains'''
|
||||
def __init__(self,
|
||||
refreshInterval,
|
||||
optionChainSymbolSelector,
|
||||
universeSettings = None):
|
||||
'''Creates a new instance of OptionUniverseSelectionModel
|
||||
Args:
|
||||
refreshInterval: Time interval between universe refreshes</param>
|
||||
optionChainSymbolSelector: Selects symbols from the provided option chain
|
||||
universeSettings: Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed'''
|
||||
self.next_refresh_time_utc = datetime.min
|
||||
|
||||
self.refresh_interval = refreshInterval
|
||||
self.option_chain_symbol_selector = optionChainSymbolSelector
|
||||
self.universe_settings = universeSettings
|
||||
|
||||
def get_next_refresh_time_utc(self):
|
||||
'''Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes.'''
|
||||
return self.next_refresh_time_utc
|
||||
|
||||
def create_universes(self, algorithm: QCAlgorithm) -> list[Universe]:
|
||||
'''Creates a new fundamental universe using this class's selection functions
|
||||
Args:
|
||||
algorithm: The algorithm instance to create universes for
|
||||
Returns:
|
||||
The universe defined by this model'''
|
||||
self.next_refresh_time_utc = (algorithm.utc_time + self.refresh_interval).date()
|
||||
|
||||
uniqueUnderlyingSymbols = set()
|
||||
for option_symbol in self.option_chain_symbol_selector(algorithm.utc_time):
|
||||
if not Extensions.is_option(option_symbol.security_type):
|
||||
raise ValueError("optionChainSymbolSelector must return option, index options, or futures options symbols.")
|
||||
|
||||
# prevent creating duplicate option chains -- one per underlying
|
||||
if option_symbol.underlying not in uniqueUnderlyingSymbols:
|
||||
uniqueUnderlyingSymbols.add(option_symbol.underlying)
|
||||
selection = self.filter
|
||||
if hasattr(self, "Filter") and callable(self.Filter):
|
||||
selection = self.Filter
|
||||
yield Extensions.create_option_chain(algorithm, option_symbol, selection, self.universe_settings)
|
||||
|
||||
def filter(self, filter):
|
||||
'''Defines the option chain universe filter'''
|
||||
# NOP
|
||||
return filter
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using QuantConnect.Data.Fundamental;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the QC500 universe as a universe selection model for framework algorithm
|
||||
/// For details: https://github.com/QuantConnect/Lean/pull/1663
|
||||
/// </summary>
|
||||
public class QC500UniverseSelectionModel : FundamentalUniverseSelectionModel
|
||||
{
|
||||
private const int _numberOfSymbolsCoarse = 1000;
|
||||
private const int _numberOfSymbolsFine = 500;
|
||||
|
||||
// rebalances at the start of each month
|
||||
private int _lastMonth = -1;
|
||||
private readonly Dictionary<Symbol, double> _dollarVolumeBySymbol = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new default instance of the <see cref="QC500UniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
public QC500UniverseSelectionModel()
|
||||
: base(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="QC500UniverseSelectionModel"/>
|
||||
/// </summary>
|
||||
/// <param name="universeSettings">Universe settings defines what subscription properties will be applied to selected securities</param>
|
||||
public QC500UniverseSelectionModel(UniverseSettings universeSettings)
|
||||
: base(true, universeSettings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs coarse selection for the QC500 constituents.
|
||||
/// The stocks must have fundamental data
|
||||
/// The stock must have positive previous-day close price
|
||||
/// The stock must have positive volume on the previous trading day
|
||||
/// </summary>
|
||||
public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectCoarse), out IEnumerable<Symbol> result, algorithm, coarse))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (algorithm.Time.Month == _lastMonth)
|
||||
{
|
||||
return Universe.Unchanged;
|
||||
}
|
||||
|
||||
var sortedByDollarVolume =
|
||||
(from x in coarse
|
||||
where x.HasFundamentalData && x.Volume > 0 && x.Price > 0
|
||||
orderby x.DollarVolume descending
|
||||
select x).Take(_numberOfSymbolsCoarse).ToList();
|
||||
|
||||
_dollarVolumeBySymbol.Clear();
|
||||
foreach (var x in sortedByDollarVolume)
|
||||
{
|
||||
_dollarVolumeBySymbol[x.Symbol] = x.DollarVolume;
|
||||
}
|
||||
|
||||
// If no security has met the QC500 criteria, the universe is unchanged.
|
||||
// A new selection will be attempted on the next trading day as _lastMonth is not updated
|
||||
if (_dollarVolumeBySymbol.Count == 0)
|
||||
{
|
||||
return Universe.Unchanged;
|
||||
}
|
||||
|
||||
return _dollarVolumeBySymbol.Keys;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs fine selection for the QC500 constituents
|
||||
/// The company's headquarter must in the U.S.
|
||||
/// The stock must be traded on either the NYSE or NASDAQ
|
||||
/// At least half a year since its initial public offering
|
||||
/// The stock's market cap must be greater than 500 million
|
||||
/// </summary>
|
||||
public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
|
||||
{
|
||||
// Check if this method was overridden in Python
|
||||
if (TryInvokePythonOverride(nameof(SelectFine), out IEnumerable<Symbol> result, algorithm, fine))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
var filteredFine =
|
||||
(from x in fine
|
||||
where x.CompanyReference.CountryId == "USA" &&
|
||||
(x.CompanyReference.PrimaryExchangeID == "NYS" || x.CompanyReference.PrimaryExchangeID == "NAS") &&
|
||||
(algorithm.Time - x.SecurityReference.IPODate).Days > 180 &&
|
||||
x.MarketCap > 500000000m
|
||||
select x).ToList();
|
||||
|
||||
var count = filteredFine.Count;
|
||||
|
||||
// If no security has met the QC500 criteria, the universe is unchanged.
|
||||
// A new selection will be attempted on the next trading day as _lastMonth is not updated
|
||||
if (count == 0)
|
||||
{
|
||||
return Universe.Unchanged;
|
||||
}
|
||||
|
||||
// Update _lastMonth after all QC500 criteria checks passed
|
||||
_lastMonth = algorithm.Time.Month;
|
||||
|
||||
var percent = _numberOfSymbolsFine / (double)count;
|
||||
|
||||
// select stocks with top dollar volume in every single sector
|
||||
var topFineBySector =
|
||||
(from x in filteredFine
|
||||
// Group by sector
|
||||
group x by x.CompanyReference.IndustryTemplateCode into g
|
||||
let y = from item in g
|
||||
orderby _dollarVolumeBySymbol[item.Symbol] descending
|
||||
select item
|
||||
let c = (int)Math.Ceiling(y.Count() * percent)
|
||||
select new { g.Key, Value = y.Take(c) }
|
||||
).ToDictionary(x => x.Key, x => x.Value);
|
||||
|
||||
return topFineBySector.SelectMany(x => x.Value)
|
||||
.OrderByDescending(x => _dollarVolumeBySymbol[x.Symbol])
|
||||
.Take(_numberOfSymbolsFine)
|
||||
.Select(x => x.Symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from AlgorithmImports import *
|
||||
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
|
||||
from itertools import groupby
|
||||
from math import ceil
|
||||
|
||||
class QC500UniverseSelectionModel(FundamentalUniverseSelectionModel):
|
||||
'''Defines the QC500 universe as a universe selection model for framework algorithm
|
||||
For details: https://github.com/QuantConnect/Lean/pull/1663'''
|
||||
|
||||
def __init__(self, filterFineData = True, universeSettings = None):
|
||||
'''Initializes a new default instance of the QC500UniverseSelectionModel'''
|
||||
super().__init__(filterFineData, universeSettings)
|
||||
self.number_of_symbols_coarse = 1000
|
||||
self.number_of_symbols_fine = 500
|
||||
self.dollar_volume_by_symbol = {}
|
||||
self.last_month = -1
|
||||
|
||||
def select_coarse(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]):
|
||||
'''Performs coarse selection for the QC500 constituents.
|
||||
The stocks must have fundamental data
|
||||
The stock must have positive previous-day close price
|
||||
The stock must have positive volume on the previous trading day'''
|
||||
if algorithm.time.month == self.last_month:
|
||||
return Universe.UNCHANGED
|
||||
|
||||
sorted_by_dollar_volume = sorted([x for x in fundamental if x.has_fundamental_data and x.volume > 0 and x.price > 0],
|
||||
key = lambda x: x.dollar_volume, reverse=True)[:self.number_of_symbols_coarse]
|
||||
|
||||
self.dollar_volume_by_symbol = {x.Symbol:x.dollar_volume for x in sorted_by_dollar_volume}
|
||||
|
||||
# If no security has met the QC500 criteria, the universe is unchanged.
|
||||
# A new selection will be attempted on the next trading day as self.lastMonth is not updated
|
||||
if len(self.dollar_volume_by_symbol) == 0:
|
||||
return Universe.UNCHANGED
|
||||
|
||||
# return the symbol objects our sorted collection
|
||||
return list(self.dollar_volume_by_symbol.keys())
|
||||
|
||||
def select_fine(self, algorithm: QCAlgorithm, fundamental: list[Fundamental]):
|
||||
'''Performs fine selection for the QC500 constituents
|
||||
The company's headquarter must in the U.S.
|
||||
The stock must be traded on either the NYSE or NASDAQ
|
||||
At least half a year since its initial public offering
|
||||
The stock's market cap must be greater than 500 million'''
|
||||
|
||||
sorted_by_sector = sorted([x for x in fundamental if x.company_reference.country_id == "USA"
|
||||
and x.company_reference.primary_exchange_id in ["NYS","NAS"]
|
||||
and (algorithm.time - x.security_reference.ipo_date).days > 180
|
||||
and x.market_cap > 5e8],
|
||||
key = lambda x: x.company_reference.industry_template_code)
|
||||
|
||||
count = len(sorted_by_sector)
|
||||
|
||||
# If no security has met the QC500 criteria, the universe is unchanged.
|
||||
# A new selection will be attempted on the next trading day as self.lastMonth is not updated
|
||||
if count == 0:
|
||||
return Universe.UNCHANGED
|
||||
|
||||
# Update self.lastMonth after all QC500 criteria checks passed
|
||||
self.last_month = algorithm.time.month
|
||||
|
||||
percent = self.number_of_symbols_fine / count
|
||||
sorted_by_dollar_volume = []
|
||||
|
||||
# select stocks with top dollar volume in every single sector
|
||||
for code, g in groupby(sorted_by_sector, lambda x: x.company_reference.industry_template_code):
|
||||
y = sorted(g, key = lambda x: self.dollar_volume_by_symbol[x.Symbol], reverse = True)
|
||||
c = ceil(len(y) * percent)
|
||||
sorted_by_dollar_volume.extend(y[:c])
|
||||
|
||||
sorted_by_dollar_volume = sorted(sorted_by_dollar_volume, key = lambda x: self.dollar_volume_by_symbol[x.Symbol], reverse=True)
|
||||
return [x.Symbol for x in sorted_by_dollar_volume[:self.number_of_symbols_fine]]
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following SP500 Sectors ETFs at their inception date
|
||||
/// 1998-12-22 XLB Materials Select Sector SPDR ETF
|
||||
/// 1998-12-22 XLE Energy Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLF Financial Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLI Industrial Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLK Technology Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLP Consumer Staples Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLU Utilities Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLV Health Care Select Sector SPDR Fund
|
||||
/// 1998-12-22 XLY Consumer Discretionary Select Sector SPDR Fund
|
||||
/// </summary>
|
||||
public class SP500SectorsETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the SP500SectorsETFUniverse class
|
||||
/// </summary>
|
||||
public SP500SectorsETFUniverse() :
|
||||
base(
|
||||
"qc-sp500-sectors-etf-basket",
|
||||
new Dictionary<string, DateTime>()
|
||||
{
|
||||
{"XLB", new DateTime(1998, 12, 22)},
|
||||
{"XLE", new DateTime(1998, 12, 22)},
|
||||
{"XLF", new DateTime(1998, 12, 22)},
|
||||
{"XLI", new DateTime(1998, 12, 22)},
|
||||
{"XLK", new DateTime(1998, 12, 22)},
|
||||
{"XLP", new DateTime(1998, 12, 22)},
|
||||
{"XLU", new DateTime(1998, 12, 22)},
|
||||
{"XLV", new DateTime(1998, 12, 22)},
|
||||
{"XLY", new DateTime(1998, 12, 22)}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NodaTime;
|
||||
using Python.Runtime;
|
||||
using QuantConnect.Data.UniverseSelection;
|
||||
using QuantConnect.Interfaces;
|
||||
using QuantConnect.Scheduling;
|
||||
using QuantConnect.Securities;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a universe selection model that invokes a selector function on a specific scheduled given by an <see cref="IDateRule"/> and an <see cref="ITimeRule"/>
|
||||
/// </summary>
|
||||
public class ScheduledUniverseSelectionModel : UniverseSelectionModel
|
||||
{
|
||||
private readonly IDateRule _dateRule;
|
||||
private readonly ITimeRule _timeRule;
|
||||
private readonly Func<DateTime, IEnumerable<Symbol>> _selector;
|
||||
private readonly DateTimeZone _timeZone;
|
||||
private readonly UniverseSettings _settings;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ScheduledUniverseSelectionModel"/> class using the algorithm's time zone
|
||||
/// </summary>
|
||||
/// <param name="dateRule">Date rule defines what days the universe selection function will be invoked</param>
|
||||
/// <param name="timeRule">Time rule defines what times on each day selected by date rule the universe selection function will be invoked</param>
|
||||
/// <param name="selector">Selector function accepting the date time firing time and returning the universe selected symbols</param>
|
||||
/// <param name="settings">Universe settings for subscriptions added via this universe, null will default to algorithm's universe settings</param>
|
||||
public ScheduledUniverseSelectionModel(IDateRule dateRule, ITimeRule timeRule, Func<DateTime, IEnumerable<Symbol>> selector, UniverseSettings settings = null)
|
||||
{
|
||||
_dateRule = dateRule;
|
||||
_timeRule = timeRule;
|
||||
_selector = selector;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ScheduledUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="timeZone">The time zone the date/time rules are in</param>
|
||||
/// <param name="dateRule">Date rule defines what days the universe selection function will be invoked</param>
|
||||
/// <param name="timeRule">Time rule defines what times on each day selected by date rule the universe selection function will be invoked</param>
|
||||
/// <param name="selector">Selector function accepting the date time firing time and returning the universe selected symbols</param>
|
||||
/// <param name="settings">Universe settings for subscriptions added via this universe, null will default to algorithm's universe settings</param>
|
||||
public ScheduledUniverseSelectionModel(DateTimeZone timeZone, IDateRule dateRule, ITimeRule timeRule, Func<DateTime, IEnumerable<Symbol>> selector, UniverseSettings settings = null)
|
||||
{
|
||||
_timeZone = timeZone;
|
||||
_dateRule = dateRule;
|
||||
_timeRule = timeRule;
|
||||
_selector = selector;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ScheduledUniverseSelectionModel"/> class using the algorithm's time zone
|
||||
/// </summary>
|
||||
/// <param name="dateRule">Date rule defines what days the universe selection function will be invoked</param>
|
||||
/// <param name="timeRule">Time rule defines what times on each day selected by date rule the universe selection function will be invoked</param>
|
||||
/// <param name="selector">Selector function accepting the date time firing time and returning the universe selected symbols</param>
|
||||
/// <param name="settings">Universe settings for subscriptions added via this universe, null will default to algorithm's universe settings</param>
|
||||
public ScheduledUniverseSelectionModel(IDateRule dateRule, ITimeRule timeRule, PyObject selector, UniverseSettings settings = null)
|
||||
: this(null, dateRule, timeRule, selector, settings)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ScheduledUniverseSelectionModel"/> class
|
||||
/// </summary>
|
||||
/// <param name="timeZone">The time zone the date/time rules are in</param>
|
||||
/// <param name="dateRule">Date rule defines what days the universe selection function will be invoked</param>
|
||||
/// <param name="timeRule">Time rule defines what times on each day selected by date rule the universe selection function will be invoked</param>
|
||||
/// <param name="selector">Selector function accepting the date time firing time and returning the universe selected symbols</param>
|
||||
/// <param name="settings">Universe settings for subscriptions added via this universe, null will default to algorithm's universe settings</param>
|
||||
public ScheduledUniverseSelectionModel(DateTimeZone timeZone, IDateRule dateRule, ITimeRule timeRule, PyObject selector, UniverseSettings settings = null)
|
||||
{
|
||||
Func<DateTime, object> func;
|
||||
selector.TrySafeAs(out func);
|
||||
_timeZone = timeZone;
|
||||
_dateRule = dateRule;
|
||||
_timeRule = timeRule;
|
||||
_selector = func.ConvertSelectionSymbolDelegate();
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the universes for this algorithm. Called once after <see cref="IAlgorithm.Initialize"/>
|
||||
/// </summary>
|
||||
/// <param name="algorithm">The algorithm instance to create universes for</param>
|
||||
/// <returns>The universes to be used by the algorithm</returns>
|
||||
public override IEnumerable<Universe> CreateUniverses(QCAlgorithm algorithm)
|
||||
{
|
||||
yield return new ScheduledUniverse(
|
||||
// by default ITimeRule yields in UTC
|
||||
_timeZone ?? TimeZones.Utc,
|
||||
_dateRule,
|
||||
_timeRule,
|
||||
_selector,
|
||||
_settings ?? algorithm.UniverseSettings
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following Technology ETFs at their inception date
|
||||
/// 1998-12-22 XLK Technology Select Sector SPDR Fund
|
||||
/// 1999-03-10 QQQ Invesco QQQ
|
||||
/// 2001-07-13 SOXX iShares PHLX Semiconductor ETF
|
||||
/// 2001-07-13 IGV iShares Expanded Tech-Software Sector ETF
|
||||
/// 2004-01-30 VGT Vanguard Information Technology ETF
|
||||
/// 2006-04-25 QTEC First Trust NASDAQ 100 Technology
|
||||
/// 2006-06-23 FDN First Trust Dow Jones Internet Index
|
||||
/// 2007-05-10 FXL First Trust Technology AlphaDEX Fund
|
||||
/// 2008-12-17 TECL Direxion Daily Technology Bull 3X Shares
|
||||
/// 2008-12-17 TECS Direxion Daily Technology Bear 3X Shares
|
||||
/// 2010-03-11 SOXL Direxion Daily Semiconductor Bull 3x Shares
|
||||
/// 2010-03-11 SOXS Direxion Daily Semiconductor Bear 3x Shares
|
||||
/// 2011-07-06 SKYY First Trust ISE Cloud Computing Index Fund
|
||||
/// 2011-12-21 SMH VanEck Vectors Semiconductor ETF
|
||||
/// 2013-08-01 KWEB KraneShares CSI China Internet ETF
|
||||
/// 2013-10-24 FTEC Fidelity MSCI Information Technology Index ETF
|
||||
/// </summary>
|
||||
public class TechnologyETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the TechnologyETFUniverse class
|
||||
/// </summary>
|
||||
public TechnologyETFUniverse() :
|
||||
base(
|
||||
"qc-technology-etf-basket",
|
||||
new Dictionary<string, DateTime>()
|
||||
{
|
||||
{"XLK", new DateTime(1998, 12, 22)},
|
||||
{"QQQ", new DateTime(1999, 3, 10)},
|
||||
{"SOXX", new DateTime(2001, 7, 13)},
|
||||
{"IGV", new DateTime(2001, 7, 13)},
|
||||
{"VGT", new DateTime(2004, 1, 30)},
|
||||
{"QTEC", new DateTime(2006, 4, 25)},
|
||||
{"FDN", new DateTime(2006, 6, 23)},
|
||||
{"FXL", new DateTime(2007, 5, 10)},
|
||||
{"TECL", new DateTime(2008, 12, 17)},
|
||||
{"TECS", new DateTime(2008, 12, 17)},
|
||||
{"SOXL", new DateTime(2010, 3, 11)},
|
||||
{"SOXS", new DateTime(2010, 3, 11)},
|
||||
{"SKYY", new DateTime(2011, 7, 6)},
|
||||
{"SMH", new DateTime(2011, 12, 21)},
|
||||
{"KWEB", new DateTime(2013, 8, 1)},
|
||||
{"FTEC", new DateTime(2013, 10, 24)}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following US Treasuries ETFs at their inception date
|
||||
/// 2002-07-26 IEF iShares 7-10 Year Treasury Bond ETF
|
||||
/// 2002-07-26 SHY iShares 1-3 Year Treasury Bond ETF
|
||||
/// 2002-07-26 TLT iShares 20+ Year Treasury Bond ETF
|
||||
/// 2007-01-11 SHV iShares Short Treasury Bond ETF
|
||||
/// 2007-01-11 IEI iShares 3-7 Year Treasury Bond ETF
|
||||
/// 2007-01-11 TLH iShares 10-20 Year Treasury Bond ETF
|
||||
/// 2007-12-10 EDV Vanguard Ext Duration Treasury ETF
|
||||
/// 2007-05-30 BIL SPDR Barclays 1-3 Month T-Bill ETF
|
||||
/// 2007-05-30 SPTL SPDR Portfolio Long Term Treasury ETF
|
||||
/// 2008-05-01 TBT UltraShort Barclays 20+ Year Treasury
|
||||
/// 2009-04-16 TMF Direxion Daily 20-Year Treasury Bull 3X
|
||||
/// 2009-04-16 TMV Direxion Daily 20-Year Treasury Bear 3X
|
||||
/// 2009-08-20 TBF ProShares Short 20+ Year Treasury
|
||||
/// 2009-11-23 VGSH Vanguard Short-Term Treasury ETF
|
||||
/// 2009-11-23 VGIT Vanguard Intermediate-Term Treasury ETF
|
||||
/// 2009-11-24 VGLT Vanguard Long-Term Treasury ETF
|
||||
/// 2010-08-06 SCHO Schwab Short-Term U.S. Treasury ETF
|
||||
/// 2010-08-06 SCHR Schwab Intermediate-Term U.S. Treasury ETF
|
||||
/// 2011-12-01 SPTS SPDR Portfolio Short Term Treasury ETF
|
||||
/// 2012-02-24 GOVT iShares U.S. Treasury Bond ETF
|
||||
/// </summary>
|
||||
public class USTreasuriesETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the USTreasuriesETFUniverse class
|
||||
/// </summary>
|
||||
public USTreasuriesETFUniverse() :
|
||||
base(
|
||||
"qc-us-treasuries-etf-basket",
|
||||
new Dictionary<string, DateTime>()
|
||||
{
|
||||
{"IEF", new DateTime(2002, 7, 26)},
|
||||
{"SHY", new DateTime(2002, 7, 26)},
|
||||
{"TLT", new DateTime(2002, 7, 26)},
|
||||
{"IEI", new DateTime(2007, 1, 11)},
|
||||
{"SHV", new DateTime(2007, 1, 11)},
|
||||
{"TLH", new DateTime(2007, 1, 11)},
|
||||
{"EDV", new DateTime(2007, 12, 10)},
|
||||
{"BIL", new DateTime(2007, 5, 30)},
|
||||
{"SPTL", new DateTime(2007, 5, 30)},
|
||||
{"TBT", new DateTime(2008, 5, 1)},
|
||||
{"TMF", new DateTime(2009, 4, 16)},
|
||||
{"TMV", new DateTime(2009, 4, 16)},
|
||||
{"TBF", new DateTime(2009, 8, 20)},
|
||||
{"VGSH", new DateTime(2009, 11, 23)},
|
||||
{"VGIT", new DateTime(2009, 11, 23)},
|
||||
{"VGLT", new DateTime(2009, 11, 24)},
|
||||
{"SCHO", new DateTime(2010, 8, 6)},
|
||||
{"SCHR", new DateTime(2010, 8, 6)},
|
||||
{"SPTS", new DateTime(2011, 12, 1)},
|
||||
{"GOVT", new DateTime(2012, 2, 24)}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QuantConnect.Algorithm.Framework.Selection
|
||||
{
|
||||
/// <summary>
|
||||
/// Universe Selection Model that adds the following Volatility ETFs at their inception date
|
||||
/// 2010-02-11 SQQQ ProShares UltraPro ShortQQQ
|
||||
/// 2010-02-11 TQQQ ProShares UltraProQQQ
|
||||
/// 2010-11-30 TVIX VelocityShares Daily 2x VIX Short Term ETN
|
||||
/// 2011-01-04 VIXY ProShares VIX Short-Term Futures ETF
|
||||
/// 2011-05-05 SPLV Invesco S&P 500® Low Volatility ETF
|
||||
/// 2011-10-04 SVXY ProShares Short VIX Short-Term Futures
|
||||
/// 2011-10-04 UVXY ProShares Ultra VIX Short-Term Futures
|
||||
/// 2011-10-20 EEMV iShares Edge MSCI Min Vol Emerging Markets ETF
|
||||
/// 2011-10-20 EFAV iShares Edge MSCI Min Vol EAFE ETF
|
||||
/// 2011-10-20 USMV iShares Edge MSCI Min Vol USA ETF
|
||||
/// </summary>
|
||||
public class VolatilityETFUniverse : InceptionDateUniverseSelectionModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the VolatilityETFUniverse class
|
||||
/// </summary>
|
||||
public VolatilityETFUniverse() :
|
||||
base(
|
||||
"qc-volatility-etf-basket",
|
||||
new Dictionary<string, DateTime>()
|
||||
{
|
||||
{"SQQQ", new DateTime(2010, 2, 11)},
|
||||
{"TQQQ", new DateTime(2010, 2, 11)},
|
||||
{"TVIX", new DateTime(2010, 11, 30)},
|
||||
{"VIXY", new DateTime(2011, 1, 4)},
|
||||
{"SPLV", new DateTime(2011, 5, 5)},
|
||||
{"SVXY", new DateTime(2011, 10, 4)},
|
||||
{"UVXY", new DateTime(2011, 10, 4)},
|
||||
{"EEMV", new DateTime(2011, 10, 20)},
|
||||
{"EFAV", new DateTime(2011, 10, 20)},
|
||||
{"USMV", new DateTime(2011, 10, 20)}
|
||||
}
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user