Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>Factors by QuantConnect provides precomputed factors for individual US Equities plus unlinked factors that aren't tied to a tradable security, such as US Treasury yield curve rates. The data starts in 1998, covers every US Equity that has appeared in the SPY ETF constituents universe since August 2015, and is delivered on a daily frequency. This dataset is created by computing each factor from our own datasets with the same LEAN tooling an algorithm would use, so backtest and precomputed values match exactly.</p>

<p>For more information about the Factors dataset, including CLI commands and pricing, see the <a href="/datasets/quantconnect-factors">dataset listing</a>.<p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<p>The following snippet demonstrates how to request data from the Factors dataset:
</p><div class="section-example-container">
<pre class="python"># Factors linked to a specific stock:
self._equity = self.add_equity("AAPL", Resolution.DAILY)
self._equity.factors = self.add_data(Factors, self._equity.symbol).symbol
# Unlinked factors:
self._unlinked_factors = self.add_data(Factors, Factors.UNLINKED).symbol
# All factors:
self._universe = self.add_universe(FactorsUniverse, self._select_assets)</pre>
<pre class="csharp">// Factors linked to a specific stock:
_equity = AddEquity("SPY", Resolution.Daily);
_equityFactors = AddData&lt;Factors&gt;(_equity.Symbol).Symbol;
// Unlinked factors:
_unlinkedFactors = AddData&lt;Factors&gt;(Factors.Unlinked).Symbol;
// All factors:
_universe = AddUniverse&lt;FactorsUniverse&gt;(SelectAssets);</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<p>The following table describes the dataset properties:</p>

<table class="table qc-table"><thead><tr><th>Property</th>
<th>Value</th>
</tr></thead><tbody><tr><td>Start Date</td>
<td>January 1998</td>
</tr><tr><td>Data Density</td>
<td>Dense</td>
</tr><tr><td>Asset Coverage</td>
<td>All US Equities in the SPY ETF, plus unlinked factors</td>
</tr><tr><td>Resolution</td>
<td>Daily</td>
</tr><tr><td>Timezone</td>
<td>New York</td>
</tr></tbody></table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<p>To add Factors data to your algorithm, call the <code class="csharp">AddData</code><code class="python">add_data</code> method. For the factors linked to a specific Equity, pass the underlying Equity <code>Symbol</code>. For the unlinked factors, which aren't tied to any tradable security, pass <code class="csharp">Factors.Unlinked</code><code class="python">Factors.UNLINKED</code>. Save a reference to each dataset <code>Symbol</code> so you can access the data later in your algorithm.</p>

<div class="section-example-container">
<pre class="python">class FactorsDataAlgorithm(QCAlgorithm):

def initialize(self) -&gt; None:
self.set_start_date(2014, 3, 25)
self.set_end_date(2014, 4, 8)
self.set_cash(100000)
self._equity = self.add_equity("SPY", Resolution.DAILY)
self._equity.factors = self.add_data(Factors, self._equity.symbol).symbol
self._unlinked_factors = self.add_data(Factors, Factors.UNLINKED).symbol</pre>
<pre class="csharp">public class FactorsDataAlgorithm : QCAlgorithm
{
private Equity _equity;
private Symbol _equityFactors, _unlinkedFactors;

public override void Initialize()
{
SetStartDate(2014, 3, 25);
SetEndDate(2014, 4, 8);
SetCash(100000);
_equity = AddEquity("SPY", Resolution.Daily);
_equityFactors = AddData&lt;Factors&gt;(_equity.Symbol).Symbol;
_unlinkedFactors = AddData&lt;Factors&gt;(Factors.Unlinked).Symbol;
}
}</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<p>To get the current factor data, index the current <a href='/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices'><code>Slice</code></a> with the dataset <code>Symbol</code>.
<code>Slice</code> objects deliver unique events to your algorithm as they happen, but the <code>Slice</code> may not contain data for your dataset at every time step. To avoid issues, check if the <code>Slice</code> contains the data you want before you index it. Each <code>Factors</code> object behaves like a dictionary, mapping the factor name to its value. Index the object with a factor name constant (for example, <code class="csharp">Factors.Technical.Roc1Day</code><code class="python">Factors.Technical.ROC_1_DAY</code> is "technical_roc_1d") to get the value.

</p>

<div class="section-example-container">
<pre class="python">def on_data(self, data: Slice) -&gt; None:
equity_factors = data.get(Factors).get(self._equity.factors)
if equity_factors:
value = equity_factors[Factors.ROC_1_DAY]

unlinked_factors = data.get(Factors).get(self._unlinked_factors)
if unlinked_factors:
ust_yield = unlinked_factors[Factors.UST_YIELD_1_MONTH]</pre>
<pre class="csharp">public override void OnData(Slice data)
{
if (data.Get&lt;Factors&gt;().TryGetValue(_equityFactors, out var equityFactors))
{
var value = equityFactors[Factors.Roc1Day];
}

if (data.Get&lt;Factors&gt;().TryGetValue(_unlinkedFactors, out var unlinkedFactors))
{
var ustYield = unlinkedFactors[Factors.UstYield1Month];
}
}
</pre>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<p>To get historical factor data, call the <code class="csharp">History</code><code class="python">history</code> method with the dataset <code>Symbol</code>.
If there is no data in the period you request, the history result is empty.</p>

<div class="section-example-container">
<pre class="python"># DataFrames
equity_factors_history_df = self.history(self._equity.factors, 100, Resolution.DAILY)
unlinked_factors_history_df = self.history(self._unlinked_factors, 100, Resolution.DAILY)

# Dataset objects
equity_factors_history = self.history[Factors](self._equity.factors, 100, Resolution.DAILY)
market_factors_history = self.history[Factors](self._unlinked_factors, 100, Resolution.DAILY)</pre>
<pre class="csharp">var equityFactorsHistory = History&lt;Factors&gt;(_equityFactors, 100, Resolution.Daily);
var unlinkedFactorsHistory = History&lt;Factors&gt;(_marketFactors, 100, Resolution.Daily);</pre>
</div>

<p>For more information about historical data, see <a href="/docs/v2/writing-algorithms/historical-data/history-requests">History Requests</a>.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<p>To select a dynamic universe of US Equities based on factor values, call the <code class="csharp">AddUniverse</code><code class="python">add_universe</code> method with the <code>FactorsUniverse</code> class and a selection function.</p>

<div class="section-example-container">
<pre class="python">def initialize(self) -&gt; None:
self._universe = self.add_universe(FactorsUniverse, self._select_assets)

def _select_assets(self, data: List[FactorsUniverse]) -&gt; List[Symbol]:
ust_yield = None
positive = []
negative = []
for factors in data:
if Factors.UST_YIELD_1_MONTH in factors.keys:
ust_yield = factors[Factors.UST_YIELD_1_MONTH]
elif Factors.ROC_1_DAY in factors.keys:
if factors[Factors.ROC_1_DAY] &gt; 0:
positive.append(factors.symbol)
else:
negative.append(factors.symbol)
return positive if ust_yield &lt; 4 else negative</pre>
<pre class="csharp">private Universe _universe;

public override void Initialize()
{
_universe = AddUniverse&lt;FactorsUniverse&gt;(SelectAssets);
}

private IEnumerable&lt;Symbol&gt; SelectAssets(IEnumerable&lt;BaseData&gt; data)
{
decimal? ustYield = null;
var positive = new List&lt;Symbol&gt;();
var negative = new List&lt;Symbol&gt;();
foreach (var factors in data.OfType&lt;FactorsUniverse&gt;())
{
if (factors.ContainsKey(Factors.UstYield1Month))
{
ustYield = factors[Factors.UstYield1Month];
}
else if (factors.ContainsKey(Factors.Roc1Day))
{
if (factors[Factors.Roc1Day] &gt; 0)
{
positive.Add(factors.Symbol);
}
else
{
negative.Add(factors.Symbol);
}
}
}
return ustYield &lt; 4 ? positive : negative;
}</pre>
</div>

<p>For more information about dynamic universes, see <a href="/docs/v2/writing-algorithms/universes/key-concepts">Universes</a>.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<p>You can get historical universe data in an algorithm and in the Research Environment.</p>

<h4>Historical Universe Data in Algorithms</h4>
<p>To get historical universe data in an algorithm, call the <code class="csharp">History</code><code class="python">history</code> method with the <code>Universe</code> object and the lookback period. If there is no data in the period you request, the history result is empty.</p>

<div class="section-example-container">
<pre class="csharp">var universeHistory = History(_universe, 30, Resolution.Daily);
foreach (var universeDay in universeHistory)
{
foreach (FactorsUniverse factors in universeDay)
{
if (factors.TryGetValue(Factors.Roc1Day, out var value))
{
// ...
}
}
}</pre>
<pre class="python"># DataFrame example where the columns are the FactorsUniverse attributes:
history_df = self.history(self._universe, 30, Resolution.DAILY, flatten=True)

# Series example where the values are lists of FactorsUniverse objects:
universe_history = self.history(self._universe, 30, Resolution.DAILY)
for (_, time), universe_day in universe_history.items():
for factors in universe_day:
if Factors.ROC_1_DAY in factors.keys:
value = factors[Factors.ROC_1_DAY]</pre>
</div>

<h4>Historical Universe Data in Research</h4>
<p>To get historical universe data in research, call the <code class="csharp">UniverseHistory</code><code class="python">universe_history</code> method with the <code>Universe</code> object, a start date, and an end date. This method returns the filtered universe. If there is no data in the period you request, the history result is empty.</p>

<div class="section-example-container">
<pre class="csharp">var universeHistory = qb.History(universe, qb.Time.AddDays(-30), qb.Time);
foreach (var universeDay in universeHistory)
{
foreach (FactorsUniverse factors in universeDay)
{
if (factors.TryGetValue(Factors.Roc1Day, out var value))
{
// ...
}
}
}</pre>
<pre class="python"># DataFrame example where the columns are the FactorsUniverse attributes:
history = qb.history(universe, qb.time - timedelta(30), qb.time, flatten=True)</pre>
</div>

<p>You can call the <code class="csharp">History</code><code class="python">history</code> method in Research.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p>To remove a subscription, call the <code class="csharp">RemoveSecurity</code><code class="python">remove_security</code> method.</p>

<div class="section-example-container">
<pre class="python">self.remove_security(self._equity.factors)</pre>
<pre class="csharp">RemoveSecurity(_equityFactors);</pre>
</div>

<p>If you subscribe to Factors data for assets in a dynamic universe, remove the dataset subscription when the asset leaves your universe. To view a common design pattern, see <a href="/docs/v2/writing-algorithms/algorithm-framework/alpha/key-concepts#05-Track-Security-Changes">Track Security Changes</a>.</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<p>The <code>Factors</code> and <code>FactorsUniverse</code> objects behave like a dictionary, mapping the factor name to its value. The <code>Factors</code> class provides name constants for every factor.</p>

<h4>Linked Factors</h4>
<p>Linked factors are factors that are tied to a specific tradable security. The Factors dataset provides the following linked factors for each US Equity:</p>
<ul>
<li><code class="python">Factors.ROC_1_DAY</code><code class="csharp">Factors.Roc1Day</code>: 1-day rate of change of the closing price: close[t] / close[t-1] - 1</li>
<li><code class="python">Factors.VOLATILITY_21_DAY</code><code class="csharp">Factors.Volatility21Day</code>: 21-day realized volatility of daily returns: the standard deviation of 1-day closing-price returns over the trailing 21 days</li>
<li><code class="python">Factors.VOLUME_Z_21_DAY</code><code class="csharp">Factors.VolumeZ21Day</code>: 21-day volume z-score: the number of standard deviations the current trading volume sits above or below its trailing 21-day mean</li>
<li><code class="python">Factors.MFI_21_DAY</code><code class="csharp">Factors.Mfi21Day</code>: 21-day Money Flow Index: volume-weighted buying vs. selling pressure, from daily typical price changes signed and weighted by volume, accumulated over 21 sessions and bounded 0-100</li>
<li><code class="python">Factors.MOM_12_MONTH</code><code class="csharp">Factors.Mom12Month</code>: Twelve-month momentum skipping the most recent month: the stock's return over months t-11 through t-1, computed each session from LEAN's adjusted daily closes, from Jegadeesh and Titman (1993, JF), where higher values predicted higher returns</li>
<li><code class="python">Factors.INT_MOM</code><code class="csharp">Factors.IntMom</code>: Intermediate momentum: the stock's return over months t-12 through t-7, computed each session from LEAN's adjusted daily closes, from Novy-Marx (2012, JFE), where higher values predicted higher returns</li>
<li><code class="python">Factors.MOM_12_MONTH_OFF_SEASON</code><code class="csharp">Factors.Mom12MonthOffSeason</code>: Momentum without the seasonal month: the mean of the monthly returns of months t-1 through t-10, which leaves out the current month and month t-11, the month one year before the coming month, computed each session from LEAN's adjusted daily closes, from Heston and Sadka (2008, JFE), where higher values predicted higher returns</li>
<li><code class="python">Factors.VOLUME_TREND</code><code class="csharp">Factors.VolumeTrend</code>: Volume trend: the slope of a regression of monthly volume on a linear time trend over the trailing 60 months, divided by the mean monthly volume over those months, computed each session from LEAN's split- and dividend-adjusted daily volume with 21 sessions to a month and at least 30 months required, from Haugen and Baker (1996, JFE), where higher values predicted lower returns</li>
<li><code class="python">Factors.MOM_SEASON_SHORT</code><code class="csharp">Factors.MomSeasonShort</code>: Return seasonality last year: the stock's return over the 21 sessions from 252 to 231 sessions ago, the month one year before the coming month, computed each session from LEAN's adjusted daily closes, from Heston and Sadka (2008, JFE), where higher values predicted higher returns</li>
<li><code class="python">Factors.ILLIQUIDITY</code><code class="csharp">Factors.Illiquidity</code>: Amihud illiquidity: the mean over the past 12 months of the daily ratio of the absolute return to the dollar volume traded, computed each session from LEAN's adjusted daily bars, from Amihud (2002, JFM), where higher values predicted higher returns</li>
<li><code class="python">Factors.FINRA_SHORT_SALE_VOLUME_SHORT_VOLUME_RATIO_SMA_21_DAY</code><code class="csharp">Factors.FinraShortSaleVolumeShortVolumeRatioSma21Day</code>: 21-day simple moving average of the FINRA Reg SHO daily short volume ratio: the share (0-1) of a security's off-exchange reported volume executed as short sales during regular trading hours</li>
<li><code class="python">Factors.SPECTRAL_TICK_FLOW_SIGNAL_EXECUTION_SCORE</code><code class="csharp">Factors.SpectralTickFlowSignalExecutionScore</code>: Normalized strength (non-negative) of the strongest recurring intraday execution rhythm in the security's daily tick flow, from a Fourier transform-like spectral decomposition of daily trades; higher means trade flow more strongly backed by an active, repeating execution signature</li>
<li><code class="python">Factors.EARNING_YIELD</code><code class="csharp">Factors.EarningYield</code>: Trailing earnings yield: Morningstar's ValuationRatios.EarningYield, diluted EPS divided by price (the inverse trailing P/E), so higher values indicate cheaper stocks relative to trailing earnings</li>
</ul>

<h4>Unlinked Factors</h4>
<p>Unlinked factors are factors that aren't tied to a specific tradable security, like weather data or interest rates. The Factors dataset provides the following unlinked factors:</p>
<ul>
<li><code class="python">Factors.UST_YIELD_1_MONTH</code><code class="csharp">Factors.UstYield1Month</code>: 1-month US Treasury yield curve rate, as published daily at 4:30 PM New York time</li>
<li><code class="python">Factors.VIX</code><code class="csharp">Factors.Vix</code>: CBOE Volatility Index (VIX) daily close: the market's expectation of 30-day S&P 500 volatility implied by index option prices, in annualized percentage points</li>
<li><code class="python">Factors.WTI_CRUDE_OIL</code><code class="csharp">Factors.WtiCrudeOil</code>: WTI crude oil price: the daily mid close of Oanda's West Texas Oil CFD, in US dollars per barrel, a continuous quote that tracks the front NYMEX contract without roll jumps</li>
<li><code class="python">Factors.MONETARY_CYCLE</code><code class="csharp">Factors.MonetaryCycle</code>: Monetary cycle: the monetary environment of Jensen, Mercer and Johnson (1996), +1 while the most recent change in the Federal Reserve's primary credit rate was a decrease (expansive) and -1 while it was an increase (restrictive), read from LEAN's risk-free interest rate model for every calendar day at midnight New York; the state flips on the day the model's rate changes</li>
<li><code class="python">Factors.M_2_GROWTH_1_MONTH</code><code class="csharp">Factors.M2Growth1Month</code>: M2 money supply growth from one monthly release to the next: the Federal Reserve's seasonally adjusted monthly M2 over its value for the month before, minus one, from FRED's series M2SL as currently revised; each month's value is stamped at 13:00 New York on the fourth Tuesday of the following month, when the Federal Reserve's H.6 release publishes it</li>
</ul>
Loading