Quick answer
A useful FX macro model does not need to predict every release. It needs a repeatable way to turn official releases, forecast expectations, and release timing into comparable country scores. FXMacroData gives those inputs a shared structure: confirmed release calendars, released observations, source-labelled forecasts, and coverage metadata.
Most FX macro frameworks start with the same economic building blocks: growth, inflation, labour, policy, external balance, money, and sentiment. The hard part is turning those blocks into a model that updates consistently, respects release timing, and can be reviewed after each data cycle.
This guide shows how to build an EUR/USD-style country scorecard with FXMacroData as the data layer. The same structure works for any supported pair: score the base currency, score the quote currency, then trade the spread only when the macro evidence and price action agree.
Use case
Analysts, traders, and developers building a repeatable FX macro signal from official releases, forecasts, and coverage metadata.
Coverage basis
Inputs are selected from FXMacroData coverage metadata, so each factor has clear timing, units, and source labels.
Main output
A country-level macro score and a pair-level spread score for dashboards, research notes, alerts, and backtests.
Define a Comparable Data Universe
Start by deciding which economic concepts can be measured consistently for the currencies in the pair. The FXMacroData catalogue is useful here because it exposes coverage, units, frequency, and availability before the model assigns weights.
Some macro concepts have several reasonable proxies. A hard activity measure, a confidence survey, an output series, and a construction release can all describe the cycle, but they do not carry the same meaning. Treat coverage gaps as a signal to reduce confidence, not as a reason to force a weak proxy into a high-weight bucket.
Coverage quality: a smaller model with clear release timing, units, and source labels is easier to audit than a wide model built from mismatched factors. Score strong buckets normally, scale down partial buckets, and keep sparse currencies transparent in the output.
Map Supported Indicators to Macro Buckets
Start with the economic logic, then use the FXMacroData catalogue to decide which indicators can actually enter the model for each currency.
| Macro bucket | Supported FXMacroData inputs | Scoring idea |
|---|---|---|
| Growth | GDP, retail sales, building permits, construction-related releases where covered | Positive when growth momentum improves versus the currency's own recent history. |
| Inflation | CPI, core inflation, PCE or local inflation variants where covered | Positive for the currency when inflation pressure raises policy-rate support, unless growth risk dominates. |
| Labour | Unemployment rate, Non-Farm Payrolls, wages and participation where available | Positive when employment momentum is firm and unemployment is falling. Keep level and trend separate when unemployment gaps are not directly modelled. |
| Policy | Policy rate, central-bank releases, policy-sensitive inflation and labour data | Positive when realised data and central-bank communication point to tighter relative policy. |
| External balance | Trade balance, current account where covered | Positive when external balances improve or terms-of-trade pressure eases. |
| Money and liquidity | M2, risk-free rates, bond yields, liquidity-sensitive market datasets where covered | Use as a regime filter rather than a single-release trigger. |
| Sentiment and activity surveys | Business confidence, consumer confidence, supported official survey proxies | Positive when confidence improves and confirms hard-data momentum. |
Build the Scorecard Workflow
The core workflow has four layers: coverage, observations, forecasts, and pair scoring. The release calendar tells you when data becomes known, announcements carry released values, and predictions carry source-labelled expectations where FXMacroData has them.
1. Coverage
Use the data catalogue to decide which buckets are scoreable.
2. Actuals
Pull released values from announcements.
3. Expectations
Use source-labelled predictions only when available.
4. FX spread
Subtract quote-country score from base-country score.
Prerequisites
- An FXMacroData API key.
- A target pair, such as EUR/USD, GBP/USD, or AUD/JPY.
- A defined research horizon, such as intraday event monitoring, weekly macro review, or medium-term regime scoring.
- A decision on bucket weights before you inspect the next release.
Step 1: Check what the currency can score
A universal indicator list will usually break across currencies. Start with the catalogue, then keep rows that are available, timely, and usable for signal work.
curl "https://api.fxmacrodata.com/v1/data_catalogue/usd?include_coverage=true&api_key=YOUR_API_KEY"
A model can then require available=true, recent coverage, and a compatible unit/frequency before an indicator is allowed into the scorecard.
import requests
API_KEY = "YOUR_API_KEY"
root = "https://api.fxmacrodata.com/v1"
def catalogue(currency):
url = f"{root}/data_catalogue/{currency.lower()}"
params = {"include_coverage": "true", "api_key": API_KEY}
return requests.get(url, params=params, timeout=20).json()
usd_catalogue = catalogue("usd")
Step 2: Pull observations with release timing
For each selected indicator, use the announcements route. Keep date for the observation period and announcement_datetime for the moment the value became known.
curl "https://api.fxmacrodata.com/v1/announcements/usd/inflation?seasonality=sa&frequency=qoq&annualization=saar&start_date=2026-01-01&end_date=2026-12-31&limit=100&api_key=YOUR_API_KEY"
That distinction matters. A Q2 inflation observation can have a quarter-end date of 30 June while the release arrives in July. A backtest or live scorecard should not treat the value as known before the release timestamp.
Step 3: Convert each indicator into a signed factor
Raw values are not comparable. A 0.3% monthly inflation print, a 150k payrolls print, and a 5.25% policy rate need to become standardised factor scores.
| Transform | Use when | Example |
|---|---|---|
| Rolling z-score | You want the latest value relative to its own history. | (latest - rolling_mean) / rolling_std |
| Direction score | Higher is not always better. | Falling unemployment is positive, so multiply the unemployment z-score by -1. |
| Surprise score | A matching FXMacroData forecast exists for the same period and unit. | actual - forecast, scaled by historical surprise volatility. |
def signed_zscore(values, higher_is_positive=True, window=24):
latest = values[-1]
hist = values[-window:]
mean = sum(hist) / len(hist)
variance = sum((x - mean) ** 2 for x in hist) / max(len(hist) - 1, 1)
z = (latest - mean) / (variance ** 0.5 or 1)
return z if higher_is_positive else -z
Add Forecast Surprises Without Lookahead
Forecasts should be treated by source label. A market_consensus row is a market consensus row. A survey row is a survey row. A model should not rename one as the other simply because both can be used as expectations.
The FXMacroData Predictions API keeps those expectations separate from released observations and links them to the same announcement_id. That makes the join explicit.
curl "https://api.fxmacrodata.com/v1/predictions/usd/inflation?seasonality=sa&frequency=qoq&annualization=saar&prediction_type=survey&start_date=2026-01-01&end_date=2026-12-31&limit=100&api_key=YOUR_API_KEY"
When a prediction row and an announcement row share an announcement identifier, the scorecard can join the expectation and the realised value without guessing the release period:
{
"announcement_id": "usd_inflation_example",
"date": "2026-06-30",
"announcement_datetime": 1784032200,
"predictions": [
{
"predicted_value": 2.4,
"prediction_type": "survey",
"prediction_source": "survey_source"
}
]
}
The matching announcement row carries the realised value:
{
"announcement_id": "usd_inflation_example",
"date": "2026-06-30",
"val": 2.55,
"announcement_datetime": 1784032200,
"source": "official_source"
}
In this simplified example, the surprise is 2.55 - 2.40 = +0.15 percentage points. Because the forecast and actual use the same frequency, seasonality, annualisation, observation date, and release identifier, the surprise is suitable for a clean scorecard.
Turn Country Scores Into an FX Pair Score
A pair model should compare countries rather than score one currency in isolation. Build a country score for each side, then subtract the quote side from the base side.
Example country score
country_score = 0.25 * growth + 0.25 * inflation + 0.20 * labour + 0.20 * policy + 0.10 * external_balance
pair_score = base_country_score - quote_country_score
weights = {
"growth": 0.25,
"inflation": 0.25,
"labour": 0.20,
"policy": 0.20,
"external": 0.10,
}
def country_score(bucket_scores):
return sum(weights[k] * bucket_scores.get(k, 0.0) for k in weights)
eur_usd_score = country_score(eur_buckets) - country_score(usd_buckets)
Use thresholds to keep the output practical. For example, a score near zero can mean "no macro edge"; a high positive score can mean the base currency has stronger macro support; a high negative score can mean the quote currency has stronger support. The score should guide idea selection, not replace execution rules.
Plot the Model Outputs
Interactive charts make a macro scorecard easier to audit. A good model view should show which buckets are driving the country score, whether surprises are coming from clean expectation joins, and when the pair spread is strong enough to matter.
Bucket score comparison
Compare the base and quote currency by macro bucket before combining them into a pair score.
Takeaway: the pair signal is easier to trust when the strongest buckets are visible, not hidden inside one blended number.
Actual, expectation, and surprise
Plot expectations beside released values so the model separates trend strength from release-day surprise.
Takeaway: a surprise score is only useful when the forecast and actual use the same observation period, units, and release identifier.
Pair macro spread
Track the base-minus-quote spread through time and mark the zones where the score is strong enough to become a research lead.
Takeaway: the chart should make stale, neutral, and high-conviction regimes obvious before a trade idea reaches execution.
Review the Model After Each Release Cycle
Macro scorecards improve through review. After each major release week, record which bucket moved, whether the release was a trend confirmation or a surprise, and whether the currency pair followed through over the next few sessions.
| Review item | Question |
|---|---|
| Coverage | Were the scored inputs covered by FXMacroData with compatible units and timing? |
| Timing | Was the score updated only after announcement_datetime? |
| Surprise | Did the forecast and actual use the same frequency, seasonality, and unit? |
| Decision value | Did large score changes improve the quality of alerts, research notes, backtests, or trade filters? |
Common Questions
How should expectation sources be used?
Treat each prediction source label as its own expectation stream. A market_consensus row, survey forecast, model nowcast, central-bank projection, and blended forecast can all be useful, but they should be scored and reviewed separately unless the model has a deliberate blend method.
How should the model handle indicators that are not covered?
Use the catalogue to separate strong, partial, and unavailable buckets. If a related indicator measures the same economic concept, it can be used with a lower confidence weight. If coverage is too thin, mark that bucket as unavailable for the currency rather than overstating the signal.
What should I do when a currency has sparse coverage?
Use fewer buckets, lower confidence weights, and clearer labels. Sparse coverage is still useful when the output tells the reader which parts of the country score are strong, partial, or unavailable.
Does the scorecard generate trades automatically?
No. The scorecard ranks macro support across currencies. Execution still needs liquidity, volatility, price confirmation, and risk controls. The model is most useful as a repeatable research layer that can feed alerts, dashboards, backtests, and trade filters.
Related FXMacroData Resources
- API reference for endpoint shapes and query parameters.
- Release Calendar for confirmed event timing.
- Predictions API guide for forecast and surprise workflows.
- USD inflation API docs for CPI examples and available query options.
The final model is deliberately conservative: it favours comparable inputs, transparent coverage, and release-aware scoring over a long list of loosely related variables. That is what makes the output repeatable enough to use in a trading process.