# Market Data Sources India

> Find and pull Indian market data from the right source — NSE and BSE bhavcopy, AMFI NAV files, RBI and MoSPI macro series, MCA company filings, SEBI disclosures, and the Python libraries that wrap them — with the ticker conventions, date formats and licensing caveats that trip people up. Use when the user needs Indian stock prices, index data, mutual fund NAVs, corporate filings, macro series, or asks where to get Indian market data or why a data pull is failing.

- Skill: `sharma23yash-oss/market-data-sources-india` (Agent Skill)
- Install (CLI): `npx skillmds@latest add sharma23yash-oss/market-data-sources-india`
- Raw SKILL.md: https://api.skillmd.com/api/skills/sharma23yash-oss/market-data-sources-india/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: sharma23yash-oss (https://skillmd.com/u/sharma23yash-oss)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/sharma23yash-oss/market-data-sources-india

---


# Indian Market Data Sources

## Ground rules before you fetch anything

- **Check the terms of use of every source.** NSE, BSE and most commercial providers restrict automated access and redistribution. Public bhavcopy and AMFI files are published for download; undocumented JSON endpoints behind a website are not an API and using them may breach the site's terms.
- **Never build a redistribution product on scraped exchange data.** Exchange data is licensed. Personal research is a different matter from a hosted service.
- Respect `robots.txt`, rate-limit politely, cache aggressively, and identify your client honestly.
- When a source cannot be reached, **say so and name what you tried.** Never fill a gap with a remembered figure.

## The map

| You need | Source | Notes |
|---|---|---|
| Daily OHLC, all listed stocks | NSE and BSE **bhavcopy** (daily CSV/ZIP) | The canonical settlement-grade EOD file |
| Adjusted historical prices | Yahoo Finance via `yfinance`, tickers `RELIANCE.NS` / `500325.BO` | Free, convenient; adjustment errors around Indian corporate actions are common — verify against bhavcopy |
| Index values and constituents | NSE indices pages; NSE Indices publishes methodology and factsheets | Free-float methodology; check rebalancing dates |
| Corporate announcements and filings | NSE / BSE corporate announcements | See `exchange-filings-navigator` |
| Shareholding pattern | NSE / BSE quarterly filings | See `shareholding-pattern-analysis` |
| Mutual fund NAVs, all schemes | **AMFI** — the consolidated NAV text file, published every business day | The single best free dataset in Indian finance |
| MF scheme portfolios | AMC monthly portfolio disclosures; AMFI aggregates | Monthly, with a lag |
| Fundamentals (P&L, balance sheet, ratios) | Company filings; screener-type sites for convenience | Always trace a number back to the filing before publishing it |
| Company master data, charges, financial filings of unlisted entities | **MCA21** | Paid per document; the only source for subsidiary financials |
| Regulatory orders, circulars | SEBI website | |
| Insolvency | IBBI public announcements, NCLT orders | |
| Macro: policy rates, money supply, banking, external sector | **RBI** — Database on Indian Economy (DBIE), Weekly Statistical Supplement, Handbook of Statistics | Authoritative |
| Macro: GDP, IIP, CPI, WPI | **MoSPI** and the Office of the Economic Adviser | |
| Government finances, budget | Union Budget documents; Controller General of Accounts monthly accounts | |
| Trade data | Ministry of Commerce, DGCI&S | |
| FPI and DII flows | NSDL/CDSL FPI data; exchange daily FII/DII activity reports | |
| Credit ratings | CRISIL, ICRA, CARE, India Ratings press releases | Rationales are a forensic goldmine |
| Commodity prices | MCX; for physical, the relevant commodity board | |
| Currency reference rates | RBI reference rate; FBIL benchmarks | Use FBIL for anything requiring an official benchmark |
| G-Sec yields, benchmark curve | CCIL, RBI, FBIL | The 10Y benchmark is the risk-free rate for `dcf-india` |

## Ticker and identifier conventions

Getting these wrong is the most common cause of a silently wrong dataset.

| Identifier | Form | Where used |
|---|---|---|
| NSE symbol | `RELIANCE`, `TCS`, `HDFCBANK` | NSE files, most Indian tools |
| BSE scrip code | `500325`, `532540` | BSE files |
| Yahoo suffix | `.NS` for NSE, `.BO` for BSE | `yfinance` |
| **ISIN** | `INE002A01018` | **The only stable identifier.** Use it as the primary key |
| Series | `EQ`, `BE`, `SM`, `ST` | Filter to `EQ` for normal equity; `BE` is trade-for-trade surveillance |

**Always key your database on ISIN.** NSE symbols change on renames, mergers and demergers, and a symbol can be reassigned. Historical series joined on symbol will silently splice two different companies.

## Bhavcopy: the workhorse

Both exchanges publish an end-of-day file with OHLC, volume, delivery quantity and series for every scrip. It is the correct base for any Indian backtest.

```python
import io, zipfile, requests, pandas as pd

HEADERS = {"User-Agent": "research-script/1.0 (contact: you@example.com)"}

def fetch_zip_csv(url: str) -> pd.DataFrame:
    """Download a zipped CSV published by an exchange and return it as a DataFrame."""
    r = requests.get(url, headers=HEADERS, timeout=30)
    r.raise_for_status()
    z = zipfile.ZipFile(io.BytesIO(r.content))
    name = z.namelist()[0]
    return pd.read_csv(z.open(name))
```

Exchange URL patterns change; check the current archives page rather than hardcoding a path that worked last year. Wrap every fetch so a 404 is reported, not swallowed.

**Delivery percentage** is published in the NSE securities-wise delivery file and is genuinely useful — a price move on low delivery is speculative positioning, one on high delivery is transfer of ownership.

## AMFI NAV file

The most reliable free Indian dataset. A single semicolon-delimited text file with every scheme's NAV.

```python
import requests, pandas as pd, io

URL = "https://portal.amfiindia.com/spages/NAVAll.txt"

def amfi_nav() -> pd.DataFrame:
    txt = requests.get(URL, timeout=60).text
    rows, amc, scheme_type = [], None, None
    for line in txt.splitlines():
        line = line.strip()
        if not line:
            continue
        if ";" not in line:
            # section headers alternate between scheme type and AMC name
            if "Mutual Fund" in line:
                amc = line
            else:
                scheme_type = line
            continue
        parts = line.split(";")
        if parts[0] == "Scheme Code":
            continue
        rows.append({
            "scheme_code": parts[0],
            "isin_growth": parts[1] or None,
            "isin_div_reinvest": parts[2] or None,
            "scheme_name": parts[3],
            "nav": pd.to_numeric(parts[4], errors="coerce"),
            "date": parts[5],
            "amc": amc,
            "scheme_type": scheme_type,
        })
    df = pd.DataFrame(rows)
    df["date"] = pd.to_datetime(df["date"], format="%d-%b-%Y", errors="coerce")
    return df
```

Historical NAVs are available from AMFI's NAV history endpoint for a scheme code and date range. Scheme codes are stable; scheme *names* change on mergers, so key on scheme code or ISIN.

## Prices via yfinance

Convenient, not authoritative.

```python
import yfinance as yf

df = yf.download("RELIANCE.NS", start="2015-01-01", auto_adjust=False, progress=False)
# auto_adjust=False keeps raw Close and a separate Adj Close so you can inspect the adjustment
```

Known failure modes for Indian tickers:
- Corporate action adjustments around bonuses, splits and demergers are frequently wrong or late. **Validate against `corporate-actions-india`**: a 1:1 bonus must show an exact 50% step in raw Close and no step in Adj Close.
- Companies renamed after mergers lose history under the old symbol.
- Volume is often unreliable; use bhavcopy volume.
- Index tickers use `^NSEI` (Nifty 50) and `^BSESN` (Sensex).

## Useful Python libraries

| Library | Use | Caveat |
|---|---|---|
| `yfinance` | Quick historical prices | Adjustment quality |
| `nsepython` / `jugaad-data` | Wrappers over NSE endpoints — quotes, option chain, bhavcopy | Community-maintained; break when NSE changes its site. Check the terms of use |
| `mftool` | AMFI NAV history | |
| `pandas-datareader` | Some macro sources | |
| `nselib`, `bsedata` | Exchange helpers | Same fragility caveat |

Prefer the published files (bhavcopy, AMFI) over any wrapper around an undocumented endpoint. The files are stable, permitted, and do not break.

## Data hygiene rules

1. **Key on ISIN.** Store symbol as an attribute, not an identifier.
2. **Store raw and adjusted separately.** Never overwrite raw prices with adjusted ones.
3. **Record the source and the fetch timestamp** on every row or table. Financial data is revised.
4. **Handle the Indian trading calendar**: NSE and BSE holidays do not match any standard calendar library's defaults, there are special Muhurat trading sessions, and there have been occasional weekend sessions. Fetch the exchange's published holiday list rather than assuming.
5. **Crore and lakh.** 1 crore = 10 million; 1 lakh = 0.1 million. Indian filings report in ₹ crore or ₹ lakh, and both appear in the same document. Normalise to one unit at ingestion and record which.
6. **Face value changes** on a split alter the per-share series without any corporate action flag in some sources. Cross-check against the exchange's corporate action file.
7. **Survivorship bias**: a universe built from today's index constituents excludes every delisted and merged company. For any backtest, reconstruct point-in-time index membership from the exchange's historical constituent changes.
8. **Ex-date on T+1.** Under India's T+1 settlement cycle the ex-date coincides with the record date. Code written for T+2 will be one day off on every corporate action.

## Output format

When asked where to get something, answer in this shape:

```markdown
**Source:** <name> — <url or navigation path>
**Format:** <CSV / JSON / PDF>, <frequency>, <history available>
**Identifier:** <ISIN / symbol / scheme code>
**Cost / access:** <free / paid / registration>
**Caveats:** <the two or three things that will bite>
**Snippet:** <minimal working code, if code was asked for>
```

## Hard rules

- **Never fabricate a data point.** If a fetch fails, report the failure and the URL attempted.
- **Never present scraped data as official.** Name the source in every output.
- Do not write code that circumvents authentication, rate limits, or a paywall.
- State the as-of date on every number that came from a market data source.

