---
title: "Custom Data"
description: "Learn how to import, request and handle custom data in the research environment in QuantConnect"
canonical: https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data
markdown: https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/04%20Research%20Environment/03%20Datasets/26%20Custom%20Data
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# Custom Data

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Research Environment](https://www.quantconnect.com/docs/v2/research-environment.md) > Datasets > Custom Data

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

## Introduction

This page explains how to request, manipulate, and visualize historical user-defined custom data.

## Define Custom Data

You must format the data file into chronological order before you define the custom data class.

To define a custom data class, extend the `PythonData` class and override the [GetSource](https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/key-concepts.md#04-Set-Data-Sources) and [Reader](https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/key-concepts.md#05-Parse-Custom-Data) methods.

```python
class Nifty(PythonData):
    '''NIFTY Custom Data Class'''
    def get_source(self, config: SubscriptionDataConfig, date: datetime, is_live_mode: bool) -> SubscriptionDataSource:
        url = "http://cdn.quantconnect.com.s3.us-east-1.amazonaws.com/uploads/CNXNIFTY.csv"
        return SubscriptionDataSource(url, SubscriptionTransportMedium.REMOTE_FILE)

    def reader(self, config: SubscriptionDataConfig, line: str, date: datetime, is_live_mode: bool) -> BaseData:
        if not (line.strip() and line[0].isdigit()): return None

        # New Nifty object
        index = Nifty()
        index.symbol = config.symbol

        try:
            # Example File Format:
            # Date,       Open       High        Low       Close     Volume      Turnover
            # 2011-09-13  7792.9    7799.9     7722.65    7748.7    116534670    6107.78
            data = line.split(',')
            index.time = datetime.strptime(data[0], "%Y-%m-%d")
            index.end_time = index.time + timedelta(days=1)
            index.value = data[4]
            index["Open"] = float(data[1])
            index["High"] = float(data[2])
            index["Low"] = float(data[3])
            index["Close"] = float(data[4])

        except:
            pass

        return index
```

## Create Subscriptions

You need to [define a custom data class](https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data.md#03-Define-Custom-Data) before you can subscribe to it.

Follow these steps to subscribe to custom dataset:

1. Create a `QuantBook`.
   ```python
   qb = QuantBook()
   ```
2. Call the `add_data` method with a ticker and then save a reference to the data `Symbol`.
   ```python
   symbol = qb.add_data(Nifty, "NIFTY").symbol
   ```
   Custom data has its own resolution, so you don't need to specify it.

## Get Historical Data

You need a [subscription](https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data.md#04-Create-Subscriptions) before you can request historical data for a security. You can request an amount of historical data based on a trailing number of bars, a trailing period of time, or a defined period of time.

Before you request data, call `set_start_date` method with a `datetime` to reduce the risk of [look-ahead bias](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/glossary.md#18-look-ahead-bias).

```python
qb.set_start_date(2014, 7, 29)
```

If you call the `set_start_date` method, the date that you pass to the method is the latest date for which your history requests will return data.

### Trailing Number of Bars

Call the `history` method with a symbol, integer, and resolution to request historical data based on the given number of trailing bars and resolution.

```python
history = qb.history(symbol, 10)
```

This method returns the most recent bars, excluding periods of time when the exchange was closed.

### Trailing Period of Time

Call the `history` method with a symbol, `timedelta`, and resolution to request historical data based on the given trailing period of time and resolution.

```python
history = qb.history(symbol, timedelta(days=10))
```

This method returns the most recent bars, excluding periods of time when the exchange was closed.

### Defined Period of Time

Call the `history` method with a symbol, start `datetime`, end `datetime`, and resolution to request historical data based on the defined period of time and resolution. The start and end times you provide are based in the [notebook time zone](https://www.quantconnect.com/docs/v2/research-environment/initialization.md#04-Set-Time-Zone).

```python
start_time = datetime(2013, 7, 29)
end_time = datetime(2014, 7, 29)
history = qb.history(symbol, start_time, end_time)
```

This method returns the bars that are timestamped within the defined period of time.

In all of the cases above, the `history` method returns a `DataFrame` with a `MultiIndex`.

![Dataframe of custom NIFTY data from history call](https://cdn.quantconnect.com/i/tu/research-history-custom-full.png)

### Download Method

To download the data directly from the remote file location instead of using your custom data class, call the `download` method with the data URL.

```python
content = qb.download("http://cdn.quantconnect.com.s3.us-east-1.amazonaws.com/uploads/CNXNIFTY.csv")
```

Follow these steps to convert the content to a `DataFrame`:

1. Import the `StringIO` from the `io` library.
   ```python
   from io import StringIO
   ```
2. Create a `StringIO`.
   ```python
   data = StringIO(content)
   ```
3. Call the `read_csv` method.
   ```python
   dataframe = pd.read_csv(data, index_col=0)
   ```

![Dataframe of custom NIFTY data from io read csv](https://cdn.quantconnect.com/i/tu/research-history-custom-download.png)

## Wrangle Data

You need some [historical data](https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data.md#05-Get-Historical-Data) to perform wrangling operations. To display `pandas` objects, run a cell in a notebook with the `pandas` object as the last line. To display other data formats, call the `print` method.

The `DataFrame` that the `history` method returns has the following index levels:

1. Dataset `Symbol`
2. The `end_time` of the data sample

The columns of the `DataFrame` are the data properties.

![Dataframe of custom NIFTY data](https://cdn.quantconnect.com/i/tu/custom-research-data-1.jpg)

To select the data of a single dataset, index the `loc` property of the `DataFrame` with the data `Symbol`.

```python
history.loc[symbol]
```

![Dataframe of custom NIFTY data with symbol selected](https://cdn.quantconnect.com/i/tu/custom-research-data-2.jpg)

To select a column of the `DataFrame`, index it with the column name.

```python
history.loc[symbol]['close']
```

![Close price series of custom NIFTY data](https://cdn.quantconnect.com/i/tu/custom-research-data-3.jpg)

## Plot Data

You need some [historical custom data](https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data.md#05-Get-Historical-Data) to produce plots. You can use many of the [supported plotting libraries](https://www.quantconnect.com/docs/v2/research-environment/charting.md) to visualize data in various formats. For example, you can plot candlestick and line charts.

### Candlestick Chart

Follow these steps to plot candlestick charts:

1. Get some [historical data](https://www.quantconnect.com/docs/v2/research-environment/datasets/custom-data.md#05-Get-Historical-Data).
   ```python
   history = qb.history(Nifty, datetime(2013, 7, 1), datetime(2014, 7, 31)).loc[symbol]
   ```
2. Import the `plotly` library.
   ```python
   import plotly.graph_objects as go
   ```
3. Create a `Candlestick`.
   ```python
   candlestick = go.Candlestick(x=history.index,
                                open=history['open'],
                                high=history['high'],
                                low=history['low'],
                                close=history['close'])
   ```
4. Create a `Layout`.
   ```python
   layout = go.Layout(title=go.layout.Title(text=f'{symbol} OHLC'),
                      xaxis_title='Date',
                      yaxis_title='Price',
                      xaxis_rangeslider_visible=False)
   ```
5. Create a `Figure`.
   ```python
   fig = go.Figure(data=[candlestick], layout=layout)
   ```
6. Show the `Figure`.
   ```python
   fig.show()
   ```
   Candlestick charts display the open, high, low, and close prices of the security.

![Candlestick plot of custom NIFTY OHLC](https://cdn.quantconnect.com/i/tu/research-history-custom-candlestick.png)

### Line Chart

Follow these steps to plot line charts using built-in methods:

1. Select data to plot.
   ```python
   values = history['value'].unstack(level=0)
   ```
2. Call the `plot` method on the `pandas` object.
   ```python
   values.plot(title="Value", figsize=(15, 10))
   ```
3. Show the plot.
   ```python
   plt.show()
   ```
   Line charts display the value of the property you selected in a time series.

![Line chart of custom NIFTY value](https://cdn.quantconnect.com/i/tu/research-history-custom-lineplot.png)
