Forecasting Macro Releases: How to Use the FXMacroData Predictions API banner image

Implementation

How-To Guides

Forecasting Macro Releases: How to Use the FXMacroData Predictions API

Market moves before the number drops. The FXMacroData predictions API surfaces market consensus, central-bank projections, IMF WEO forecasts, and survey data for every covered indicator — all linked to realised observations via a stable announcement_id so you can measure forecast accuracy and build lookahead-free backtests.

[MT] Предлага се и на English

Why forecasts matter as much as the number itself

FX markets do not move on data releases — they move on surprises. When the Federal Reserve or the European Central Bank publishes new data, the market has already formed an expectation. If the print matches the consensus, the pair barely twitches. If it deviates, you get the spike.

That gap — the distance between what was expected and what arrived — is where a large share of FX volatility lives. To work with it systematically, you need access to the forecast alongside the actual observation, linked together in a way that lets you compute the surprise without contaminating your data with lookahead.

The FXMacroData predictions API is built for exactly this workflow. It surfaces forecasts from five distinct source categories and links every prediction to its target announcement via a stable announcement_id, so you can join predictions with realised values, measure forecast accuracy over time, and build surprise indices for any indicator and currency combination you care about.


What the predictions endpoint returns

Two routes expose prediction data:

  • /api/v1/predictions/{currency} — all forecasts for a currency, across every indicator in the catalogue, with optional filters for indicator, prediction type, and source.
  • /api/v1/predictions/{currency}/{indicator} — all forecasts for a specific currency and indicator pair.

Both routes are free for USD. Non-USD currencies require a Professional API key.

The response groups entries by announcement. Each group carries the announcement_id — a stable, deterministic key in the form {currency}_{indicator}_{date} — followed by a predictions list where each entry records the forecast value, its source, and a human-readable label. Here is a minimal example for USD inflation:

{
  "currency": "USD",
  "indicator": "inflation",
  "count": 2,
  "prediction_count": 3,
  "data": [
    {
      "announcement_id": "usd_inflation_2026-02-28",
      "currency": "usd",
      "indicator": "inflation",
      "date": "2026-02-28",
      "announcement_datetime": 1772433000,
      "predictions": [
        {
          "predicted_value": 2.9,
          "prediction_type": "market_consensus",
          "prediction_source": "philly_fed_spf",
          "prediction_source_label": "Philadelphia Fed Survey of Professional Forecasters"
        }
      ]
    },
    {
      "announcement_id": "usd_inflation_2026-03-31",
      "currency": "usd",
      "indicator": "inflation",
      "date": "2026-03-31",
      "predictions": [
        {
          "predicted_value": 2.6,
          "prediction_type": "market_consensus",
          "prediction_source": "philly_fed_spf",
          "prediction_source_label": "Philadelphia Fed Survey of Professional Forecasters"
        },
        {
          "predicted_value": 2.5,
          "prediction_type": "imf_weo",
          "prediction_source": "imf_weo",
          "prediction_source_label": "IMF World Economic Outlook"
        }
      ]
    }
  ]
}

The announcement_id on every prediction row is identical to the one returned by /api/v1/announcements/{currency}/{indicator}, so a simple dictionary join is all you need to pair each forecast with its realised observation.


Prediction source categories

Five prediction_type values are currently recognised. Understanding the difference matters for how you weight and interpret each forecast:

prediction_type What it is Example sources
market_consensus Compiled market poll of professional forecasters Philadelphia Fed SPF, Reuters poll
market_prediction Individual professional-forecaster point prediction Forecaster-level disaggregated survey data
survey Central-bank survey of professional forecasters ECB Survey of Professional Forecasters
central_bank_forecast Official central-bank projection published in monetary policy statements RBNZ Monetary Policy Statement, BoC Monetary Policy Report
imf_weo IMF World Economic Outlook projection Published twice yearly, all supported currencies

Each source serves a different analytical purpose. Market consensus is the short-horizon market expectation that drives immediate FX reaction on release day. Central-bank forecasts reflect the institution's own outlook and are useful for tracking how much the bank's projections evolve between meetings. IMF WEO forecasts provide a neutral multi-year baseline and are consistent across all 18 covered currencies, making them useful for cross-currency comparisons.


Building a surprise index in Python

The most direct application of the predictions API is computing a release surprise index — the deviation of the actual print from the market expectation, expressed in standard deviations of historical surprises. Here is a complete example for US Non-Farm Payrolls:

import requests
import statistics

BASE = "https://fxmacrodata.com/api"

# Fetch predictions — free for USD, no key needed
preds_resp = requests.get(
    f"{BASE}/v1/predictions/usd/non_farm_payrolls",
    params={"prediction_type": "market_consensus"},
    timeout=30,
).json()

# Fetch actuals
actuals_resp = requests.get(
    f"{BASE}/v1/announcements/usd/non_farm_payrolls",
    params={"start_date": "2020-01-01"},
    timeout=30,
).json()

# Index actuals by announcement_id
actuals = {row["announcement_id"]: row["val"] for row in actuals_resp["data"]}

# Compute surprises (actual - consensus)
surprises = []
for group in preds_resp["data"]:
    aid = group["announcement_id"]
    actual = actuals.get(aid)
    if actual is None:
        continue
    # Use the first (or only) prediction in the group
    forecast = group["predictions"][0]["predicted_value"]
    surprises.append({
        "date": group["date"],
        "actual": actual,
        "forecast": forecast,
        "surprise": actual - forecast,
    })

# Normalise to z-scores
values = [s["surprise"] for s in surprises]
mean = statistics.mean(values)
stdev = statistics.stdev(values)
for s in surprises:
    s["z_score"] = (s["surprise"] - mean) / stdev

# Print recent surprises
for s in surprises[-6:]:
    direction = "↑ beat" if s["z_score"] > 0 else "↓ miss"
    print(f"{s['date']}: actual={s['actual']:,.0f}k  forecast={s['forecast']:,.0f}k  "
          f"surprise={s['surprise']:+,.0f}k  z={s['z_score']:+.2f}  {direction}")

The output gives you a time series of normalised surprises that can be directly correlated with USD spot moves on release days to quantify the surprise-to-FX transmission coefficient for any given indicator.


Comparing central-bank forecasts to market consensus

A useful signal in rate-sensitive currency pairs is the divergence between what the central bank projects and what the market expects. When the two converge, it often signals that the market has fully digested the bank's guidance. When they diverge, it can indicate either a credibility gap or a genuine information asymmetry between the bank and the buy side.

You can retrieve both forecast types in a single request and compute the divergence directly:

import requests

# Fetch all prediction types for EUR inflation together
resp = requests.get(
    "https://fxmacrodata.com/api/v1/predictions/eur/inflation",
    params={"api_key": "YOUR_API_KEY"},
    timeout=30,
).json()

# For each announcement group, compare central_bank_forecast vs market_consensus
for group in resp["data"]:
    preds_by_type = {p["prediction_type"]: p for p in group["predictions"]}
    cb = preds_by_type.get("central_bank_forecast")
    mkt = preds_by_type.get("market_consensus")
    if cb and mkt:
        divergence = cb["predicted_value"] - mkt["predicted_value"]
        print(f"{group['date']}: CB={cb['predicted_value']:.2f}%  "
              f"Market={mkt['predicted_value']:.2f}%  "
              f"Divergence={divergence:+.2f}pp  "
              f"({cb['prediction_source_label']})")

Positive divergence (the central bank projects higher inflation than the market) is typically a hawkish signal. The bank either has non-public information or is deliberately signalling tolerance for above-target inflation. Sustained positive divergence has historically preceded surprise hikes in several currency pairs tracked on the release calendar.


Cross-currency forecast comparison with IMF WEO

Because IMF WEO projections exist for every covered currency and use a consistent methodology, they are well-suited to cross-currency comparisons. The following snippet pulls GDP forecasts for the four major commodity-linked currencies and ranks them by expected growth:

import requests

API_KEY = "YOUR_API_KEY"
CURRENCIES = ["aud", "cad", "nzd", "nok"]

forecasts = {}
for ccy in CURRENCIES:
    resp = requests.get(
        f"https://fxmacrodata.com/api/v1/predictions/{ccy}/gdp",
        params={"prediction_type": "imf_weo", "api_key": API_KEY},
        timeout=30,
    ).json()
    if resp.get("data"):
        # Take the most recent forecast
        latest = resp["data"][-1]
        forecasts[ccy.upper()] = latest["predictions"][0]["predicted_value"]

# Rank by projected growth
ranked = sorted(forecasts.items(), key=lambda x: x[1], reverse=True)
print("IMF WEO GDP forecast ranking:")
for rank, (ccy, val) in enumerate(ranked, 1):
    print(f"  {rank}. {ccy}: {val:.1f}% YoY")

This kind of ranking feeds naturally into relative-value frameworks for commodity-currency pairs like AUD/CAD or NZD/AUD, where growth differentials are a primary driver of medium-term carry positioning.


Filtering by prediction source

When a single announcement has multiple predictions from different sources, you may want to isolate a specific one. Use the prediction_source query parameter with the stable source slug:

# Philadelphia Fed Survey of Professional Forecasters only
curl "https://fxmacrodata.com/api/v1/predictions/usd/inflation?prediction_source=philly_fed_spf"

# ECB Survey of Professional Forecasters (requires API key)
curl "https://fxmacrodata.com/api/v1/predictions/eur/inflation?prediction_source=ecb_spf&api_key=YOUR_API_KEY"

# RBNZ Monetary Policy Statement (requires API key)
curl "https://fxmacrodata.com/api/v1/predictions/nzd/inflation?prediction_source=rbnz_mps&api_key=YOUR_API_KEY"

# IMF World Economic Outlook
curl "https://fxmacrodata.com/api/v1/predictions/usd/inflation?prediction_source=imf_weo"

The prediction_source_label field in the response gives the full human-readable name of the source, suitable for chart labels and report footnotes. Use the stable prediction_source slug for filtering and programmatic joins.


Using the release calendar for upcoming forecasts

The release calendar surfaces upcoming announcement dates for all covered currencies. When you combine calendar data with the predictions endpoint, you can build a forward-looking dashboard that shows the current consensus for each upcoming release.

import requests
from datetime import date

API_KEY = "YOUR_API_KEY"
BASE = "https://fxmacrodata.com/api"

# Get upcoming USD releases
calendar = requests.get(f"{BASE}/v1/calendar/usd").json()
upcoming = [row for row in calendar["data"] if row.get("release")]

# For each upcoming release, fetch the current consensus prediction
for release in upcoming[:5]:
    indicator = release["release"]
    preds = requests.get(
        f"{BASE}/v1/predictions/usd/{indicator}",
        params={"prediction_type": "market_consensus"},
        timeout=30,
    ).json()
    if preds.get("data"):
        latest_pred = preds["data"][-1]
        if latest_pred.get("predictions"):
            val = latest_pred["predictions"][0]["predicted_value"]
            print(f"{indicator}: consensus={val}")

Endpoint reference summary

Full parameter documentation is available on the API reference page. The table below gives a quick reference for the two predictions routes:

Parameter Type Description
currencypath3-letter currency code. USD is free; others require a key.
indicatorpath or queryIndicator slug (e.g. inflation, policy_rate, gdp). Path in the /{currency}/{indicator} route; optional query on /{currency}.
prediction_typequeryOne of market_consensus, market_prediction, survey, central_bank_forecast, imf_weo, fxmacrodata.
prediction_sourcequeryStable source slug (e.g. philly_fed_spf, ecb_spf, imf_weo).
start_date / end_datequeryPeriod date range (YYYY-MM-DD). Defaults to last 12 months / today.
api_keyqueryProfessional API key. Required for non-USD currencies.

The predictions API is designed to sit alongside the inflation, policy rate, and other indicator overview pages — where cross-currency comparisons are most useful — and the release calendar, where the timing of upcoming announcements meets the forecasts that precede them.

Blogroll