FX Rate Import
Import historical exchange rates from FRED, ECB, or OpenExchangeRates
Overview
The FX system supports multiple exchange rate providers to pre-populate the database with historical rates. This allows ticket imports to use cached rates instead of making live API calls.
Providers
| Provider | Base Currency | Currencies | Cost | Best For |
|---|---|---|---|---|
| FRED (Federal Reserve) | USD | 20+ major | Free | USD-based historical data |
| ECB (European Central Bank) | EUR | 32 | Free | EUR-based historical data |
| OpenExchangeRates | USD | 170+ | Paid | Exotic currencies, live rates |
FRED (Recommended for USD)
The Federal Reserve Economic Data (FRED) API provides free historical exchange rates from 2000+.
Setup
- Get a free API key: https://fred.stlouisfed.org/docs/api/api_key.html
- Add to your
.env:FRED_API_KEY=your_api_key_here
Bulk Import
# Import rates from 2020 to today (default)
bun run packages/api/src/scripts/fx-import.ts
# Custom date range
FX_START_DATE=2022-01-01 FX_END_DATE=2024-12-31 bun run packages/api/src/scripts/fx-import.tsSupported Currencies
FRED provides USD-based rates for major currencies:
USD (base), EUR, GBP, JPY, CHF, AUD, CAD, SEK, NOK, DKK,
NZD, ZAR, BRL, CNY, HKD, INR, KRW, MXN, MYR, SGD, THB, TWDDaily Updates (Cron)
To keep rates fresh, run the daily job:
# Manually
bun run apps/server/src/jobs/fx-daily.ts
# Via cron (6 AM ET daily, after FRED updates at ~5 PM ET previous day)
0 11 * * * FRED_API_KEY=xxx bun run /path/to/apps/server/src/jobs/fx-daily.tsECB (European Central Bank)
The ECB API provides free historical rates with EUR as the base currency.
Usage
# From packages/api directory
bun run fx:import --start 2020-01-01
# With options
bun run fx:import --start 2020-01-01 --end 2024-12-31 --currencies USD,GBP,CHFOptions
| Option | Description |
|---|---|
--start <date> | Start date (required, YYYY-MM-DD) |
--end <date> | End date (default: today) |
--currencies <list> | Comma-separated codes (default: all) |
--dry-run | Preview without saving |
Supported Currencies
ECB publishes daily rates for 32 currencies against EUR:
EUR (base), USD, GBP, JPY, CHF, AUD, CAD, SEK, NOK, DKK,
PLN, CZK, HUF, RON, BGN, HRK, ISK, TRY, NZD, ZAR,
BRL, CNY, HKD, IDR, ILS, INR, KRW, MXN, MYR, PHP, SGD, THBOpenExchangeRates (Fallback)
OpenExchangeRates is a paid service that provides 170+ currencies including exotic ones not available from FRED or ECB.
Setup
- Sign up at https://openexchangerates.org/signup
- Add to your
.env:OXR_APP_ID=your_app_id_here
When It's Used
OXR is automatically used as a fallback when:
- The requested currency pair isn't supported by FRED or ECB
- Historical rates aren't cached in the database
Pricing
- Free tier: 1,000 requests/month, hourly updates
- Developer: $12/month, 10,000 requests, hourly updates
- Enterprise: Higher limits, minute-level updates
How the FX Service Works
- Cache Check: First looks for cached rate in
FxRatetable - Provider Selection: Chooses best provider based on currency support:
- ECB for EUR-based pairs
- FRED for USD-based pairs (when configured)
- OXR as fallback for exotic currencies
- Cross-Rate Calculation: Computes rates between any two currencies:
GBP → JPY = (JPY/USD) / (GBP/USD) - Cache Storage: Stores fetched rates for future use
Import Optimization
During ticket imports, the system:
- Collects all unique currency/date pairs needed
- Batch-fetches cached rates from DB in one query
- Uses in-memory cache during row processing
- Only calls external APIs for cache misses
You'll see logs like:
[import] FX cache: 176/176 rates found in DBEnvironment Variables
| Variable | Required | Description |
|---|---|---|
FRED_API_KEY | No | FRED API key for USD-based rates |
OXR_APP_ID | No | OpenExchangeRates app ID |
ECB_ENABLED | No | Enable/disable ECB (default: true) |
Notes
- ECB and FRED don't publish rates on weekends/holidays
- All imports are idempotent (safe to re-run)
- Rates are stored with
isIntraday: false(end-of-day rates) - For best coverage, configure both FRED and OXR