feat: macro series
This commit is contained in:
@@ -663,6 +663,10 @@ def series_history(
|
|||||||
ff_params: list = [series_id]
|
ff_params: list = [series_id]
|
||||||
if from_date:
|
if from_date:
|
||||||
ff_where.append("event_date >= ?"); ff_params.append(from_date)
|
ff_where.append("event_date >= ?"); ff_params.append(from_date)
|
||||||
|
# Filter to the series' native currency to avoid mixing countries
|
||||||
|
ff_currency = meta.get("ff_currency")
|
||||||
|
if ff_currency:
|
||||||
|
ff_where.append("currency = ?"); ff_params.append(ff_currency)
|
||||||
|
|
||||||
ff_rows = conn.execute(
|
ff_rows = conn.execute(
|
||||||
f"SELECT event_date, event_time, event_name, actual_value, "
|
f"SELECT event_date, event_time, event_name, actual_value, "
|
||||||
|
|||||||
@@ -1228,6 +1228,16 @@ def init_db():
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# ── Migrations ────────────────────────────────────────────────────────────
|
||||||
|
# Re-assign ADP events that were incorrectly mapped to PAYEMS
|
||||||
|
try:
|
||||||
|
c.execute(
|
||||||
|
"UPDATE ff_calendar SET series_id = 'ADP_NFP' "
|
||||||
|
"WHERE series_id = 'PAYEMS' AND event_name LIKE 'ADP%'"
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|||||||
@@ -29,39 +29,56 @@ FRED_SERIES: Dict[str, Dict[str, Any]] = {
|
|||||||
"unit": "K",
|
"unit": "K",
|
||||||
"freq": "monthly",
|
"freq": "monthly",
|
||||||
"category": "employment",
|
"category": "employment",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": True,
|
"higher_is_bullish": True,
|
||||||
"assets": ["SPY", "QQQ", "EURUSD=X", "TLT"],
|
"assets": ["SPY", "QQQ", "EURUSD=X", "TLT"],
|
||||||
"zscore_window": 12,
|
"zscore_window": 12,
|
||||||
"transform": None,
|
"transform": None,
|
||||||
"delta_absolute": False,
|
"delta_absolute": False,
|
||||||
},
|
},
|
||||||
|
"ADP_NFP": {
|
||||||
|
"name": "ADP Non-Farm Employment",
|
||||||
|
"unit": "K",
|
||||||
|
"freq": "monthly",
|
||||||
|
"category": "employment",
|
||||||
|
"ff_currency": "USD",
|
||||||
|
"higher_is_bullish": True,
|
||||||
|
"assets": ["SPY", "QQQ"],
|
||||||
|
"zscore_window": 12,
|
||||||
|
"transform": None,
|
||||||
|
"delta_absolute": False,
|
||||||
|
"ff_only": True,
|
||||||
|
},
|
||||||
"UNRATE": {
|
"UNRATE": {
|
||||||
"name": "Unemployment Rate",
|
"name": "Unemployment Rate",
|
||||||
"unit": "%",
|
"unit": "%",
|
||||||
"freq": "monthly",
|
"freq": "monthly",
|
||||||
"category": "employment",
|
"category": "employment",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": False,
|
"higher_is_bullish": False,
|
||||||
"assets": ["SPY", "QQQ", "EURUSD=X"],
|
"assets": ["SPY", "QQQ", "EURUSD=X"],
|
||||||
"zscore_window": 12,
|
"zscore_window": 12,
|
||||||
"transform": None,
|
"transform": None,
|
||||||
"delta_absolute": True, # pp change (e.g. 4.1 → 4.0 = -0.1 pp)
|
"delta_absolute": True,
|
||||||
},
|
},
|
||||||
"CPIAUCSL": {
|
"CPIAUCSL": {
|
||||||
"name": "CPI All Items (YoY %)",
|
"name": "CPI All Items (YoY %)",
|
||||||
"unit": "%",
|
"unit": "%",
|
||||||
"freq": "monthly",
|
"freq": "monthly",
|
||||||
"category": "inflation",
|
"category": "inflation",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": False,
|
"higher_is_bullish": False,
|
||||||
"assets": ["TLT", "GLD", "EURUSD=X", "SPY"],
|
"assets": ["TLT", "GLD", "EURUSD=X", "SPY"],
|
||||||
"zscore_window": 12,
|
"zscore_window": 12,
|
||||||
"transform": "yoy_pct", # FRED gives index level → compute YoY
|
"transform": "yoy_pct",
|
||||||
"delta_absolute": True, # pp change between consecutive YoY readings
|
"delta_absolute": True,
|
||||||
},
|
},
|
||||||
"CPILFESL": {
|
"CPILFESL": {
|
||||||
"name": "Core CPI (YoY %)",
|
"name": "Core CPI (YoY %)",
|
||||||
"unit": "%",
|
"unit": "%",
|
||||||
"freq": "monthly",
|
"freq": "monthly",
|
||||||
"category": "inflation",
|
"category": "inflation",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": False,
|
"higher_is_bullish": False,
|
||||||
"assets": ["TLT", "GLD", "EURUSD=X"],
|
"assets": ["TLT", "GLD", "EURUSD=X"],
|
||||||
"zscore_window": 12,
|
"zscore_window": 12,
|
||||||
@@ -73,6 +90,7 @@ FRED_SERIES: Dict[str, Dict[str, Any]] = {
|
|||||||
"unit": "%",
|
"unit": "%",
|
||||||
"freq": "monthly",
|
"freq": "monthly",
|
||||||
"category": "inflation",
|
"category": "inflation",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": False,
|
"higher_is_bullish": False,
|
||||||
"assets": ["TLT", "GLD", "SPY"],
|
"assets": ["TLT", "GLD", "SPY"],
|
||||||
"zscore_window": 12,
|
"zscore_window": 12,
|
||||||
@@ -84,34 +102,36 @@ FRED_SERIES: Dict[str, Dict[str, Any]] = {
|
|||||||
"unit": "%",
|
"unit": "%",
|
||||||
"freq": "monthly",
|
"freq": "monthly",
|
||||||
"category": "monetary",
|
"category": "monetary",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": False,
|
"higher_is_bullish": False,
|
||||||
"assets": ["TLT", "SPY", "EURUSD=X", "GLD"],
|
"assets": ["TLT", "SPY", "EURUSD=X", "GLD"],
|
||||||
"zscore_window": 12,
|
"zscore_window": 12,
|
||||||
"transform": None,
|
"transform": None,
|
||||||
"delta_absolute": True, # bp/pp move
|
"delta_absolute": True,
|
||||||
},
|
},
|
||||||
"ICSA": {
|
"ICSA": {
|
||||||
"name": "Initial Jobless Claims",
|
"name": "Initial Jobless Claims",
|
||||||
"unit": "K",
|
"unit": "K",
|
||||||
"freq": "weekly",
|
"freq": "weekly",
|
||||||
"category": "employment",
|
"category": "employment",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": False,
|
"higher_is_bullish": False,
|
||||||
"assets": ["SPY", "QQQ"],
|
"assets": ["SPY", "QQQ"],
|
||||||
"zscore_window": 52,
|
"zscore_window": 52,
|
||||||
"transform": "div1000", # FRED gives raw count → display in K
|
"transform": "div1000",
|
||||||
"delta_absolute": False,
|
"delta_absolute": False,
|
||||||
},
|
},
|
||||||
"GDPC1": {
|
"GDPC1": {
|
||||||
# Real GDP level in billions (chained 2017$) → compute QoQ annualized growth
|
|
||||||
"name": "GDP Growth (QoQ Ann. %)",
|
"name": "GDP Growth (QoQ Ann. %)",
|
||||||
"unit": "%",
|
"unit": "%",
|
||||||
"freq": "quarterly",
|
"freq": "quarterly",
|
||||||
"category": "growth",
|
"category": "growth",
|
||||||
|
"ff_currency": "USD",
|
||||||
"higher_is_bullish": True,
|
"higher_is_bullish": True,
|
||||||
"assets": ["SPY", "QQQ", "EURUSD=X", "TLT"],
|
"assets": ["SPY", "QQQ", "EURUSD=X", "TLT"],
|
||||||
"zscore_window": 8,
|
"zscore_window": 8,
|
||||||
"transform": "qoq_annualized",
|
"transform": "qoq_annualized",
|
||||||
"delta_absolute": True, # pp change between quarterly readings
|
"delta_absolute": True,
|
||||||
},
|
},
|
||||||
"BAMLH0A0HYM2": {
|
"BAMLH0A0HYM2": {
|
||||||
"name": "HY Credit Spread (OAS)",
|
"name": "HY Credit Spread (OAS)",
|
||||||
@@ -122,7 +142,7 @@ FRED_SERIES: Dict[str, Dict[str, Any]] = {
|
|||||||
"assets": ["HYG", "LQD", "SPY"],
|
"assets": ["HYG", "LQD", "SPY"],
|
||||||
"zscore_window": 52,
|
"zscore_window": 52,
|
||||||
"transform": None,
|
"transform": None,
|
||||||
"delta_absolute": True, # pp change in spread
|
"delta_absolute": True,
|
||||||
},
|
},
|
||||||
"T10Y2Y": {
|
"T10Y2Y": {
|
||||||
"name": "Yield Spread 10Y-2Y",
|
"name": "Yield Spread 10Y-2Y",
|
||||||
@@ -294,6 +314,9 @@ def bootstrap_fred(
|
|||||||
if not meta:
|
if not meta:
|
||||||
logger.warning(f"[FRED bootstrap] Unknown series: {sid}")
|
logger.warning(f"[FRED bootstrap] Unknown series: {sid}")
|
||||||
continue
|
continue
|
||||||
|
if meta.get("ff_only"):
|
||||||
|
results[sid] = {"skipped": "ff_calendar only — no FRED fetch"}
|
||||||
|
continue
|
||||||
|
|
||||||
# Warm-up period: extra years before from_date for transform + z-score
|
# Warm-up period: extra years before from_date for transform + z-score
|
||||||
transform = meta.get("transform")
|
transform = meta.get("transform")
|
||||||
|
|||||||
Reference in New Issue
Block a user