From bd7637eada283898a905bb02130f740e816fc546 Mon Sep 17 00:00:00 2001 From: Robert Tidball Date: Wed, 8 Jul 2026 20:49:42 +1000 Subject: [PATCH] Add FXMacroData integration --- quantmind/preprocess/fetch/__init__.py | 6 ++++ quantmind/preprocess/fetch/fxmacrodata.py | 41 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 quantmind/preprocess/fetch/fxmacrodata.py diff --git a/quantmind/preprocess/fetch/__init__.py b/quantmind/preprocess/fetch/__init__.py index adf3bef..8c75932 100644 --- a/quantmind/preprocess/fetch/__init__.py +++ b/quantmind/preprocess/fetch/__init__.py @@ -17,15 +17,21 @@ DEFAULT_USER_AGENT, fetch_url, ) +from quantmind.preprocess.fetch.fxmacrodata import ( + DEFAULT_FXMACRODATA_BASE_URL, + fetch_fxmacrodata_calendar, +) from quantmind.preprocess.fetch.local import read_local_file __all__ = [ "ArxivIdParseError", "CrossrefMetadata", + "DEFAULT_FXMACRODATA_BASE_URL", "DEFAULT_USER_AGENT", "Fetched", "RawPaper", "fetch_arxiv", + "fetch_fxmacrodata_calendar", "fetch_url", "read_local_file", "resolve_doi", diff --git a/quantmind/preprocess/fetch/fxmacrodata.py b/quantmind/preprocess/fetch/fxmacrodata.py new file mode 100644 index 0000000..0719a27 --- /dev/null +++ b/quantmind/preprocess/fetch/fxmacrodata.py @@ -0,0 +1,41 @@ +"""FXMacroData fetch helpers for macroeconomic context.""" + +from __future__ import annotations + +from typing import Any, Optional + +import httpx + +DEFAULT_FXMACRODATA_BASE_URL = "https://fxmacrodata.com/api/v1" + + +async def fetch_fxmacrodata_calendar( + currency: str = "usd", + *, + limit: int = 50, + api_key: Optional[str] = None, + base_url: str = DEFAULT_FXMACRODATA_BASE_URL, + timeout: float = 30.0, +) -> dict[str, Any]: + """Fetch official release-calendar rows from FXMacroData. + + The function returns the parsed JSON payload so callers can preserve + FXMacroData metadata such as data quality, source names, and confirmed + announcement timestamps when building knowledge items. + """ + + limit_count = max(1, min(int(limit), 100)) + params: dict[str, str] = {"limit": str(limit_count)} + if api_key: + params["api_key"] = api_key + + url = f"{base_url.rstrip('/')}/calendar/{currency.lower()}" + headers = {"User-Agent": "QuantMind/0.2 fxmacrodata-fetch"} + async with httpx.AsyncClient(timeout=timeout, follow_redirects=True) as client: + response = await client.get(url, params=params, headers=headers) + response.raise_for_status() + payload: dict[str, Any] = response.json() + if isinstance(payload.get("data"), list): + payload["data"] = payload["data"][:limit_count] + + return payload