Universe Selection

Legacy Fundamental Universes

Introduction

Warning: This API for Universe Selection was deprecated on November 2023. Please refer to the new Fundamental Selection API.

A FundamentalUniverseSelectionModel selects a universe of US Equities based on CoarseFundamental and, sometimes, FineFundamental data. If the model uses CoarseFundamental data, it relies on the US Equity Coarse Universe dataset. If the Universe Selection model uses FineFundamental data, it relies on the US Fundamental dataset.

These types of universes operate on daily schedule. In backtests, they select assets at midnight. In live trading, the selection timing depends on the data provider you use.

If you use a fundamental Universe Selection model, the only way to unsubscribe from a security is to return a list from the selection functions that doesn't include the security Symbol. The RemoveSecurity method doesn't work with these types of Universe Selection models.

Coarse Fundamental Selection

The CoarseFundamentalUniverseSelectionModel selects assets based on CoarseFundamental data. To use this model, define a coarse selection function. The coarse selection function receives a list of CoarseFundamental objects and returns a list of Symbol objects. The Symbol objects you return from the coarse selection function are the constituents of the universe.

public override void Initialize()
{
    UniverseSettings.Asynchronous = true;
    AddUniverseSelection(new CoarseFundamentalUniverseSelectionModel(SelectCoarse));
}

private IEnumerable<Symbol> SelectCoarse(IEnumerable<CoarseFundamental> coarse)
{
    // Return most liquid assets w/ fundamentals
    return coarse.Where(c => c.HasFundamentalData)
                 .OrderByDescending(c => c.DollarVolume)
                 .Take(100)
                 .Select(c => c.Symbol);
}
def Initialize(self) -> None:
    self.UniverseSettings.Asynchronous = True
    self.AddUniverseSelection(CoarseFundamentalUniverseSelectionModel(self.SelectCoarse))

def SelectCoarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
    selected = [c for c in coarse if c.HasFundamentalData]
    sorted_by_dollar_volume = sorted(selected, key=lambda c: c.DollarVolume, reverse=True)
    return [c.Symbol for c in sorted_by_dollar_volume[:100]] # Return most liquid assets w/ fundamentals

To move the coarse selection function outside of the algorithm class, create a universe selection model that inherits the CoarseFundamentalUniverseSelectionModel class.

// In Initialize
UniverseSettings.Asynchronous = true;
AddUniverseSelection(new MostLiquidFundamentalUniverseSelectionModel(UniverseSettings));

// Outside of the algorithm class
class MostLiquidFundamentalUniverseSelectionModel : CoarseFundamentalUniverseSelectionModel
{
    public MostLiquidFundamentalUniverseSelectionModel(UniverseSettings universeSettings)
        : base(default(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>>), universeSettings)
    {
    }

    public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
    {
        return coarse.Where(c => c.HasFundamentalData)
                     .OrderByDescending(c => c.DollarVolume)
                     .Take(100)
                     .Select(c => c.Symbol);
    }
}
# In Initialize
self.UniverseSettings.Asynchronous = True
self.AddUniverseSelection(MostLiquidFundamentalUniverseSelectionModel(self.UniverseSettings))

# Outside of the algorithm class
class MostLiquidFundamentalUniverseSelectionModel(CoarseFundamentalUniverseSelectionModel):
    def __init__(self, universe_settings: UniverseSettings) -> None:
        super().__init__(self.SelectCoarse, universe_settings)

    def SelectCoarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        selected = [c for c in coarse if c.HasFundamentalData]
        sorted_by_dollar_volume = sorted(selected, key=lambda c: c.DollarVolume, reverse=True)
        return [c.Symbol for c in sorted_by_dollar_volume[:100]]

To return the current universe constituents from the coarse selection function, return Universe.Unchanged.

To view the implementation of this model, see the LEAN GitHub repository.

Fine Fundamental Selection

The FineFundamentalUniverseSelectionModel selects assets based on CoarseFundamental and FineFundamental data. This is the only model that provides corporate fundamental data to your algorithm. To use this model, define a coarse selection function and a fine selection function. The coarse selection function receives a list of CoarseFundamental objects and returns a list of Symbol objects. To filter the CoarseFundamental down to the securities that have fundamental data, add a HasFundamentalData filter to the coarse selection function. The fine selection function receives a subset of FineFundamental objects generated from coarse selection results and returns a list of Symbol objects. The Symbol objects you return from the fine selection function are the constituents of the universe.

public override void Initialize()
{
    UniverseSettings.Asynchronous = true;
    AddUniverseSelection(new FineFundamentalUniverseSelectionModel(SelectCoarse, SelectFine));
}

private IEnumerable<Symbol> SelectCoarse(IEnumerable<CoarseFundamental> coarse)
{
    // Return most liquid assets w/ fundamentals
    return coarse.Where(c => c.HasFundamentalData)
                 .OrderByDescending(c => c.DollarVolume)
                 .Take(100)
                 .Select(c => c.Symbol);
}

private IEnumerable<Symbol> SelectFine(IEnumerable<FineFundamental> fine)
{
    // Return assets with lowest P/E ratios
    return fine.OrderBy(f => f.ValuationRatios.PERatio)
               .Take(10)
               .Select(f => f.Symbol);
}
def Initialize(self) -> None:
    self.UniverseSettings.Asynchronous = True
    self.AddUniverseSelection(FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine))

def SelectCoarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
    selected = [c for c in coarse if c.HasFundamentalData]
    sorted_by_dollar_volume = sorted(selected, key=lambda c: c.DollarVolume, reverse=True)
    return [c.Symbol for c in sorted_by_dollar_volume[:100]] # Return most liquid assets w/ fundamentals

def SelectFine(self, fine: List[FineFundamental]) -> List[Symbol]:
    sorted_by_pe_ratio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False)
    return [c.Symbol for c in sorted_by_pe_ratio[:10]] # Return assets with lowest P/E ratios

To move the selection functions outside of the algorithm class, create a universe selection model that inherits the FineFundamentalUniverseSelectionModel class.

// In Initialize
UniverseSettings.Asynchronous = true;
AddUniverseSelection(new LowPERatioUniverseSelectionModel(UniverseSettings));

// Outside of the algorithm class
class LowPERatioUniverseSelectionModel : FineFundamentalUniverseSelectionModel
{
    public LowPERatioUniverseSelectionModel(UniverseSettings universeSettings = null)
        : base(default(Func<IEnumerable<CoarseFundamental>, IEnumerable<Symbol>>), 
               default(Func<IEnumerable<FineFundamental>, IEnumerable<Symbol>>),
               universeSettings)
    {
    }

    public override IEnumerable<Symbol> SelectCoarse(QCAlgorithm algorithm, IEnumerable<CoarseFundamental> coarse)
    {
        return coarse.Where(c => c.HasFundamentalData)
                     .OrderByDescending(c => c.DollarVolume)
                     .Take(100)
                     .Select(c => c.Symbol);
    }

    public override IEnumerable<Symbol> SelectFine(QCAlgorithm algorithm, IEnumerable<FineFundamental> fine)
    {
        return fine.OrderBy(f => f.ValuationRatios.PERatio)
                   .Take(10)
                   .Select(f => f.Symbol);
    }
}
# In Initialize
self.UniverseSettings.Asynchronous = True
self.AddUniverseSelection(LowPERatioUniverseSelectionModel(self.UniverseSettings))

# Outside of the algorithm class
class LowPERatioUniverseSelectionModel(FineFundamentalUniverseSelectionModel):
    def __init__(self, universe_settings: UniverseSettings = None) -> None:
        super().__init__(self.SelectCoarse, self.SelectFine, universe_settings)

    def SelectCoarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        selected = [c for c in coarse if c.HasFundamentalData]
        sorted_by_dollar_volume = sorted(selected, key=lambda c: c.DollarVolume, reverse=True)
        return [c.Symbol for c in sorted_by_dollar_volume[:100]]

    def SelectFine(self, fine: List[FineFundamental]) -> List[Symbol]:
        sorted_by_pe_ratio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False)
        return [c.Symbol for c in sorted_by_pe_ratio[:10]]

To return the current universe constituents from the coarse or fine selection function, return Universe.Unchanged.

If you add a FineFundamentalUniverseSelectionModel to your algorithm, you can access fundamental data in the fine selection function or from the Equity object. To access fundamental data from the Equity object, use the Equity.Fundamentals property.

To view the implementation of this model, see the LEAN GitHub repository.

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: