---
title: "Legacy Fundamental Universes"
description: "A Fundamental Universe selection model selects a universe of US Equities based on coarse and fine fundamental data."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/legacy-fundamental-universes
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/legacy-fundamental-universes.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/34%20Algorithm%20Framework/02%20Universe%20Selection/09%20Legacy%20Fundamental%20Universes
modified: 2026-10-30
index: https://www.quantconnect.com/llms.txt
---

# Legacy Fundamental Universes

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Algorithm Framework > Universe Selection > Legacy Fundamental Universes

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

> Warning: This API for Universe Selection was deprecated on November 2023. Please refer to the [new Fundamental Selection API](https://www.quantconnect.com/docs/v2/writing-algorithms/algorithm-framework/universe-selection/fundamental-universes.md).

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](https://www.quantconnect.com/datasets/quantconnect-us-coarse-universe-constituents) dataset. If the Universe Selection model uses `FineFundamental` data, it relies on the [US Fundamental](https://www.quantconnect.com/datasets/morning-star-us-fundamentals) 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](https://www.quantconnect.com/docs/v2/cloud-platform/datasets.md) 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 `remove_security` 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.

```python
# Set asynchronous universe settings for improved speed and use CoarseFundamentalUniverseSelectionModel with a custom function to select the top 100 most liquid assets with available fundamental data, ensuring the universe consists of liquid and fundamentally strong securities for stable returns.
def initialize(self) -> None:
    self.universe_settings.asynchronous = True
    self.add_universe_selection(CoarseFundamentalUniverseSelectionModel(self.select_coarse))

def select_coarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
    selected = [c for c in coarse if c.has_fundamental_data]
    sorted_by_dollar_volume = sorted(selected, key=lambda c: c.dollar_volume, 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.

```python
# Move the coarse selection function outside of the algorithm class by creating a custom universe selection model inheriting from CoarseFundamentalUniverseSelectionModel, allowing for modification and reusability of the selection logic.
self.universe_settings.asynchronous = True
self.add_universe_selection(MostLiquidFundamentalUniverseSelectionModel(self.universe_settings))

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

    def select_coarse(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        selected = [c for c in coarse if c.has_fundamental_data]
        sorted_by_dollar_volume = sorted(selected, key=lambda c: c.dollar_volume, 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`.

For more information about this model, see the [class reference](https://www.lean.io/docs/v2/lean-engine/class-reference/py/QuantConnect/Algorithm/Framework/Selection/CoarseFundamentalUniverseSelectionModel/) and [implementation](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Framework/Selection/CoarseFundamentalUniverseSelectionModel.cs).

## 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 `has_fundamental_data` 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.

```python
# FineFundamentalUniverseSelectionModel integrates corporate fundamental data into the algorithm through a two-step filtering process: coarse selection ensures liquidity and fundamental data availability, while fine selection focuses on valuation metrics, refining the universe of selected stocks.
def initialize(self) -> None:
    self.universe_settings.asynchronous = True
    self.add_universe_selection(FineFundamentalUniverseSelectionModel(self.select_coarse, self.select_fine))

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

def select_fine(self, fine: List[FineFundamental]) -> List[Symbol]:
    sorted_by_pe_ratio = sorted(fine, key=lambda x: x.valuation_ratios.pe_ratio, 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.

```python
# Create a custom universe selection model inheriting from FineFundamentalUniverseSelectionModel to move both coarse and fine selection functions outside the algorithm class, enabling easier modification and reusability of the filtering and ranking logic.
self.universe_settings.asynchronous = True
self.add_universe_selection(LowPERatioUniverseSelectionModel(self.universe_settings))

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

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

    def select_fine(self, fine: List[FineFundamental]) -> List[Symbol]:
        sorted_by_pe_ratio = sorted(fine, key=lambda x: x.valuation_ratios.pe_ratio, 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 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 fundamentals` property.

For more information about this model, see the [class reference](https://www.lean.io/docs/v2/lean-engine/class-reference/py/QuantConnect/Algorithm/Framework/Selection/FineFundamentalUniverseSelectionModel/) and [implementation](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Framework/Selection/FineFundamentalUniverseSelectionModel.cs).
