Equity

Liquidity Universes

Introduction

A liquidity universe lets you select a set of stocks with the greatest dollar volume in the market.

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.DollarVolume.Top(50));
# Add the 50 stocks with the highest dollar volume.
self.universe_settings.asynchronous = True
self.add_universe(self.universe.dollar_volume.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()
    {
        // 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.DollarVolume.Top(10));
    }
}
class MinuteLiquidUniverseAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        # 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.dollar_volume.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, 1, 1);
        SetEndDate(2024, 7, 1);
        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.DollarVolume.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(), true);
    }
}
class AsynchronousLiquidUniverseAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 1, 1)
        self.set_end_date(2024, 7, 1)
        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.dollar_volume.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], True)

Other Examples

For more examples, see the following algorithms:

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: