How captn3m0/historical-mf-data works
1. This repository is primarily a historical data archive, not an application. The core asset is the data/ directory: a long, date-partitioned collection of daily AMFI-style CSV exports for Indian mutual fund NAVs.
2. The data layer is organized by year, month, and day (data/YYYY/MM/DD.csv). That structure is the main storage boundary in the repo: each file represents a snapshot of the day’s fund pricing data, preserved in the source format without cleanup.
3. The repo intentionally keeps AMFI’s original quirks. Invalid ISINs and invalid NAV values are retained as-is rather than normalized away. This means the raw CSV archive is the canonical input, and downstream consumers must tolerate imperfect source data.
4. fetch.sh is the acquisition subsystem. It is responsible for pulling or refreshing the daily CSV inputs from the external AMFI source and populating the data/ tree.
5. generate.py is the transformation/build subsystem. Its job is to take the raw CSV archive and produce the packaged dataset described in the README: a SQLite database containing historical NAVs and fund metadata.
6. The generated database is the main distribution artifact for consumers. The README points to a release asset (funds.db.zst) rather than the repo itself, which means the repo serves as both source archive and build input for a published binary dataset.
7. The logical database schema has three main entities: schemes for scheme metadata, funds for date-indexed NAV history, and securities for ISIN-to-scheme mapping and type. A derived view, nav_by_isin, provides the key join path for querying NAVs by ISIN.
8. The primary data flow is: external AMFI export → fetch.sh → raw CSV archive in data/ → generate.py → SQLite DB → compressed release artifact. This is the central pipeline to diagram.
9. Query access is read-only and consumer-driven. The README’s examples show usage patterns that first resolve a security by ISIN, then look up the latest NAV on or before a target date, or retrieve NAV history for a scheme.
10. Indexes are deliberately omitted from the published database to reduce download size. Consumers are expected to add indexes locally after download, which shifts performance optimization from the build artifact to the user’s environment.
11. GitHub Actions (.github/workflows/update.yml) indicates the repo is maintained by automation. The workflow likely orchestrates periodic fetch/build/release updates, making the CI pipeline part of the data refresh architecture.
12. The repo boundary is therefore: upstream market data provider on one side, and downstream analysts/tools querying SQLite on the other. Everything inside the repo exists to preserve, rebuild, version, and distribute that historical dataset.
Main entry points: update.yml update.yml · fetch.sh fetch.sh · generate.py generate.py · 01.csv Daily CSV
Components 17
Upstream
External AMFI source feeding the archive.
- AMFI export · Upstream daily mutual-fund NAV CSV feed.
Archive
Raw date-partitioned CSV storage.
- Raw archive · Canonical preserved source data organized by year, month, and day.
- Daily CSV · One day of AMFI-style fund pricing data, kept in source form.
data/2006/04/01.csv - Source quirks · Retains invalid ISINs and NAV values without normalization.
Build
Scripts that refresh and package the dataset.
- fetch.sh · Fetches or refreshes daily CSV inputs from AMFI.
fetch.sh - generate.py · Transforms the raw archive into the packaged SQLite dataset.
generate.py
Distribution
Published SQLite artifact and its schema.
- funds.db · Packaged historical NAV and metadata database for consumers.
- schemes · Scheme metadata and descriptive fund attributes.
- funds · Date-indexed NAV history for schemes.
- securities · ISIN-to-scheme mapping and security type.
- nav_by_isin · Join path for looking up NAVs by ISIN.
- No indexes · Indexes are omitted to keep the release artifact small.
- Release asset · Published compressed database asset for download.
Automation
Scheduled maintenance and release workflow.
- update.yml · Automation that likely schedules refresh, build, and release.
.github/workflows/update.yml
Consumers
Read-only query patterns over the packaged database.
- Readers · Query the SQLite database by ISIN or scheme and add local indexes if needed.
- NAV lookup · Resolve security by ISIN, then find NAV on or before a target date.
- History query · Retrieve NAV history for a scheme over time.
Connections 22
- AMFI export → fetch.sh: daily exports · Upstream feed is acquired by the fetch script.
- fetch.sh → Raw archive: populate · Acquired CSVs are written into the raw archive tree.
- Raw archive → Daily CSV: contains · Archive is partitioned into per-day snapshot files.
- Raw archive → Source quirks: preserves · Source irregularities are retained as canonical input.
- Raw archive → generate.py: input · The build script reads the raw archive as its source.
- generate.py → funds.db: builds · Transformation produces the packaged SQLite database.
- funds.db → schemes: stores · Database contains scheme metadata.
- funds.db → funds: stores · Database contains historical NAV rows.
- funds.db → securities: stores · Database contains ISIN and security mapping data.
- schemes → nav_by_isin: joins via · Scheme metadata participates in query paths.
- funds → nav_by_isin: joins via · NAV history is exposed through the derived view.
- securities → nav_by_isin: joins via · ISIN mapping anchors the primary lookup view.
- funds.db → No indexes: omits · Published database intentionally excludes indexes.
- funds.db → Release asset: compresses to · Database is distributed as a compressed release asset.
- update.yml → fetch.sh: orchestrates · Automation coordinates data refresh.
- update.yml → generate.py: orchestrates · Automation coordinates dataset generation.
- update.yml → Release asset: publishes · Automation likely updates the release artifact.
- Readers → NAV lookup: use · Consumers query by ISIN for current or historical NAVs.
- Readers → History query: use · Consumers query NAV history by scheme.
- NAV lookup → nav_by_isin: reads · Lookup workflow depends on the ISIN join view.
- History query → funds: reads · History workflow reads the NAV table directly.
- Readers → funds.db: download · Consumers retrieve the packaged database artifact.