Obscura

FX Rates

Reference exchange rates between major currencies.

fx_rates — the dataset name to pass to the Obscura API.

Category Markets Columns 4 Refresh Daily Point-in-time available_date

What one row means

One daily ECB reference exchange rate for a single base/quote currency pair, sourced from the keyless Frankfurter API (which mirrors the ECB's official daily reference rates): units of `quote` per one unit of `base` as published for a given calendar day.

One row per (available_date, base, quote).

Point-in-time availability

Every Obscura dataset carries available_date: the calendar day the publisher made the row available, day-of, with no session rounding. It is the one column a backtest filters on, and it means the same thing on every dataset in the catalog.

For fx_rates: published: available_date = the ECB's daily reference-rate publication day (~16:00 CET on each TARGET business day) — the day the rate is dated IS the day it became public, no separate filing/period lag to strip out.

Refresh cadence

Obscura refreshes fx_rates daily — the most frequent scheduled job that re-collects or re-exports it. This is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when a row became public is recorded per row in available_date.

Schema — 4 columns

The full public column list for fx_rates, with the meaning of every field. The same schema is served unauthenticated at https://api.obscura.trade/v1/catalog/fx_rates.

ColumnTypeDescription
available_datedate · not nullThe ECB reference-rate date, taken verbatim from the Frankfurter response's `date` field. Since ECB publishes once daily and the rate "for" this day only exists once published (~16:00 CET that same TARGET business day), this date is simultaneously the natural quote date and the true public-availability date — not a leaked period/as-of date. Part of the composite primary key with base and quote; falls back to the prior business day's date on weekends/ECB holidays since Frankfurter/ECB does not publish rates on non-TARGET days.
basetext · not nullThree-letter ISO 4217 currency code the rate is quoted FROM — the base currency of the pair, e.g. "USD". Part of the composite primary key.
quotetext · not nullThree-letter ISO 4217 currency code the rate is quoted TO — one of the ~30 currencies in the Frankfurter/ECB response's `rates` map keyed against `base` (e.g. "EUR", "JPY", "GBP"). Part of the composite primary key; a base currency never appears as its own quote (Frankfurter omits the identity pair).
ratedouble precision · not nullUnits of `quote` per one unit of `base`, taken directly from the Frankfurter response's `rates[quote]` value with no unit conversion or scaling applied. On conflict this is the one column updated, so a later sync of the same (available_date, base, quote) overwrites the rate with the newest value the API reports for that day.

Access fx_rates

Two delivery paths, one identifier. Both require an Obscura account and an active subscription; the catalog entry and the schema above are public.

import obscura

client = obscura.Client("obs_live_…")

df = client.query(
    dataset="fx_rates",
    start="2024-01-01",
)

Create a free account Browse all 95 datasets

Frequently asked questions

What is in the fx_rates dataset?

Reference exchange rates between major currencies. One daily ECB reference exchange rate for a single base/quote currency pair, sourced from the keyless Frankfurter API (which mirrors the ECB's official daily reference rates): units of `quote` per one unit of `base` as published for a given calendar day.

How do I avoid look-ahead bias with fx_rates?

Filter on fx_rates.available_date, the day the publisher made the row public. For this dataset that date is derived as follows — published: available_date = the ECB's daily reference-rate publication day (~16:00 CET on each TARGET business day) — the day the rate is dated IS the day it became public, no separate filing/period lag to strip out. A query of the form WHERE available_date <= '<as-of date>' never sees a row before it existed.

In what formats can I get fx_rates?

As a Parquet bulk export (POST https://api.obscura.trade/v1/download) or as JSON from the typed query API (POST https://api.obscura.trade/v1/query), both with dataset="fx_rates". The column schema is public at https://api.obscura.trade/v1/catalog/fx_rates.

How often is fx_rates updated?

Obscura refreshes fx_rates on a daily schedule — that is the most frequent scheduled job that re-collects or re-exports the table. It is Obscura's own pipeline cadence, not the upstream publisher's release schedule; when the publisher makes a row available is described by the availability rule above, and is recorded per row in available_date.

Related datasets

Cboe IndicesDaily history of Cboe's volatility indices, including VIX, sourced directly from Cboe. Crypto MarketsPer-coin market data from CoinGecko: price, market cap and volume across thousands of cryptocurrencies. DeFiLlama ProtocolsTotal value locked in each DeFi protocol, tracked by DeFiLlama. DeFiLlama StablecoinsCirculating supply of each stablecoin over time, from DeFiLlama. DeFiLlama TVLTotal value locked on each blockchain, from DeFiLlama. Flow MetricsTrade-flow metrics per symbol in fixed time windows: taker (aggressor) buy versus sell volume and trade counts, broken o… Forex OrderbookOANDA's order book and position book by currency pair: where retail traders' open orders and positions sit relative to p… Forex PositionsRetail forex positioning by pair (share of traders long versus short), collected from several broker sentiment feeds.