Equity
Liquidity Universes
Create Universes
To add a dollar volume universe, call the Universe.DollarVolume.Topuniverse.dollar_volume.top helper method and pass the result to the AddUniverseadd_universe method.
// Add the 50 stocks with the highest dollar volume. UniverseSettings.Asynchronous = true; AddUniverse(Universe.Top(50));
# Add the 50 stocks with the highest dollar volume. self.universe_settings.asynchronous = True self.add_universe(self.universe.top(50))
Selection Frequency
Equity universes run on a daily basis by default. To adjust the selection schedule, see Schedule.
Examples
The following examples demonstrate some common liquidity universes for US Equities.
Example 1: Minute-Resolution Universe
The following algorithm asynchronously selects the 10 most liquid US Equities as the universe. It uses minute resolution data to provide the most realistic results.
public class MinuteLiquidUniverseAlgorithm : QCAlgorithm
{
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
// Use asynchronous universe selection to speed up your algorithm.
UniverseSettings.Asynchronous = true;
// Use minute resolution data so orders fill at realistic prices.
UniverseSettings.Resolution = Resolution.Minute;
// Add a universe of the 10 most liquid US Equities.
AddUniverse(Universe.Top(10));
}
} class MinuteLiquidUniverseAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
# Use asynchronous universe selection to speed up your algorithm.
self.universe_settings.asynchronous = True
# Use minute resolution data so orders fill at realistic prices.
self.universe_settings.resolution = Resolution.MINUTE
# Add a universe of the 10 most liquid US Equities.
self.add_universe(self.universe.top(10))
Example 2: Trade Liquid Assets off Bollinger Bands
The following algorithm asynchronously selects the 500 most liquid US Equities as the universe. Each day, it forms a portfolio of the assets in the universe that are below their lower Bollinger Band .
public class AsynchronousLiquidUniverseAlgorithm : QCAlgorithm
{
private Universe _universe;
public override void Initialize()
{
SetStartDate(2024, 9, 1);
SetEndDate(2024, 12, 31);
Settings.AutomaticIndicatorWarmUp = true;
// When a new asset enters the universe, seed its current price so you can trade it right away.
SetSecurityInitializer(
new BrokerageModelSecurityInitializer(BrokerageModel, new FuncSecuritySeeder(GetLastKnownPrices))
);
// Use asynchronous universe selection to speed up the algorithm.
UniverseSettings.Asynchronous = true;
// Use daily data. It doesn't affect accuracy since the trades fill at the daily market open.
UniverseSettings.Resolution = Resolution.Daily;
// Add a universe of the 500 most liquid Equities.
_universe = AddUniverse(Universe.Top(500));
}
public override void OnSecuritiesChanged(SecurityChanges changes)
{
// Create Bollinger Band indicators for the universe constituents.
foreach (var security in changes.AddedSecurities)
{
(security as dynamic).BB = BB(security.Symbol, 60, 2);
}
// Deregister the indicators when assets leave the universe.
foreach (var security in changes.RemovedSecurities)
{
DeregisterIndicator((security as dynamic).BB);
}
}
public override void OnData(Slice slice)
{
// Ensure there are TradeBar objects in the current slice.
if (slice.Bars.Count == 0)
{
return;
}
// Select the Equities that are below their lower Bollinger Band.
var selected = _universe.Selected
.Select(symbol => (Securities[symbol] as dynamic))
.Where(security => security.BB.IsReady && security.Price != 0 && security.Price < security.BB.LowerBand.Current.Value);
// Form an equal-weighted portfolio with the selected assets.
var weight = 1m / selected.Count();
SetHoldings(selected.Select(security => new PortfolioTarget(security.Symbol, weight)).ToList(), liquidateExistingHoldings: true);
}
} class AsynchronousLiquidUniverseAlgorithm(QCAlgorithm):
def initialize(self) -> None:
self.set_start_date(2024, 9, 1)
self.set_end_date(2024, 12, 31)
self.settings.automatic_indicator_warm_up = True
# When a new asset enters the universe, seed its current price so you can trade it right away.
self.set_security_initializer(
BrokerageModelSecurityInitializer(self.brokerage_model, FuncSecuritySeeder(self.get_last_known_prices))
)
# Use asynchronous universe selection to speed up the algorithm.
self.universe_settings.asynchronous = True
# Use daily data. It doesn't affect accuracy since the trades fill at the daily market open.
self.universe_settings.resolution = Resolution.DAILY
# Add a universe of the 500 most liquid Equities.
self._universe = self.add_universe(self.universe.top(500))
def on_securities_changed(self, changes: SecurityChanges) -> None:
# Create Bollinger Band indicators for the universe constituents.
for security in changes.added_securities:
security.bb = self.bb(security.symbol, 60, 2)
# Deregister the indicators when assets leave the universe.
for security in changes.removed_securities:
self.deregister_indicator(security.bb)
def on_data(self, slice: Slice) -> None:
# Ensure there are TradeBar objects in the current slice.
if not slice.bars:
return
# Select the Equities that are below their lower Bollinger Band.
securities = [self.securities[symbol] for symbol in self._universe.selected]
selected = [
security for security in securities
if security.bb.is_ready and security.price and security.price < security.bb.lower_band.current.value
]
# Form an equal-weighted portfolio with the selected assets.
weight = 1 / len(selected)
self.set_holdings([PortfolioTarget(security.symbol, weight) for security in selected], liquidate_existing_holdings=True)
Other Examples
For more examples, see the following algorithms: