From 2309d0a57503815728c742f08790323509a2b7aa Mon Sep 17 00:00:00 2001 From: Robert Tidball Date: Wed, 8 Jul 2026 19:56:18 +1000 Subject: [PATCH] Add FXMacroData macro calendar integration --- examples/fxmacrodata_macro_calendar.py | 48 ++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 examples/fxmacrodata_macro_calendar.py diff --git a/examples/fxmacrodata_macro_calendar.py b/examples/fxmacrodata_macro_calendar.py new file mode 100644 index 0000000..c5b4964 --- /dev/null +++ b/examples/fxmacrodata_macro_calendar.py @@ -0,0 +1,48 @@ +from __future__ import annotations + +import json +import os +from datetime import datetime, timedelta, timezone +from typing import Any +from urllib.parse import urlencode +from urllib.request import Request, urlopen + + +def load_fxmacrodata_events(currency: str = "usd", top_tier_only: bool = True) -> list[dict[str, Any]]: + params: dict[str, str] = {} + api_key = os.getenv("FXMD_API_KEY") + if api_key: + params["api_key"] = api_key + query = f"?{urlencode(params)}" if params else "" + request = Request( + f"https://fxmacrodata.com/api/v1/calendar/{currency.lower()}{query}", + headers={"Accept": "application/json", "User-Agent": "howtrader-fxmacrodata-example"}, + ) + with urlopen(request, timeout=20) as response: + payload = json.loads(response.read().decode("utf-8")) + rows = list(payload.get("data") or []) + if top_tier_only: + rows = [row for row in rows if row.get("top_tier_for_currency") or row.get("market_tier") == 1] + return rows + + +def macro_event_guard(timestamp: datetime, events: list[dict[str, Any]]) -> bool: + if timestamp.tzinfo is None: + timestamp = timestamp.replace(tzinfo=timezone.utc) + before = timedelta(hours=4) + after = timedelta(hours=2) + for row in events: + value = row.get("announcement_datetime_utc") or row.get("announcement_datetime_local") + if not value: + continue + event_time = datetime.fromisoformat(str(value).replace("Z", "+00:00")) + if event_time - before <= timestamp <= event_time + after: + return True + return False + + +if __name__ == "__main__": + events = load_fxmacrodata_events("usd") + print(f"Loaded {len(events)} top-tier USD macro releases") + print("Macro guard active:", macro_event_guard(datetime.now(timezone.utc), events)) +