---
title: "Requesting Data"
description: "If you create a data subscription, your algorithm receives data updates for that security or custom data source."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/securities/requesting-data
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/securities/requesting-data.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/03%20Securities/02%20Requesting%20Data
modified: 2026-11-01
index: https://www.quantconnect.com/llms.txt
---

# Requesting Data

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Securities > Requesting Data

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

## Introduction

When you add a security to your algorithm, your algorithm creates a data subscription and receives data updates for that security or [custom data source](https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/key-concepts.md).

## Add Assets

To create an Equity subscription, call the `add_equity` method and pass the `ticker` argument. The `ticker` argument represents the current ticker.

```python
# Add the SPY ETF.
equity = self.add_equity("SPY")
```

The `add_equity` method creates a subscription for a single Equity asset and adds it to your **user-defined** universe.

For more information about adding assets, see [Asset Classes](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes.md).

## Add Universes

Universe selection is the process of selecting a basket of assets you may trade. When you add a universe to your algorithm, LEAN sends a large dataset into a filter function you define. LEAN automatically subscribes to these new assets and adds them to your algorithm.

```python
# Use the _fundamental_filter_function to add the 100 most liquid stocks to the universe.
class MyFundamentalUniverseAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.universe_settings.asynchronous = True
        self.add_universe(self._fundamental_filter_function)

    # Get the top 100 stocks by dollar volume.
    def _fundamental_filter_function(self, fundamental: List[Fundamental]) -> List[Symbol]:
        sorted_by_dollar_volume = sorted(fundamental, key=lambda x: x.dollar_volume, reverse=True)
        return [c.symbol for c in sorted_by_dollar_volume[:100]]
```

For more information about universes, see [Universes](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/key-concepts.md).

## Resolutions

Resolution is the duration of time that's used to sample a data source. Market data is sampled and saved in disk with five resolutions. The `Resolution` enumeration has the following members:

- `Resolution.TICK`
- `Resolution.SECOND`
- `Resolution.MINUTE`
- `Resolution.HOUR`
- `Resolution.DAILY`

For more information about the resolutions of each asset class, follow these steps:

1. Open the [Asset Classes](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes.md) documentation.
2. Click an asset class.
3. Click **Requesting Data**.
4. Scroll down to the **Resolutions** section.

You can subscribe to daily resolution for an asset for updating indicator and subscribe to another asset for denser resolution for trading using the indicator.

```python
def initialize(self):
    self.add_equity("VIX", Resolution.DAILY)
    self.add_equity("SPY", Resolution.MINUTE)
```

To get data with multiple or customizable resolutions for an asset, use [consolidators](https://www.quantconnect.com/docs/v2/writing-algorithms/consolidating-data/getting-started.md).

## Fill Forward

Fill forward means if there is no data point for the current [slice](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices.md), LEAN uses the previous data point. Fill forward is the default data setting. If you disable fill forward, you may get [stale fills](https://www.quantconnect.com/docs/v2/writing-algorithms/reality-modeling/trade-fills/key-concepts.md#06-Stale-Fills) or you may see trade volume as zero.

For more information about how to enable and disable fill forward for each asset class, follow these steps:

1. Open the [Asset Classes](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes.md) documentation.
2. Click an asset class.
3. Click **Requesting Data**.
4. Scroll down to the **Fill Forward** section.

### Example: Disable Fill Forward Data

For some illiquid securities or alternative data, using forward filled data might not be an accurate estimation nor usable information. To avoid this, disable fill forward.

```python
def initialize(self):
    self.add_data(BrainSentiment7Days, symbol, fill_forward=False)
```

## Security Changed Events

When you add and remove assets, LEAN notifies your algorithm through the `on_securities_changed` event handler. The event handler receives a `SecurityChanges` object, which contains references to the added and removed securities. To access the added securities, iterate the `changes.added_securities` property. To get the removed securities, iterate the `changes.removed_securities` property.

```python
# Use on_securities_changed to know when an asset is added or removed.
def on_securities_changed(self, changes: SecurityChanges) -> None:
    # Iterate through the added assets.
    for security in changes.added_securities:
        self.debug(f"{self.time}: Added {security.symbol}")

    # Iterate through the removed assets.
    for security in changes.removed_securities:
        self.debug(f"{self.time}: Removed {security.symbol}")

        if security.invested:
            self.liquidate(security.symbol, "Removed from Universe")
```

The preceding example [liquidates](https://www.quantconnect.com/docs/v2/writing-algorithms/trading-and-orders/liquidating-positions.md) securities that leave the universe. You can use this event to create [indicators](https://www.quantconnect.com/docs/v2/writing-algorithms/indicators/key-concepts.md) when a new security enters the universe.

## Remove Subscriptions

To remove a security subscription, call the `remove_security` method.

```python
# Remove the security subscription.
self.remove_security(self._symbol)
```

The `remove_security` method cancels your open orders for the security and liquidates your holdings.

## Examples

The following examples demonstrate some common practices on the subject of requesting data.

### Example 1: Add Linked Alternative Data for Universe Constituents

Many traders select universe constituents and then allocate positions with two independent sets of logic. Position sizing usually requires additional information, like alternative data factors. To manage alternative data subscriptions for all the universe constituents, subscribe and unsubscribe from the data in the `on_securities_changed` method. The following example demonstrates adds the [KavoutCompositeFactorBundle](https://www.quantconnect.com/datasets/kavout-composite-factor-bundle) when assets enter the universe.

```python
class RequestSecuritiesDataAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        # Seed the price of each asset with its last known price to avoid trading errors.
        self.settings.seed_initial_prices = True
        # Add a universe of the 25 most liquid US Equities.
        self.add_universe(self.universe.top(25))

    def on_data(self, slice: Slice) -> None:
        # Invest by the updated Kavout Factor data.
        factor_data = slice.get(KavoutCompositeFactorBundle)
        if factor_data:
            sorted_by_factor_score = sorted(
                factor_data.items(),
                key=lambda x: x[1].growth + x[1].value_factor + x[1].quality + x[1].momentum + x[1].low_volatility,
                reverse=True
            )
            sorted_by_factor_score = [x for x in sorted_by_factor_score if self.securities[x[0].underlying].price][:10]
            top_factor_targets = [PortfolioTarget(x[0].underlying, 0.1) for x in sorted_by_factor_score]
            self.set_holdings(top_factor_targets, True)

    def on_securities_changed(self, changes: SecurityChanges) -> None:
        # Iterate securities that entered the universe.
        for security in changes.added_securities:
            # Subscribe to the factor data for the new security.
            # Save the alternative data symbol in the security object.
            security.alt_data_symbol = self.add_data(KavoutCompositeFactorBundle, security.symbol, Resolution.DAILY).symbol

        # Iterate securities that left the universe.
        for security in changes.removed_securities:
            # Unsubscribe from the altnerative data updates.
            self.remove_security(security.alt_data_symbol)
```

### Example 2: Add Linked Custom Data

QuantConnect Cloud has a lot of data, but not everything. To import some external data into your algorithm, define a [custom data source](https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/custom-securities/key-concepts.md) . The following algorithm loads Bitstamp's BTCUSD trading activity from a CSV file and plots it:

```python
# Define the algorithm.
class LinkedCustomDataExampleAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        # Add Bitcoin and the custom dataset.
        btc = self.add_crypto('BTCUSD')
        btc.data_symbol = self.add_data(Bitstamp, btc.symbol.value, Resolution.DAILY).symbol
        # Plot the price from the custom dataset.
        self.plot_indicator('BTC Price', self.identity(btc.data_symbol))

# Define the custom data source.
class Bitstamp(PythonData):
    # Define the get_source method to load the data from its location.
    def get_source(self, config, date, is_live_mode):
        source = "https://raw.githubusercontent.com/QuantConnect/Documentation/master/Resources/datasets/custom-data/bitstampusd.csv"
        # REMOTE_FILE in the next line means the data file in online storage.
        return SubscriptionDataSource(source, SubscriptionTransportMedium.REMOTE_FILE)

    # Define the reader method to parse the CSV rows.
    def reader(self, config, line, date, is_live_mode):
        # Ignore empty rows.
        if not line.strip():
            return None

        # Instantiate a new data object.
        coin = Bitstamp()
        coin.symbol = config.symbol

        # Ignore non-numeric lines.
        if not line[0].isdigit():
            return None

        # Split the CSV row by its commas.
        data = line.split(',')

        # Ignore invalid data.
        coin.value = float(data[4])
        if coin.value == 0:
            return None

        # Parse the row.
        coin.time = datetime.strptime(data[0], "%Y-%m-%d")
        coin.end_time = coin.time + timedelta(1)
        coin["Open"] = float(data[1])
        coin["High"] = float(data[2])
        coin["Low"] = float(data[3])
        coin["Close"] = coin.value
        coin["VolumeBTC"] = float(data[5])
        coin["VolumeUSD"] = float(data[6])
        coin["WeightedPrice"] = float(data[7])
        return coin
```
