Data Providers

What Are Data Providers?

To show you stock prices and charts, the application needs to download historical price data from the internet. Different websites and services offer this data - these are called “data providers”.

Good news: The application uses Yahoo Finance, which is free and works great for most people. You don’t need to configure anything!

Yahoo Finance (Default)

Free - No API key required - Global coverage

Yahoo Finance is the default provider and works out of the box with no configuration.

Pros:

  • Free to use

  • No API key required

  • Good coverage for US and European stocks

  • Historical data going back many years

Cons:

  • End-of-day data only

  • Occasional reliability issues

  • No official API support

  • Has undocumented rate limits (the app handles this automatically)

Configuration:

# .env (optional — yahoo is the default)
PRICE_DATA_PROVIDER=yahoo

Ticker Resolution

DEGIRO transaction exports identify stocks by ISIN, but Yahoo Finance needs a ticker symbol (SAP.DE, SAVE.ST, KD, …). The application resolves the ISIN → ticker mapping automatically the first time it sees a stock, and caches the result in the yahoo_ticker column of the stocks table.

How resolution works

When a new stock is imported, resolve_ticker_from_isin() tries strategies in order:

  1. Manual override. A small allowlist (MANUAL_TICKER_MAPPING in src/degiro_portfolio/ticker_resolver.py) for stocks where a specific listing must be pinned.

  2. Yahoo Finance Search (yf.Search(isin)). The primary resolver. Yahoo indexes most listed equities and ETFs globally by ISIN; the search returns candidate listings across exchanges.

  3. Legacy prefix heuristic. Last-resort defensive path for US/NL/DE/FR/IT/ES ISINs, kept for offline or network-flaky environments.

Picking the right listing

The same ISIN can be listed on several Yahoo venues (Stockholm and Stuttgart, Athens and Amsterdam, etc.). To pick the right one, the resolver compares each candidate’s suffix against:

  1. The stock’s trading currency. SEK → .ST, NOK → .OL, CHF → .SW, GBP → .L, JPY → .T, PLN → .WA, HKD → .HK, AUD → .AX, CAD → .TO, BRL → .SA, INR → .NS, … (~30 currencies; USD is intentionally unmapped — US tickers have no suffix).

  2. If the currency hint doesn’t disambiguate (e.g. EUR is shared across Athens, Amsterdam, Paris, Milan, Madrid, …), the ISIN country prefix: DE.DE, FR.PA, NL.AS, GR.AT, IE.IR, AT.VI, IT.MI, ES.MC, FI.HE, BE.BR, PT.LS, …

  3. If neither matches, the first equity/ETF/mutual-fund result wins.

This covers 40+ ISIN country codes across Europe, Asia/Pacific, the Americas, the Middle East, and Africa. The complete maps live in CURRENCY_TO_SUFFIX and COUNTRY_TO_SUFFIX in ticker_resolver.py.

Examples

ISIN

Currency

Resolved ticker

How

SE0015192067

SEK

SAVE.ST

Yahoo Search, .ST matched currency

GRS469003024

EUR

KRI.AT

Yahoo Search, .AT matched country

CH0024608827

CHF

PGHN.SW

Yahoo Search, .SW matched currency

GB00B1YW4409

GBP

III.L

Yahoo Search, .L matched currency

JP3389510003

JPY

6544.T

Yahoo Search, .T matched currency

US50155Q1004

USD

KD

Yahoo Search (Kyndryl)

DE0007164600

EUR

SAP.DE

Manual override

Forcing a re-resolve

If you upgraded from a version that couldn’t resolve tickers for some markets, clear the cached tickers and trigger a refresh:

from src.degiro_portfolio.database import SessionLocal, Stock
db = SessionLocal()
db.query(Stock).update({Stock.yahoo_ticker: None})
db.commit()

Then click Update Market Data in the web UI (or POST /api/update-market-data).

Pinning a specific listing

If Yahoo’s first result is wrong for a particular stock, add an entry to MANUAL_TICKER_MAPPING:

MANUAL_TICKER_MAPPING: Dict[str, Dict[str, str]] = {
    # ... existing mappings ...
    "GB0005405286": {"GBP": "HSBA.L"},  # HSBC Holdings - London
}

Manual mappings are checked first, before any network call, and always win.

For deeper internals (full mapping tables, troubleshooting, migration from old hard-coded mappings), see TICKER_RESOLUTION.md in the project root.

Rate Limiting

Yahoo Finance has undocumented rate limits (~2000 requests/hour). The application automatically throttles requests (~20/minute) to stay within limits.

If you see rate limit errors:

  • Wait 60 seconds and try again

  • Exchange rates are cached daily to reduce API calls

  • The app falls back gracefully when limits are hit

Environment Variables

You can optionally create a .env file in the project root:

PRICE_DATA_PROVIDER=yahoo

# Optional: adjust fetch periods
INITIAL_FETCH_PERIOD=max
INDEX_FETCH_PERIOD=5y
UPDATE_FETCH_PERIOD=7d

Troubleshooting

“No data returned” for a stock

  • Check if the ticker symbol is correct

  • The stock might be delisted or only available on regional exchanges

  • Try clicking “Update Market Data” again

Rate limit errors

  • Wait 60 seconds and try again

  • The app auto-throttles, but rapid manual refreshes can hit limits

Notes

  • Historical data is stored in the local database

  • Switching data providers doesn’t affect stored data

  • You can re-fetch data at any time by clicking “Update Market Data”