---
title: "JSON Format Example"
description: "This page explains how to import custom data of a single security sourced in JSON format."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/custom-securities/json-format-example
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/custom-securities/json-format-example.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/16%20Importing%20Data/02%20Streaming%20Data/02%20Custom%20Securities/03%20JSON%20Format%20Example
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# JSON Format Example

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Importing Data > Streaming Data > Custom Securities > JSON Format Example

> 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 import custom data of a single security sourced in `JSON` format.

## Data Format

The following code snippet shows an example `JSON` file

```
[
    {
      "Date": "1997-01-01",
      "Open": 905.2,
      "High": 941.4,
      "Low": 905.2,
      "Close": 939.55,
      "SharesTraded": 38948210,
      "Tur11er(Rs.Cr)": 978.21
    },
    {
      "Date": "1997-01-02",
      "Open": 941.95,
      "High": 944,
      "Low": 925.05,
      "Close": 927.05,
      "SharesTraded": 49118380,
      "Tur11er(Rs.Cr)": 1150.42
    },
    ...
    {
      "Date": "2014-07-25",
      "Open": 7828.2,
      "High": 7840.95,
      "Low": 7748.6,
      "Close": 7790.45,
      "SharesTraded": 153936037,
      "Tur11er(Rs.Cr)": 7827.61
    },
    {
      "Date": "2014-07-28",
      "Open": 7792.9,
      "High": 7799.9,
      "Low": 7722.65,
      "Close": 7748.7,
      "SharesTraded": 116534670,
      "Tur11er(Rs.Cr)": 6107.78
    }
]
```

The data in the file must be in chronological order.

## Define Custom Types

To define a custom data type, inherit 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.

If you need to create multiple objects in your `reader` method from a single `line`, follow these steps:

1. In the `get_source` method, pass `FileFormat.UNFOLDING_COLLECTION` as the third argument to the `SubscriptionDataSource` constructor.
2. In the `reader` method, order the objects by their timestamp and then return a `BaseDataCollection(end_time, config.symbol, objects)` where `objects` is a list of your custom data objects.

```python
class MyCustomDataType(PythonData):
    def get_source(self,
         config: SubscriptionDataConfig,
         date: datetime,
         is_live: bool) -> SubscriptionDataSource:
        if not is_live:
            return SubscriptionDataSource("<custom_data_key>", SubscriptionTransportMedium.OBJECT_STORE, FileFormat.UNFOLDING_COLLECTION)
        return SubscriptionDataSource("https://raw.githubusercontent.com/QuantConnect/Documentation/master/Resources/datasets/custom-data/unfolding-collection-example.json", SubscriptionTransportMedium.REMOTE_FILE, FileFormat.UNFOLDING_COLLECTION)

    def reader(self,
         config: SubscriptionDataConfig,
         line: str,
         date: datetime,
         is_live: bool) -> BaseData:

        if not (line.strip()):
            return None

        objects = []
        data = json.loads(line)

        for datum in data:
            index = MyCustomDataType()
            index.symbol = config.symbol
            index.time = datetime.strptime(datum["Date"], "%Y-%m-%d")
            index.end_time = index.time + timedelta(1)
            index["Open"] = float(datum["Open"])
            index["High"] = float(datum["High"])
            index["Low"] = float(datum["Low"])
            index["Close"] = float(datum["Close"])
            index.value = index["Close"]
            objects.append(index)

        return BaseDataCollection(objects[-1].end_time, config.symbol, objects)
```

## Create Subscriptions

To create a subscription for the custom type, in the `initialize` method, call the `add_data` method. The `add_data` method returns a `Security` object, which contains a `Symbol`. Save a reference to the `symbol` so you can use it in `on_data` to access the security data in the `Slice`.

```python
class MyAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self._symbol = self.add_data(MyCustomDataType, "MyCustomDataType", Resolution.DAILY).symbol
```

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

## Receive Custom Data

As your data reader reads your custom data file, LEAN adds the data points in the `Slice` it passes to your algorithm's `on_data` method. To collect the custom data, use the `symbol` or name of your custom data subscription. You can access the `value` and custom properties of your custom data class from the `Slice`. To access the custom properties, pass the property name to the `get_property` method.

```python
class MyAlgorithm(QCAlgorithm):
    def on_data(self, slice: Slice) -> None:
        if slice.contains_key(self._symbol):
            custom_data = slice[self._symbol]
            close = custom_data.close
```

If you add custom properties to your data object in the `reader` method, LEAN adds them as members to the data object in the `Slice`. To ensure the property names you add in the `reader` method follow the convention of member names, LEAN applies the following changes to the property names you provide in the `reader` method:

1. `-` and `.` characters are replaced with whitespace.
2. The first letter is capitalized.
3. Whitespace characters are removed.

For example, if you set a property name in the `reader` method to `['some-property.name']`, you can access it in the `on_data` method through the `Somepropertyname` member of your data object.

## Demonstration Algorithms

- [CustomDataBitcoinAlgorithm.py](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/CustomDataBitcoinAlgorithm.py) (Python)
