Accounts and securities at NSDL and CDSL
Sources and reference dates
The public monthly BO Aggregate reports are downloaded from NSDL’s depository statistics, discovered through its public resource listing, and CDSL’s archive and current statistics. No logged-in account data or investor-level records are collected.
The completed backfill retrieved 289 files on 9 October 2026. CDSL has 137 and NSDL 136 distinct reference months from April 2015 to August 2026. The first download pass missed CDSL November 2022 because its filename uses spaces rather than hyphens; the matcher was generalised and the actual November file recovered. Dates inside the table take precedence over portal titles and filenames. A reference date within a month is normalised to that month’s end; this does not infer an observation on that day. CSV content is parsed as CSV even when a download is named .xls. NSDL files are XLSX workbooks.
Annual and monthly reports overlap. A complete monthly category table takes precedence over an annual report for the same provider and month. Tables are never added together. Differences between overlapping reports are logged; none were found in the first backfill. The latest category tables use the most recent month present at both providers.
Meaning and units
Accounts are non-closed accounts, not unique investors. Several accounts may belong to the same person. NSDL explicitly includes suspended accounts in its non-closed and reported-active columns. Reported active does not mean recent trading activity, and is not used as the denominator here.
Equity, debt, fund units and other securities are reported in ₹ crore. Custody value is the sum of all four, only when all four are known. It includes corporate and institutional holdings and securities beyond listed-company equity. Changes in value combine prices, changes in holdings, transfers and other effects. They are not net purchases, cash flows or investment returns.
CDSL Individual and NSDL Resident remain separate universes. NSDL’s Funds column includes AIF, InvIT, REIT and mutual-fund units; CDSL’s MF column is not equivalent. Demat mutual-fund holdings exclude units held outside demat, so comparisons with all-industry AUM or total household savings are inappropriate.
Equity per account equals equity value × 10,000,000 divided by all non-closed accounts in that category. Empty accounts are included. This is an arithmetic average across accounts, not a median investor balance or a fixed investor cohort. A zero denominator produces a missing result. Year-on-year growth uses the exact reference month twelve months earlier; a missing comparison month produces a missing growth rate.
Chart category mappings
CDSL charts show Individual, Corporate, Mutual Funds and NRI separately; all remaining source categories form Other. NSDL charts combine Corporate with Body Corporate, and FPI with Foreign Portfolio Investor and legacy FII; Resident and Mutual Fund remain separate, and the remaining categories form Other. These are naming mappings within a provider, not a harmonisation between providers. The latest tables retain the native source names. Each provider’s equity shares sum to its own equity total.
Validation and missing observations
Every raw download is retained with its source URL, retrieval timestamp, byte length and SHA-256 hash under .cache/ref/depositories. Computation verifies these hashes. Unexpected schemas, invalid or negative numbers, non-integer account counts, active counts above non-closed counts, duplicate category rows and mismatched printed totals fail validation. Printed account totals allow 0.001 accounts of numerical tolerance; asset totals allow ₹0.02 crore of rounding tolerance. The first backfill checked 45 printed total rows. Reports without printed totals still undergo row and schema checks, but cannot receive this reconciliation.
Source blanks and dashes stay missing, rather than becoming zero. Aggregation requires every constituent value. An absent chart category is zero only inside an otherwise fully parsed month; an absent month stays missing. CDSL November 2022 was recovered from the official space-separated filename BO Aggregate NOV-2022.csv; its cells explicitly date the observations to November. CDSL now has no missing reference months. NSDL April 2024 remains absent because the April-labelled file contains March observations. This source gap is not interpolated.
An additional consistency check flags an isolated possible equity/debt reversal. It requires consecutive neighbouring months, compares the observation with the geometric mean of its neighbours, and flags when the sum of absolute log distances exceeds 1.4 and swapping equity and debt reduces that distance below one quarter of the original. This is an anomaly screen, not an automatic correction. For a flagged provider-month equity and debt values are withheld. Accounts, fund units and other securities are retained, since this screen does not implicate those fields. NSDL January 2023 is the only first-backfill flag: the raw distance was 3.283 and the reversed distance 0.0036. Its original file remains available for review.
A separate category check withholds an isolated, material equity jump pending source review. Require consecutive months, positive values, equity more than twice or less than half the geometric mean of the neighbours, neighbouring equity values within 25% of each other, account counts within 25% of their neighbouring geometric mean, and baseline category equity above 1% of that provider’s current total. This conservative screen does not establish that the source is wrong. Only the flagged category’s equity cell is withheld; dependent equity totals, custody totals and shares consequently become missing. The first backfill flags NSDL Resident in May 2026: the original XLSX reports ₹1,52,52,228.77 crore, 2.181 times its neighbouring baseline. No replacement is inferred. Its accounts and other assets remain usable.
All BO numeric fields are extracted: non-closed accounts, source-reported active accounts, equity, debt, funds and other securities. The complete native-category history contains all 3,122 distinct provider–month–category observations and all 29 native labels, including historical naming variants. It includes usable values, original reported asset values in _reported columns, quality actions, source URLs and hashes. There are 18,702 non-blank numeric source cells: 18,675 remain usable after withholding 14 equity and 13 debt cells. Source blanks remain missing. Printed total rows are retained in the coverage audit and reconciled, rather than added to investor-category observations.
Native-label charts preserve that label’s own coverage: absence before introduction or after a rename is not treated as zero. Broad naming mappings apply only to the equity-mix overview. A native label does not guarantee its economic definition stayed unchanged through the entire history. Definitions and source notes must be consulted for comparisons over time.
The equity-mix and asset-mix overviews default to actual calendar quarter-end observations plus the latest source month when it is interim. They retain their real source dates and do not substitute an earlier month for a missing quarter end. This snapshot view removes distracting gaps in intermediate months without estimating those observations. The Every month selector retains the complete calendar, nulls and dated gap labels. Monthly line charts preserve short gaps. Their table views retain all-missing calendar months as rows of dashes; CSV exports retain those dates with empty values. Exports preserve the source gaps regardless of the selected view; the complete history remains downloadable separately.
Asset-class shares use the strict sum of all four components as denominator. If any component is unknown, every asset share is unknown; the remaining known components are never renormalised to 100%. Fund and equity year-on-year comparisons use the exact month twelve months earlier. Holdings per account include all non-closed accounts in that native category and are not cohort returns.
All bundles carry source and method metadata. The coverage bundle includes missing months, anomaly flags, field-by-field extraction counts, printed totals and parsing checks; the latest category bundle includes source URLs. A failed computation does not overwrite published bundles. Collection refreshes the latest three available portal months and discovers new files; a full backfill can be requested explicitly. The source history is a current downloaded edition and may include revisions. It is unsuitable for a point-in-time historical strategy test without separately captured historical vintages.
Reproduce
uv run python -m tipsheet.sources.depositories --backfill
uv run python -m tipsheet.run --only depositories
uv run pytest pipeline/tests/test_depositories.py -q
The refresh workflow collects these reports in its morning and weekly tiers. Raw reference caches use the existing cache persistence mechanism. This workflow change takes effect only when released.