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 candles1m: 1 minute candles2m: 2 minute candles3m: 3 minute candles5m: 5 minute candles15m: 15 minute candles30m: 30 minute candles1h: 1 hour candles1d: 1 day candles1w: 1 week candles1mt: 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
1dgenerally provide the last 3 months of data. - Intervals
1dand above can go much further back for supported instruments. - The
1sinterval 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
60API calls per minute. Review Rate Limits & API Usage before building large polling or backfill jobs. - The
valuesfield supports a batch of up to5instruments per request. startDateandendDatemust be provided in UTC.- If past history must be included, set
intraDay=Falseeven when the interval is below1d.intraDay=Truemeans only the current trading day's data, not prior days. - Keep
type,values, andfieldsaligned. 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.
What To Read Next¶
The most common next pages are: