1. What this dataset is
- Content: daily OHLCV history for Nifty 500 stocks and a set of NSE/BSE indices (including NIFTY 50, NIFTY 100, NIFTY 200, NIFTY 500, India VIX, Bank Nifty, Nifty Next 50 and Sensex). About 525 instruments are mapped in the current instrument master.
- Source: Dhan historical-data API (daily candles). Nothing else is merged in.
- Depth: stored daily history reaches back to 1996 for the longest-running instruments. Each instrument starts at its own first available date, and the length differs by instrument.
- Dates: ISO
YYYY-MM-DD, Indian trading-session dates (IST). - Read-only: the API never places orders and exposes no account data.
2. How the data is collected
| Step | What happens | When (IST) |
|---|---|---|
| Authentication | An access token is generated and validated against Dhan. Failures are recorded in an audit status file and raise an alert; the old token stays in use until it expires. | 05:00 and 23:00, every day |
| Fetch | Incremental update: only new sessions since the last stored date are requested, per instrument. Re-running is safe (idempotent). | 17:00, every day (weekends and holidays are checked against the calendar and normally return nothing new) |
| Gap recovery | Runs straight after a successful fetch. It re-requests sessions that are expected but missing. | After fetch |
| Audit | Runs straight after gap recovery. It checks duplicates, record validity, coverage, and links the dataset catalogue to the audit result. | After gap recovery |
| Retries | Each step retries up to 3 times with a delay before it stops and raises an alert. | — |
Validation before storing
- Rows with non-positive prices (
ohlc_nonpositive) or inconsistent OHLC (ohlc_inconsistent, e.g. high below low) are rejected and not stored. The rejection reason and date are recorded; raw values are not. - Data is stored as yearly partitions per instrument. A write is staged, read back and validated, then atomically replaces the partition, so a failed run does not leave half-written data.
- Timestamps are stored as UTC instants and exposed as IST session dates.
3. Status words you will see
| Word | Meaning |
|---|---|
SUCCESS / COMPLETE | A non-empty response was stored, every returned row passed validation, and no expected session was found missing. |
PARTIAL | The instrument is stored but some provider rows were rejected (listed on the status page). Check the rejected date range before using that period. |
NO_DATA | The provider returned nothing for the instrument. It is listed but unusable. |
| Open gap | An expected session with no stored row. It is a warning, not proof of an error (see limitations). |
| Known missing | The provider was asked and returned no data for that range; recorded so it is not asked again forever. |
4. How to use it
- Look up the instrument:
GET /api/v1/instruments?symbol=...and keep itsinstrument_key. - Fetch history:
GET /api/v1/data/{instrument_key}?from=YYYY-MM-DD&to=YYYY-MM-DD&limit=10000. - Read the
statusfield in the response. If it isPARTIAL, check/api/v1/status/partialfor the affected dates. - Check
/api/v1/statusfor the last successful update and the latest audit before relying on recent rows.
import requests, pandas as pd
BASE = "https://data.tradetechanalytics.com/api/v1"
inst = requests.get(f"{BASE}/instruments", params={"symbol": "Reliance Industries"}, timeout=30).json()["data"][0]
p = requests.get(f"{BASE}/data/{inst['instrument_key']}",
params={"from": "2020-01-01", "to": "2026-10-01", "limit": 10000}, timeout=30).json()
df = pd.DataFrame(p["data"]); print(inst["symbol"], p["status"], len(df))
Good practice
- Use
instrument_key, not the symbol text, as the identifier. - Do not treat a missing date as zero volume or an unchanged price. Join to a trading calendar.
- For research, hold out a later period and never tune on it.
- Record the dataset
auditID you used so results can be reproduced.
5. Known limitations — read before using for research
- Survivorship bias (large). 1,136 symbols have been in the Nifty 500 since 1998. 501 are live today and 635 have been removed. Only 6 of those 635 removed symbols exist in Dhan's instrument master, so almost all past members that left the index are missing. A back-test across all instruments looks better than real trading. See Survivorship & membership for dated membership of every symbol. Point-in-time membership is published but not yet applied inside the API.
- Price adjustment is not verified. We do not yet check that history is consistently adjusted for splits, bonuses and other corporate actions. For at least one stock the provider has been reported to return different closes for the same date depending on the request window. Prices around corporate actions can show jumps. Treat large one-day moves with suspicion.
- Open-gap counts are inflated. Many gaps are sessions before an instrument existed or joined the index. Until gaps are classified against listing dates, the open-gap number overstates real missing data.
- Calendar coverage. The bundled authoritative exchange calendar covers 2026 only. Earlier non-trading days are not inferred.
- Early history is weaker. Thousands of provider rows from roughly 2006–2013 were rejected as non-positive or inconsistent. The ten PARTIAL instruments are listed on the status page.
- One instrument is unmapped (HEG). It is retained as inactive.
- Not investment advice. Data is provided as-is for research and analytics.
6. What is planned
- Apply point-in-time membership (published on the survivorship page) inside research tests, so they only use stocks that were members on each date. The share of past members with no data cannot be recovered from Dhan and stays documented.
- Per-instrument quality label (OK / REVIEW / EXCLUDE) from jump and adjustment checks.
- Gap classification: before listing, known provider hole, or real miss.
Until these land, treat research results on this data as provisional.