Roboquant is an open-source Kotlin algorithmic trading platform for backtesting, notebooks, and live-trading workflows. The FXMacroData integration in the Roboquant repository is intentionally narrow: it shows how to use the FXMacroData release calendar as a macro-event risk gate around an existing strategy.
FxMacroDataCalendarSample.kt pattern to fetch FXMacroData release-calendar rows, extract top-tier macro-event dates, wrap your base Strategy, and return no signals when the current Roboquant Event falls inside a blackout date or window. This is a risk-control layer, not a signal generator.
The sample pairs FXMacroData calendar data with Roboquant's normal strategy flow. In the repository example, an EMACrossover strategy still creates the trading idea, while a MacroBlackoutStrategy decides whether macro-event timing should suppress signals for that event.
Fit
Use this for
Pausing or thinning strategy signals around scheduled top-tier macro releases such as policy, inflation, labor, and retail-sales events.
Choose Roboquant when
You want a Kotlin/JVM strategy layer where a calendar-aware wrapper can sit beside feeds, accounts, signals, and backtest runs.
Avoid
Treating the release calendar as a prediction feed. It is a scheduled-event timing input for risk control.
Why Roboquant Works for Calendar Guardrails
Roboquant strategies receive time-stamped events and return signals. That makes macro-event gating a clean wrapper problem: fetch a calendar before the run, convert high-impact releases into blackout dates or windows, and let the wrapper decide whether the delegated strategy should run for the current event time.
The Roboquant sample uses three simple pieces:
| Piece | Role in the integration | Why it matters |
|---|---|---|
fetchCalendar() |
Calls the FXMacroData release-calendar endpoint for a currency and date range. | Keeps the macro-event input outside the strategy loop. |
topTierBlackoutDates() |
Filters rows where top_tier_for_currency is true or market_tier is 1. |
Focuses the gate on scheduled events most likely to matter for the currency. |
MacroBlackoutStrategy |
Returns an empty signal list on blackout dates, otherwise delegates to the base strategy. | Separates market-entry logic from calendar risk control. |
Visual Check: Event Blackout Window
Before wiring the calendar into a strategy, decide how the release time maps to a block. The repository sample blocks by date. Intraday users can extend the same idea into a before-and-after window around the exact announcement_datetime.
Release-calendar gate
Block the strategy during scheduled event risk
The calendar row supplies the event time, tier, release name, and currency. The strategy wrapper decides whether the current Roboquant event is allowed to produce signals.
Input
Calendar
Filter
Tier 1
Output
No signal
Workflow Shape
The integration is easiest to reason about as a pre-run guardrail. Fetch the calendar once, build a set of blocked dates or windows, then pass that set into a strategy wrapper.
Step 1: Start from the Roboquant Sample
Start with the Roboquant repository and the sample file at roboquant/test/org/roboquant/samples/FxMacroDataCalendarSample.kt. Roboquant can be used as a Maven, Gradle, or Kotlin Toolchain dependency; the repository README shows the current dependency pattern and points to the Roboquant tutorial.
implementation group: 'org.roboquant', name: 'roboquant', version: 'VERSION'
The sample is marked as an ignored test, which is appropriate for an external API example. Use it as a template for your own project rather than treating it as a unit test that should run in every build.
Step 2: Fetch the FXMacroData Release Calendar
Inspect the calendar endpoint first. Public examples send the API key in the X-API-Key header when one is required. USD release-calendar rows are available for this kind of check without exposing a secret.
curl -H "X-API-Key: YOUR_API_KEY" "https://api.fxmacrodata.com/v1/calendar/USD?start_date=2026-07-01&end_date=2026-07-20"
The response includes the currency, timezone, quality metadata, and event rows. The fields that matter for this Roboquant use case are announcement_datetime, announcement_datetime_utc, release, name, market_tier, top_tier_for_currency, and release_date_confirmed.
The repository sample keeps the parser compact by filtering JSON text for top-tier events. In production code, parse the response with a JSON library and keep the raw response or normalized blackout set with your backtest artifacts.
private fun topTierBlackoutDates(rows: CalendarResponse): Set<LocalDate> {
return rows.data
.filter { it.topTierForCurrency || it.marketTier == 1 }
.map { it.announcementDateTime.atZone(ZoneOffset.UTC).toLocalDate() }
.toSet()
}
Step 3: Wrap the Strategy
Once the blackout set exists, the strategy wrapper is small. If the current Roboquant event falls inside the blackout set, return no signals. Otherwise, ask the delegated strategy to create signals normally.
private class MacroBlackoutStrategy(
private val delegate: Strategy,
private val blackoutDates: Set<LocalDate>,
private val zoneId: ZoneId = ZoneOffset.UTC
) : Strategy {
override fun createSignals(event: Event): List<Signal> {
val eventDate = event.time.atZone(zoneId).toLocalDate()
if (eventDate in blackoutDates) return emptyList()
return delegate.createSignals(event)
}
}
That wrapper is deliberately conservative. It does not change the feed, mutate account state, or modify the base strategy. It only controls whether the strategy is allowed to emit signals during macro-event risk.
Run checklist
- Fetch the calendar before the backtest run.
- Filter to the currencies and tiers that match the traded assets.
- Choose date-level or intraday blackout windows deliberately.
- Log which event suppressed each signal so performance differences can be audited.
Backtest Guardrails
A macro blackout filter is easy to add and easy to misuse. Keep the guardrail explicit so the backtest remains explainable.
| Guardrail | Why it matters |
|---|---|
| Cache the calendar snapshot | The backtest should be reproducible with the same event list. |
| Use confirmed scheduled rows | Future release rows should come from confirmed official schedules, not inferred cadence rules. |
| Keep the strategy signal separate | The calendar gate should suppress or allow signals; it should not become a hidden alpha rule. |
| Test window width | A date-level blackout is simple but may be too coarse for intraday strategies. |
| Audit blocked events | Review the event names, tiers, timestamps, and currencies that changed trades. |
The right blackout width depends on the strategy. A daily strategy may use the sample's date-level approach. A short-horizon intraday strategy should usually use the exact release timestamp, a pre-event buffer, and a post-event cooldown.
Related Links
- Open source FXMacroData integrations
- FXMacroData release calendar
- FXMacroData API quickstart
- FXMacroData API reference
Sources and References
- Roboquant open-source repository
- Roboquant FXMacroData calendar sample
- Roboquant tutorial
- FXMacroData OpenAPI schema
With that setup, FXMacroData gives Roboquant a scheduled-event risk layer: fetch the calendar once, choose the blackout rule, wrap the strategy, and make every suppressed signal visible in the backtest record.