Skip to content

Historical Market Data

historical_data() returns time-series data such as OHLC candles, volume, open interest, and selected analytics fields across a requested time range.

When To Use This Page

Use this page when you need to:

  • fetch historical candles for stocks, indices, futures, or options
  • retrieve one or more fields across a time window
  • run analytics, backtests, or charting workflows
  • request options Greeks or OI-related history when supported

LLM guidance

Use historical_data() for time-windowed analytics and intraday OHLC series, not for live quote snapshots or order-book checks. Keep request ranges and intervals aligned with the documented rate and retention constraints. values maps symbols to StockChart objects, not plain dict payloads, so access all requested series via attributes such as stock.open, stock.close, stock.delta, or stock.cumulative_oi. Each returned series is a typed list of points with nanosecond timestamps, where most price and cumulative fields use TimeSeriesPoint(timestamp, value) and Greeks or IV-style fields use TickPoint(timestamp, value). For cumulative fields such as volume or OI, compute per-interval changes with diff() instead of treating each point as an interval value. For cumulative_volume, day-and-higher intervals can usually be consumed as-is, but intervals below 1d should be differenced across the full cumulative series from the first returned row, regardless of whether intraDay is True or False.

Basic Usage

from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv

nubra = InitNubraSdk(NubraEnv.UAT, env_creds=True)
market_data = MarketData(nubra)

result = market_data.historical_data({
    "exchange": "NSE",
    "type": "STOCK",
    "values": ["ASIANPAINT", "TATAMOTORS"],
    "fields": ["open", "high", "low", "close", "cumulative_volume"],
    "startDate": "2025-04-19T11:01:57.000Z",
    "endDate": "2025-04-24T06:13:57.000Z",
    "interval": "1d",
    "intraDay": False,
    "realTime": False
})

print(result.message)
print(result.market_time)

Accessing Response Fields

for data in result.result:
    print(data.exchange, data.type)
    for stock_data in data.values:
        for symbol, values in stock_data.items():
            print(symbol)
            print(values.close)
            print(values.high)
            print(values.low)
            print(values.open)
            print(values.cumulative_volume)

SDK Surface

from nubra_python_sdk.marketdata.market_data import MarketData

MarketData.historical_data(request: dict)

Request Contract

Attribute Data Type Description
exchange String Exchange name such as NSE or BSE
type String "STOCK", "INDEX", "OPT", or "FUT"
values Union[List[str], str] One or more instrument symbols such as ["ASIANPAINT","TATAMOTORS"], ["HDFCBANK25MAY2380CE"], or ["NIFTY2550822400PE"]
fields List[str] One or more fields such as ["open","high","low","close","tick_volume","cumulative_volume","cumulative_volume_premium","cumulative_oi","cumulative_call_oi","cumulative_put_oi","cumulative_fut_oi","l1bid","l1ask","theta","delta","gamma","vega","iv_bid","iv_ask","iv_mid","cumulative_volume_delta"]
startDate str Start datetime in a format such as "2025-04-19T11:01:57.000Z"
endDate str End datetime in a format such as "2025-04-24T06:13:57.000Z"
interval str Interval can be "1s", "1m", "2m", "3m", "5m", "15m", "30m", "1h", "1d", "1w", or "1mt"
intraDay bool If True, startDate is the current date
realTime bool To be declared

Supported intervals include:

  • 1s: 1 second candles
  • 1m: 1 minute candles
  • 2m: 2 minute candles
  • 3m: 3 minute candles
  • 5m: 5 minute candles
  • 15m: 15 minute candles
  • 30m: 30 minute candles
  • 1h: 1 hour candles
  • 1d: 1 day candles
  • 1w: 1 week candles
  • 1mt: 1 month candles

Response Contract

Field Type Nullable Meaning
market_time str no current market timestamp
message str no response label
result list[ChartData] yes grouped historical response
result[].exchange str no exchange name
result[].type str no requested instrument type
result[].values list[dict] yes symbol-to-series mapping

Reference Response Shape

class MarketChartsResponse:
    market_time: str
    message: str
    result: list[ChartData]

class ChartData:
    exchange: str
    type: str
    values: list[dict[str, StockChart]]

class StockChart:
    open: list[TimeSeriesPoint] | None
    high: list[TimeSeriesPoint] | None
    low: list[TimeSeriesPoint] | None
    close: list[TimeSeriesPoint] | None
    cumulative_volume: list[TimeSeriesPoint] | None
    cumulative_oi: list[TimeSeriesPoint] | None
    theta: list[TickPoint] | None
    delta: list[TickPoint] | None
    gamma: list[TickPoint] | None
    vega: list[TickPoint] | None
    iv_mid: list[TickPoint] | None

class TimeSeriesPoint:
    timestamp: int
    value: int

class TickPoint:
    timestamp: int | None
    value: float | None

Time And Interval Notes

  • Intervals below 1d generally provide the last 3 months of data.
  • Intervals 1d and above can go much further back for supported instruments.
  • The 1s interval is a special case and is limited to a recent short window.
  • Use UTC timestamps in request payloads.
  • When intraDay=True, the request uses the current trading day and returns that day's series at the selected interval.

Example Patterns

Typical use cases include:

  • stocks and indices OHLC history
  • option history with OI and Greeks
  • converting the SDK response into pandas DataFrames

If you need to query heavily, review Rate Limits & API Usage before scaling usage.

Historical Data Examples

Below are ready-to-use examples showing how to query historical data for different asset types.

Expired Options Data

import pandas as pd
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv

pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", 1000)
pd.set_option("display.max_colwidth", None)
pd.set_option("display.width", 0)

nubra = InitNubraSdk(NubraEnv.PROD, env_creds=True)
md_instance = MarketData(nubra)

instruments = ["NIFTY2611326000CE", "NIFTY25D2326000CE"]
response = md_instance.historical_data({
    "exchange": "NSE",
    "type": "OPT",
    "values": instruments,
    "fields": [
        "open", "high", "low", "close", "cumulative_volume",
        "theta", "delta", "gamma", "vega", "iv_mid", "cumulative_oi"
    ],
    "startDate": "2025-12-01T11:01:57.000Z",
    "endDate": "2026-01-14T06:13:57.000Z",
    "interval": "1d",
    "intraDay": False,
    "realTime": False
})

def tsp_list_to_series(tsp_list):
    return pd.Series(
        data=[p.value for p in tsp_list],
        index=pd.to_datetime([p.timestamp for p in tsp_list], unit="ns")
    )

dfs = {}
for instrument_dict in response.result[0].values:
    for symbol, stock_chart in instrument_dict.items():
        df = pd.DataFrame({
            "open": tsp_list_to_series(stock_chart.open),
            "high": tsp_list_to_series(stock_chart.high),
            "low": tsp_list_to_series(stock_chart.low),
            "close": tsp_list_to_series(stock_chart.close),
            "volume": tsp_list_to_series(stock_chart.cumulative_volume),
            "theta": tsp_list_to_series(stock_chart.theta),
            "delta": tsp_list_to_series(stock_chart.delta),
            "gamma": tsp_list_to_series(stock_chart.gamma),
            "vega": tsp_list_to_series(stock_chart.vega),
            "iv_mid": tsp_list_to_series(stock_chart.iv_mid),
            "cumulative_oi": tsp_list_to_series(stock_chart.cumulative_oi),
        })
        df.sort_index(inplace=True)
        df["symbol"] = symbol
        dfs[symbol] = df

print(f"{instruments[0]} Historical data with greeks")
print(dfs[instruments[0]].head())
print()
print(f"{instruments[1]} Historical data with greeks")
print(dfs[instruments[1]].head())

Replace the instruments with expired option symbols from the last 3 months.

Indices Data

import pandas as pd
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv

nubra = InitNubraSdk(NubraEnv.PROD, env_creds=True)
md_instance = MarketData(nubra)

instruments = ["NIFTY"]
response = md_instance.historical_data({
    "exchange": "NSE",
    "type": "INDEX",
    "values": instruments,
    "fields": ["open", "high", "low", "close", "cumulative_volume"],
    "startDate": "2016-02-01T11:01:57.000Z",
    "endDate": "2026-02-04T06:18:57.000Z",
    "interval": "1mt",
    "intraDay": False,
    "realTime": False
})

def tsp_values(tsp_list):
    return [p.value for p in tsp_list]

dfs = {}
for instrument_dict in response.result[0].values:
    for symbol, stock_chart in instrument_dict.items():
        index = pd.to_datetime(
            [p.timestamp for p in stock_chart.open],
            unit="ns"
        )
        df = pd.DataFrame(
            {
                "open": tsp_values(stock_chart.open),
                "high": tsp_values(stock_chart.high),
                "low": tsp_values(stock_chart.low),
                "close": tsp_values(stock_chart.close),
                "volume": tsp_values(stock_chart.cumulative_volume),
            },
            index=index
        )
        df.sort_index(inplace=True)
        df[["open", "high", "low", "close"]] = df[["open", "high", "low", "close"]].div(100)
        df["symbol"] = symbol
        dfs[symbol] = df

print(dfs["NIFTY"])

Change or add index symbols in the instruments list.

Stocks Data

import pandas as pd
from nubra_python_sdk.marketdata.market_data import MarketData
from nubra_python_sdk.start_sdk import InitNubraSdk, NubraEnv

nubra = InitNubraSdk(NubraEnv.PROD, env_creds=True)
md_instance = MarketData(nubra)

instruments = ["RELIANCE"]
response = md_instance.historical_data({
    "exchange": "NSE",
    "type": "STOCK",
    "values": instruments,
    "fields": ["open", "high", "low", "close", "cumulative_volume"],
    "startDate": "2026-02-05T03:30:00.000Z",
    "endDate": "2026-02-05T11:30:00.000Z",
    "interval": "3m",
    "intraDay": False,
    "realTime": False
})

def tsp_list_to_series(tsp_list):
    idx = pd.to_datetime(
        [p.timestamp for p in tsp_list],
        unit="ns",
        utc=True
    ).tz_convert("Asia/Kolkata")
    return pd.Series(
        data=[p.value for p in tsp_list],
        index=idx
    )

dfs = {}
for instrument_dict in response.result[0].values:
    for symbol, stock_chart in instrument_dict.items():
        df = pd.DataFrame({
            "open": tsp_list_to_series(stock_chart.open),
            "high": tsp_list_to_series(stock_chart.high),
            "low": tsp_list_to_series(stock_chart.low),
            "close": tsp_list_to_series(stock_chart.close),
            "volume": tsp_list_to_series(stock_chart.cumulative_volume),
        })
        df.sort_index(inplace=True)
        df["symbol"] = symbol
        dfs[symbol] = df

print(dfs["RELIANCE"])

Important Rules

  • Historical data is rate-limited to 60 API calls per minute. Review Rate Limits & API Usage before building large polling or backfill jobs.
  • The values field supports a batch of up to 5 instruments per request.
  • startDate and endDate must be provided in UTC.
  • If past history must be included, set intraDay=False even when the interval is below 1d. intraDay=True means only the current trading day's data, not prior days.
  • Keep type, values, and fields aligned. Do not request fields that do not apply to the selected instrument type.
  • Prices and many numeric series are returned in exchange-native integer units such as paise for NSE instruments unless your application converts them.
  • When intraDay=True, users can fetch the current day's full OHLC or requested fields at the interval they query.
  • Intraday and interval choices affect retention windows and response size.
  • Cache repeated queries when you are requesting the same symbols, windows, or fields.

The most common next pages are:

  1. Rate Limits & API Usage
  2. Get Instruments
  3. Current Price
  4. Option Chain
NEO Assistant