Skip to main content

Asset CSV Import Pipeline Guide

import_assets.py loads instruments and their listings from CSV files into the catalogue. It is idempotent: importing a file twice updates the rows instead of duplicating them.

CSV format​

name,ticker,isin,productType,currency
Airbus SE,AIR.PA,NL0000235190,STOCK,EUR
Apple Inc,AAPL,US0378331005,STOCK,USD
Apple Inc,APC.DE,US0378331005,STOCK,EUR
iShares Core MSCI World UCITS ETF,EUNL.DE,IE00B4L5Y983,ETF,EUR
ColumnRule
nameNot empty
tickerAt most 20 characters
isin12 characters, [A-Z]{2}[A-Z0-9]{10}
productTypeSTOCK or ETF
currency3 upper-case letters

Rows are deduplicated on (isin, ticker, currency). The exchange of a listing is deduced from the ticker suffix (AIR.PA → XPAR, BMW.DE → XETR); a ticker without suffix gets no exchange.

The image ships two catalogues: data/etf.csv and data/stocks.csv.

What the import writes​

CSV file
│ parse_csv(): validation, deduplication
▼
AssetImporter.run() — batches of 200 rows
├─ one row of assets per ISIN
├─ one row of asset_listings per (instrument, ticker, exchange, currency)
└─ default mappings: YahooFinance and GoogleFinance
  • The first listing of an instrument is its primary listing; when none is primary yet, a listing in USD, GBP, JPY, CHF, CAD or AUD becomes primary.
  • The import makes no network call. The Yahoo Finance mapping it writes is the ticker of the file, not verified: the first ingestion or fundamentals request of the listing replaces it with the Yahoo symbol verified from the ISIN and the currency.

Commands​

# One file
docker compose exec fonrex-api python import_assets.py --file data/etf.csv

# Simulation, nothing written
docker compose exec fonrex-api python import_assets.py --file data/etf.csv --dry-run

# Every CSV file of a directory
docker compose exec fonrex-api python import_assets.py --dir data/isin_data

# Without --file or --dir: data/etf.csv and data/stocks.csv
docker compose exec fonrex-api python import_assets.py

Options: --batch-size (rows per transaction, 200), --verbose.

A simple file name is looked up in data/isin_data/, then in the application folder; a relative or absolute path is used as it is.

Enrichment from Yahoo Finance​

The deep enrichment (highlights, financial statements, earnings, analyst ratings) is a separate step:

# One instrument
docker compose exec fonrex-api python import_assets.py --enrich-only --isin US0378331005

# The instruments of a file
docker compose exec fonrex-api python import_assets.py --enrich-only --file data/etf.csv --limit 100

--enrich-only needs --isin or --file. Yahoo is asked with the symbol verified for the primary listing; an instrument without a verified symbol is skipped and the log says why. GET /fundamental/deep?ticker=...&refresh=true does the same for one instrument through the API.

make db-seed imports the default catalogue and enriches it (scripts/seed_database.py --enrich).

Removing ISIN duplicates​

Databases created before the ISIN uniqueness rule may hold the same ISIN twice. scripts/clean_isin_duplicates.py merges them onto the oldest row:

docker compose exec fonrex-api python scripts/clean_isin_duplicates.py --diagnose-only # read only
docker compose exec fonrex-api python scripts/clean_isin_duplicates.py --dry-run # run, then roll back
docker compose exec fonrex-api python scripts/clean_isin_duplicates.py --create-index # clean + unique index

Next step​

Ingest the prices of the imported listings — see Ingesting historical data.