QuantConnect
Spectral Tick Flow Signal
Introduction
The QuantConnect Spectral Tick-Flow Signal dataset provides daily signals for US Equities based on a proprietary Fourier transform-like algorithm applied to US Equity tick data. The dataset is designed to summarize recurring intraday trade-flow patterns and potential execution-flow activity into a compact set of fields that can be used for screening, ranking, and research across a large-cap US Equity universe.
The data covers 500 US Equities across S&P 500 constituents and SPY, starts in June 2009, and is delivered on a daily frequency. Each data point is linked to a US Equity and represents one security for one trading day. The dataset also includes a daily universe file, enabling algorithms to rank or filter the full cross-section without manually subscribing to every symbol.
The headline score is ExecutionScore, a non-negative value that reflects the strength of the detected execution-flow signal for a security on a given day. Larger values indicate stronger signal activity relative to other securities or dates. The SignatureCount field can be used to distinguish confirmed signal events from lower-confidence observations.
Typical use is to request the daily cross-section, rank securities by ExecutionScore or related fields, and use the results as an input to a long-only, long-short, market-neutral, or risk-management strategy.
This dataset depends on the US Equity Security Master dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes.
For more information about the Spectral Tick Flow Signal dataset, including CLI commands and pricing, see the dataset listing.
About the Provider
QuantConnect was founded in 2012 to serve quants everywhere with the best possible algorithmic trading technology. Seeking to disrupt a notoriously closed-source industry, QuantConnect takes a radically open-source approach to algorithmic trading. Through the QuantConnect web platform, more than 50,000 quants are served every month.
Getting Started
The following snippet demonstrates how to request data from the Spectral Tick-Flow Signal dataset:
self._equity = self.add_equity("AAPL", Resolution.DAILY)
self.dataset_symbol = self.add_data(SpectralTickFlowSignal, self._equity).symbol _equity = AddEquity("AAPL", Resolution.Daily).Symbol;
_datasetSymbol = AddData<SpectralTickFlowSignal>(_equity).Symbol;
Data Summary
The following table describes the dataset properties:
| Property | Value |
|---|---|
| Start Date | June 2009 |
| Asset Coverage* | 500 US Equities (S&P 500 constituents and SPY) |
| Data Density | Sparse |
| Resolution | Daily |
| Timezone | EST |
The coverage includes S&P 500 constituents and SPY over the dataset history. The universe changes over time with constituent membership.
This dataset depends on the US Equity Security Master dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes.
Requesting Data
To add Spectral Tick-Flow Signal data to your algorithm, call the AddDataadd_data method. Save a reference to the dataset Symbol so you can access the data later in your algorithm.
class SpectralTickFlowSignalDataAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2026, 6, 16)
self.set_end_date(2026, 6, 24)
self.set_cash(100000)
self._equity = self.add_equity("AAPL", Resolution.DAILY)
self._dataset_symbol = self.add_data(SpectralTickFlowSignal, self._equity).symbol public class SpectralTickFlowSignalDataAlgorithm : QCAlgorithm
{
private Symbol _symbol, _datasetSymbol;
public override void Initialize()
{
SetStartDate(2026, 6, 16);
SetEndDate(2026, 6, 24);
SetCash(100000);
_equity = AddEquity("AAPL", Resolution.Daily).Symbol;
_datasetSymbol = AddData<SpectralTickFlowSignal>(_equity).Symbol;
}
}
Accessing Data
To add Spectral Tick-Flow Signal data to your algorithm, call the AddDataadd_data method. Save a reference to the dataset Symbol so you can access the data later in your algorithm.
class SpectralTickFlowSignalDataAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2026, 6, 16)
self.set_end_date(2026, 6, 24)
self.set_cash(100000)
self._equity = self.add_equity("AAPL", Resolution.DAILY)
self._dataset_symbol = self.add_data(SpectralTickFlowSignal, self._equity).symbol public class SpectralTickFlowSignalDataAlgorithm : QCAlgorithm
{
private Symbol _equity, _datasetSymbol;
public override void Initialize()
{
SetStartDate(2026, 6, 16);
SetEndDate(2026, 6, 24);
SetCash(100000);
_equity = AddEquity("AAPL", Resolution.Daily).Symbol;
_datasetSymbol = AddData<SpectralTickFlowSignal>(_equity).Symbol;
}
}
Historical Data
To get historical Spectral Tick-Flow Signal data, call the Historyhistory method with the dataset Symbol. If there is no data in the period you request, the history result is empty.
# DataFrame history_df = self.history(self._dataset_symbol, 100, Resolution.DAILY) # Dataset objects history_bars = self.history[SpectralTickFlowSignal](self._dataset_symbol, 100, Resolution.DAILY)
var history = History<SpectralTickFlowSignal>(_datasetSymbol, 100, Resolution.Daily);
For more information about historical data, see History Requests.
Universe Selection
To select a dynamic universe of US Equities based on Spectral Tick-Flow Signal data, call the AddUniverseadd_universe method with the SpectralTickFlowSignalUniverse class and a selection function. Each daily universe file delivers the full cross-section, so you can rank or filter every covered name by any signal field, for example, the names with the strongest confirmed algorithmic-execution intensity.
def initialize(self) -> None:
self.universe_settings.resolution = Resolution.DAILY
self._universe = self.add_universe(SpectralTickFlowSignalUniverse, self._select_assets)
def _select_assets(self, alt_coarse: List[SpectralTickFlowSignalUniverse]) -> List[Symbol]:
confirmed = [d for d in alt_coarse if d.signature_count > 0]
return [d.symbol for d in sorted(confirmed, key=lambda d: d.execution_score)[-10:]] private Universe _universe;
public override void Initialize()
{
UniverseSettings.Resolution = Resolution.Daily;
_universe = AddUniverse<SpectralTickFlowSignalUniverse>(altCoarse =>
{
return altCoarse
.OfType<SpectralTickFlowSignalUniverse>()
.Where(d => d.SignatureCount > 0)
.OrderBy(d => d.ExecutionScore)
.TakeLast(10)
.Select(d => d.Symbol);
});
}
Remove Subscriptions
To remove a subscription, call the RemoveSecurityremove_security method.
self.remove_security(self.dataset_symbol)
RemoveSecurity(_datasetSymbol);
If you subscribe to Spectral Tick-Flow Signal data for assets in a dynamic universe, remove the dataset subscription when the asset leaves your universe. To view a common design pattern, see Track Security Changes.
Example Applications
The QuantConnect Spectral Tick-Flow Signal dataset enables you to test strategies using daily tick-flow signals provided by QuantConnect. Examples include the following strategies:
- Ranking a large-cap US Equity universe by each security's
ExecutionScore - Buying securities with the strongest detected execution-flow activity
- Building a market-neutral strategy based on the top N and bottom N securities in the daily signal universe
- Using tick-flow signal strength as a filter, confirmation variable, or position-sizing input in an existing Equity strategy
Classic Algorithm Example
The following example algorithm buys Apple when its Spectral Tick-Flow Signal ExecutionScore clears a threshold, signaling active algorithmic-execution flow. Otherwise, it remains in cash.
from AlgorithmImports import *
class SpectralTickFlowSignalAlgorithm(QCAlgorithm):
execution_score_threshold = 15
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100000)
# AAPL is both the traded security and the equity the custom signal is linked to.
self._aapl = self.add_equity("AAPL", Resolution.DAILY)
self.dataset_symbol = self.add_data(SpectralTickFlowSignal, self._aapl).symbol
def on_data(self, data: Slice) -> None:
# Require current signal and equity data to avoid stale fills.
if self.dataset_symbol not in data:
return
# Hold AAPL on strong algorithmic-execution intensity, otherwise stand aside.
execution_score = data[self.dataset_symbol].execution_score
target_holdings = 1 if execution_score > self.execution_score_threshold else 0
if target_holdings != self.portfolio.invested:
self.set_holdings(self._aapl, target_holdings) public class SpectralTickFlowSignalAlgorithm : QCAlgorithm
{
private Equity _aapl;
private Symbol _datasetSymbol;
private const decimal ExecutionScoreThreshold = 15m;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
SetCash(100000);
// AAPL is both the traded security and the equity the custom signal is linked to.
_aapl = AddEquity("AAPL", Resolution.Daily);
_datasetSymbol = AddData<SpectralTickFlowSignal>(_aapl.Symbol).Symbol;
}
public override void OnData(Slice slice)
{
// Require current signal and equity data to avoid stale fills.
if (!slice.ContainsKey(_datasetSymbol))
{
return;
}
// Hold AAPL on strong algorithmic-execution intensity, otherwise stand aside.
decimal executionScore = slice[_datasetSymbol].ExecutionScore;
var targetHoldings = executionScore > ExecutionScoreThreshold ? 1 : 0;
if (targetHoldings == 1 != Portfolio.Invested)
{
SetHoldings(_aapl.Symbol, targetHoldings);
}
}
}
Framework Algorithm Example
The following example algorithm creates a dynamic universe of US Equities that have a confirmed algorithmic-execution signature. It then buys the subset of Equities with the strongest execution intensity and forms an equal-weighted portfolio.
from AlgorithmImports import *
class SpectralTickFlowSignalAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.set_cash(100000)
self.settings.seed_initial_prices = True
self.universe_settings.resolution = Resolution.DAILY
# Filter to the confirmed execution signatures with the strongest intensity.
self.add_universe(SpectralTickFlowSignalUniverse, self.universe_selection)
self.add_alpha(SpectralTickFlowSignalAlphaModel())
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
self.add_risk_management(NullRiskManagementModel())
self.set_execution(ImmediateExecutionModel())
def universe_selection(self, alt_coarse: List[SpectralTickFlowSignalUniverse]) -> List[Symbol]:
# Keep only confirmed execution signatures, ranked by intensity.
confirmed = [d for d in alt_coarse if d.signature_count > 0]
return [d.symbol for d in sorted(confirmed, key=lambda d: d.execution_score)[-50:]]
class SpectralTickFlowSignalAlphaModel(AlphaModel):
def update(self, algorithm: QCAlgorithm, slice: Slice) -> List[Insight]:
insights = []
for dataset_symbol, data_point in slice.get(SpectralTickFlowSignal).items():
security = algorithm.securities[dataset_symbol.underlying]
# Buy names with a confirmed execution signature, liquidate otherwise.
target_direction = InsightDirection.UP if data_point.signature_count > 0 else InsightDirection.FLAT
if security.price and target_direction == InsightDirection.UP and not security.invested:
insights.append(Insight.price(security, timedelta(7), target_direction))
return insights
def on_securities_changed(self, algorithm: QCAlgorithm, changes: SecurityChanges) -> None:
for security in changes.added_securities:
# Subscribe to the daily signal feed for the added equity.
dataset = algorithm.add_data(SpectralTickFlowSignal, security, Resolution.DAILY)
security.dataset_symbol = dataset.symbol
for security in changes.removed_securities:
# Unsubscribe from the Spectral Tick-Flow Signal feed.
algorithm.remove_security(security.dataset_symbol) public class SpectralTickFlowSignalAlgorithm : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
SetCash(100000);
Settings.SeedInitialPrices = true;
UniverseSettings.Resolution = Resolution.Daily;
// Filter to the confirmed execution signatures with the strongest intensity.
AddUniverse<SpectralTickFlowSignalUniverse>(altCoarse => altCoarse
.Select(d => d as SpectralTickFlowSignalUniverse)
.Where(d => d.SignatureCount > 0)
.OrderBy(d => d.ExecutionScore)
.TakeLast(50)
.Select(d => d.Symbol)
);
AddAlpha(new SpectralTickFlowSignalAlphaModel());
SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
AddRiskManagement(new NullRiskManagementModel());
SetExecution(new ImmediateExecutionModel());
}
}
public class SpectralTickFlowSignalAlphaModel : AlphaModel
{
public override IEnumerable<Insight> Update(QCAlgorithm algorithm, Slice slice)
{
var insights = new List<Insight>();
foreach (var (datasetSymbol, dataPoint) in slice.Get<SpectralTickFlowSignal>())
{
var security = algorithm.Securities[datasetSymbol.Underlying];
// Buy names with a confirmed execution signature, liquidate otherwise.
var targetDirection = dataPoint.SignatureCount > 0 ? InsightDirection.Up : InsightDirection.Flat;
if (security.Price != 0 && targetDirection == InsightDirection.Up && !security.Holdings.Invested)
{
insights.Add(Insight.Price(security.Symbol, TimeSpan.FromDays(7), targetDirection));
}
}
return insights;
}
public override void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges changes)
{
foreach (var security in changes.AddedSecurities)
{
// Subscribe to the daily signal feed for the added equity.
var dataset = algorithm.AddData<SpectralTickFlowSignal>(security.Symbol, Resolution.Daily);
security.Set("DatasetSymbol", dataset.Symbol);
}
foreach (var security in changes.RemovedSecurities)
{
// Unsubscribe from the Spectral Tick-Flow Signal feed.
algorithm.RemoveSecurity(security.Get<Symbol>("DatasetSymbol"));
}
}
}
Research Example
The following example lists US Equities with confirmed algorithmic-execution signatures, ranked by execution intensity.
#r "../QuantConnect.DataSource.SpectralTickFlowSignal.dll"
using QuantConnect.DataSource;
var qb = new QuantBook();
// Requesting data
var aapl = qb.AddEquity("AAPL", Resolution.Daily).Symbol;
var symbol = qb.AddData<SpectralTickFlowSignal>(aapl).Symbol;
// Historical data
var history = qb.History<SpectralTickFlowSignal>(symbol, 30, Resolution.Daily);
foreach (SpectralTickFlowSignal signal in history)
{
Console.WriteLine($"{signal} at {signal.EndTime}");
}
// Add Universe Selection
IEnumerable<Symbol> UniverseSelection(IEnumerable<BaseData> altCoarse)
{
return (from d in altCoarse.OfType<SpectralTickFlowSignalUniverse>()
where d.SignatureCount > 0
orderby d.ExecutionScore descending select d.Symbol).Take(10);
}
var universe = qb.AddUniverse<SpectralTickFlowSignalUniverse>(UniverseSelection);
// Historical Universe data
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-5), qb.Time);
foreach (var signals in universeHistory)
{
foreach (SpectralTickFlowSignalUniverse signal in signals)
{
Console.WriteLine($"{signal.Symbol} execution score at {signal.EndTime}: {signal.ExecutionScore}");
}
} qb = QuantBook()
# Requesting Data
aapl = qb.add_equity("AAPL", Resolution.DAILY)
symbol = qb.add_data(SpectralTickFlowSignal, aapl).symbol
# Historical data
history = qb.history(SpectralTickFlowSignal, symbol, 30, Resolution.DAILY)
for (symbol, time), row in history.iterrows():
print(f"{symbol} execution score at {time}: {row['execution_score']}")
# Add Universe Selection
def universe_selection(alt_coarse: List[SpectralTickFlowSignalUniverse]) -> List[Symbol]:
confirmed = [d for d in alt_coarse if d.signature_count > 0]
return [d.symbol for d in sorted(confirmed, key=lambda d: d.execution_score, reverse=True)[:10]]
universe = qb.add_universe(SpectralTickFlowSignalUniverse, universe_selection)
# Historical Universe data
universe_history = qb.universe_history(universe, qb.time-timedelta(5), qb.time)
for (_, time), signals in universe_history.items():
for signal in signals:
print(f"{signal.symbol} execution score at {signal.end_time}: {signal.execution_score}")
Data Point Attributes
The Spectral Tick-Flow Signal dataset provides SpectralTickFlowSignal and SpectralTickFlowSignalUniverse objects.
SpectralTickFlowSignal Attributes
SpectralTickFlowSignal objects have the following attributes:
SpectralTickFlowSignalUniverse Attributes
SpectralTickFlowSignalUniverse objects have the following attributes: