feat: causal lab
This commit is contained in:
@@ -67,6 +67,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "MACRO_DATA_SURPRISE",
|
||||
"category": "monetary_shock",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 4, "absorption_days": 12, "decay_type": "exp"},
|
||||
"instruments": ["EURUSD", "SP500", "XAUUSD", "QQQ", "TLT", "USDJPY", "EEM", "GDX", "SLV"],
|
||||
"description": "Scheduled economic release vs consensus -> OIS repricing -> full asset repricing",
|
||||
"ai_rationale": "Hawkish surprise: OIS up -> 2Y up -> USD up -> EURUSD/USDJPY/EEM react; 10Y up -> TLT down, GDX/XAUUSD down. Growth channel -> SP500/QQQ up. Dovish miss: all reversed.",
|
||||
@@ -162,6 +163,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "CENTRAL_BANK_DECISION",
|
||||
"category": "central_bank",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 5, "absorption_days": 14, "decay_type": "exp"},
|
||||
"instruments": ["EURUSD", "SP500", "XAUUSD", "QQQ", "TLT", "USDJPY", "GBPUSD", "XLF", "EEM"],
|
||||
"description": "CB rate decision + forward guidance -> full curve repricing -> carry FX, bonds, equities",
|
||||
"ai_rationale": "Rate hike -> 2Y/10Y up -> carry differential -> EURUSD/USDJPY/GBPUSD down; TLT down; QQQ hardest hit (duration); XLF benefits from steeper curve. Dovish: all reversed. EEM suffers from USD rate rises (capital outflows).",
|
||||
@@ -254,6 +256,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "GROWTH_CORPORATE_SIGNAL",
|
||||
"category": "growth_shock",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 4, "absorption_days": 10, "decay_type": "exp"},
|
||||
"instruments": ["SP500", "QQQ", "IWM", "EURUSD", "XAUUSD", "HYG"],
|
||||
"description": "Corporate/macro growth signal -> earnings revision + risk appetite -> equities, credit, FX, Gold",
|
||||
"ai_rationale": "Earnings beats revise EPS upward and compress credit spreads (HYG up). QQQ > SP500 > IWM in tech-driven beats; IWM > SP500 in domestic growth signals. EURUSD follows risk appetite. Gold falls as safe haven demand recedes.",
|
||||
@@ -325,6 +328,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "GEOPOLITICAL_RISK_OFF",
|
||||
"category": "geopolitical",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 7, "absorption_days": 21, "decay_type": "linear"},
|
||||
"instruments": ["EURUSD", "XAUUSD", "SP500", "BRENT", "USDJPY", "VXX", "TLT", "HYG", "UNG", "SLV"],
|
||||
"description": "Geopolitical shock -> risk premium + safe haven demand -> multi-asset risk-off repricing",
|
||||
"ai_rationale": "Gold/TLT/JPY safe havens rise; EUR/SP500/HYG fall. VXX spikes. USDJPY falls (JPY strengthens as safe haven). BRENT and UNG spike if energy-producing region. EU equities most exposed to European conflicts.",
|
||||
@@ -408,6 +412,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "COMMODITY_SUPPLY_SHOCK",
|
||||
"category": "commodity",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 1, "half_life_days": 5, "absorption_days": 14, "decay_type": "exp"},
|
||||
"instruments": ["BRENT", "XAUUSD", "EURUSD", "SP500", "UNG", "XLE", "SLV"],
|
||||
"description": "Supply disruption/glut -> Brent + energy inflation -> EU trade deficit -> multi-asset",
|
||||
"ai_rationale": "OPEC cuts hit BRENT and XLE (energy sector stocks) first. Energy inflation pressures EU trade balance (EURUSD down) and inflates Gold/SLV. UNG follows as cross-commodity supply chain linkage. S&P suffers from margin pressure.",
|
||||
@@ -472,6 +477,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "TRADE_POLICY_SHOCK",
|
||||
"category": "trade_policy",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 1, "half_life_days": 10, "absorption_days": 21, "decay_type": "linear"},
|
||||
"instruments": ["EURUSD", "SP500", "XAUUSD", "EEM", "QQQ", "GBPUSD", "IWM"],
|
||||
"description": "Tariff announcement -> stagflationary shock -> EUR/GBP down SP500/QQQ down EEM down Gold up",
|
||||
"ai_rationale": "Tariffs create stagflation: import cost rise (inflation) + trade volume drop (growth). EEM is hit hardest via global trade contraction and USD strength. QQQ suffers from tech supply chain disruption (AAPL/NVDA exposed). GBPUSD exposed as UK trade-dependent. IWM domestic plays can benefit initially but input cost inflation hurts margins.",
|
||||
@@ -551,6 +557,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "CREDIT_SYSTEMIC_EVENT",
|
||||
"category": "credit_stress",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 7, "absorption_days": 21, "decay_type": "exp"},
|
||||
"instruments": ["EURUSD", "SP500", "XAUUSD", "HYG", "TLT", "VXX", "XLF", "USDJPY", "BTC"],
|
||||
"description": "Credit event -> spread widening + deleveraging -> systemic risk-off + USD liquidity flight",
|
||||
"ai_rationale": "HYG is the primary instrument (spreads widen = HYG down). TLT initially up (flight to quality) then volatile (sold for cash). VXX spikes hard. XLF (financials) crushed. USDJPY falls (JPY safe haven). BTC complex: initially up as alternative store of value, then down on margin calls.",
|
||||
@@ -638,6 +645,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "TECHNICAL_MOMENTUM_BREAKOUT",
|
||||
"category": "technical",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 3, "absorption_days": 7, "decay_type": "exp"},
|
||||
"instruments": ["EURUSD", "SP500", "QQQ"],
|
||||
"description": "Technical breakout/breakdown -> stop cascade + momentum -> instrument price action",
|
||||
"ai_rationale": "Technical events operate via microstructure: breakout triggers stops, amplifying the move. No fundamental anchor. The correlated asset move is weaker. Applies to any instrument — the primary and correlated move fields should be overridden per event.",
|
||||
@@ -687,6 +695,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "SENTIMENT_POSITIONING_EXTREME",
|
||||
"category": "sentiment",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 1, "half_life_days": 5, "absorption_days": 10, "decay_type": "linear"},
|
||||
"instruments": ["SP500", "QQQ", "EURUSD", "XAUUSD", "VXX", "HYG", "BTC"],
|
||||
"description": "Extreme fear / greed -> crowded trade unwind -> contrarian mean reversion",
|
||||
"ai_rationale": "+sigma = extreme fear/oversold (contrarian buy signal). VXX collapses as fear recedes. HYG recovers as credit spreads compress. BTC follows the risk appetite extreme. Mean reversion typically takes 3-10 days to materialize once the flow exhausts.",
|
||||
@@ -755,6 +764,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "COMMODITY_INVENTORY_REPORT",
|
||||
"category": "commodity",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 2, "absorption_days": 5, "decay_type": "exp"},
|
||||
"instruments": ["BRENT", "EURUSD", "XAUUSD", "UNG", "XLE"],
|
||||
"description": "Weekly inventory surprise -> supply/demand balance -> Brent + XLE + UNG",
|
||||
"ai_rationale": "EIA crude draw vs consensus -> Brent spot up + backwardation. XLE (energy sector ETF) follows Brent with some lag. EIA gas storage report separately drives UNG. Secondary inflation channel hits EURUSD and gold.",
|
||||
@@ -813,6 +823,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "INSTITUTIONAL_FLOW",
|
||||
"category": "positioning",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 1, "half_life_days": 7, "absorption_days": 14, "decay_type": "linear"},
|
||||
"instruments": ["EURUSD", "SP500", "XAUUSD"],
|
||||
"description": "Large institutional flow -> order flow imbalance -> momentum + mean reversion risk",
|
||||
"ai_rationale": "COT repositioning or FX intervention moves prices via order flow mechanics (not fundamentals). Move is self-limiting — creates a mean reversion setup once the flow exhausts. Low confidence, short-lived signal.",
|
||||
@@ -859,6 +870,7 @@ BUILT_IN_TEMPLATES = [
|
||||
"slug": "UNCLASSIFIED_IMPACT",
|
||||
"category": "unclassified",
|
||||
"heuristic_ver": 2,
|
||||
"calibration_json": {"lag_days": 0, "half_life_days": 5, "absorption_days": 12, "decay_type": "exp"},
|
||||
"instruments": ["EURUSD", "SP500", "XAUUSD"],
|
||||
"description": "Fallback — event doesn't fit established regimes. Low confidence, no causal chain.",
|
||||
"ai_rationale": "Direct trigger to output with no intermediate nodes. Precision scores from this template are marked low-confidence and excluded from calibration stats.",
|
||||
@@ -964,16 +976,41 @@ def seed_templates(conn):
|
||||
conn.execute("""
|
||||
INSERT INTO causal_graph_templates
|
||||
(name, category, sub_type, instruments, description, graph_json,
|
||||
ai_rationale, heuristic_ver, created_by)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'system')
|
||||
calibration_json, ai_rationale, heuristic_ver, created_by)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'system')
|
||||
""", (
|
||||
t["name"], t["category"], t.get("sub_type", ""),
|
||||
json.dumps(t.get("instruments", [])),
|
||||
t.get("description", ""),
|
||||
json.dumps(t["graph_json"]),
|
||||
json.dumps(t.get("calibration_json", {})),
|
||||
t.get("ai_rationale", ""),
|
||||
ver,
|
||||
))
|
||||
|
||||
# Migration: fill missing temporal params in calibration_json for all built-in templates.
|
||||
# Only sets keys that are absent — never overwrites existing calibration stats.
|
||||
for t in BUILT_IN_TEMPLATES:
|
||||
defaults = t.get("calibration_json", {})
|
||||
if not defaults:
|
||||
continue
|
||||
row = conn.execute(
|
||||
"SELECT id, calibration_json FROM causal_graph_templates WHERE name=?", (t["name"],)
|
||||
).fetchone()
|
||||
if not row:
|
||||
continue
|
||||
calib = json.loads(row["calibration_json"] or "{}")
|
||||
dirty = False
|
||||
for key in ("lag_days", "half_life_days", "absorption_days", "decay_type"):
|
||||
if calib.get(key) is None and key in defaults:
|
||||
calib[key] = defaults[key]
|
||||
dirty = True
|
||||
if dirty:
|
||||
conn.execute(
|
||||
"UPDATE causal_graph_templates SET calibration_json=?, updated_at=datetime('now') WHERE id=?",
|
||||
(json.dumps(calib), row["id"])
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user