feat: Phase 4+5 — price discovery status + replay historique
Phase 4 — Price Discovery Status (la pièce maîtresse) :
- price_discovery.py (nouveau) : capture_price_snapshots() sauve les prix des tickers
liés à chaque news scorée (energy→BZ=F/NG=F, metals→GC=F/HG=F, indices→^GSPC/IWM)
- compute_absorptions() mesure combien du mouvement attendu s'est déjà produit
(status: not_yet_priced <30% / partially_priced 30-80% / fully_priced >80%)
- build_price_discovery_block() → bloc prompt avec opportunités classées
- database.py : table news_price_snapshots + save/get/purge fonctions
- auto_cycle.py : capture après ai_score_news_batch, compute avant suggestions,
block injecté dans suggestion + scoring prompts + context snapshot
- ai_analyzer.py : param price_discovery_block dans suggest + score
Phase 5 — Replay historique :
- cycle.py : POST /api/cycle/contexts/{run_id}/replay — recharge le snapshot historique
et relance suggest_patterns_from_market_context avec le contexte original
- useApi.ts : hook useReplayCycle
- SystemLogs.tsx : bouton "Rejouer ce cycle" dans onglet Contexte IA avec champ
notes, résultats inline (liste des patterns générés), section price_discovery
ouverte par défaut en rouge
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -385,6 +385,19 @@ def init_db():
|
||||
context_json TEXT NOT NULL
|
||||
)""")
|
||||
|
||||
c.execute("""CREATE TABLE IF NOT EXISTS news_price_snapshots (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
article_hash TEXT NOT NULL,
|
||||
article_title TEXT,
|
||||
ticker TEXT NOT NULL,
|
||||
expected_direction TEXT,
|
||||
expected_impact_score REAL,
|
||||
price_at_capture REAL,
|
||||
captured_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
capture_cycle_id TEXT,
|
||||
UNIQUE(article_hash, ticker)
|
||||
)""")
|
||||
|
||||
c.execute("""CREATE TABLE IF NOT EXISTS skipped_trades (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT,
|
||||
@@ -2130,6 +2143,57 @@ def list_cycle_context_snapshots(limit: int = 30) -> list:
|
||||
return [{"run_id": r["run_id"], "ts": r["ts"]} for r in rows]
|
||||
|
||||
|
||||
# ── News Price Snapshots (Phase 4 — Price Discovery) ─────────────────────────
|
||||
|
||||
def save_news_price_snapshot(
|
||||
article_hash: str,
|
||||
article_title: str,
|
||||
ticker: str,
|
||||
expected_direction: str,
|
||||
expected_impact_score: float,
|
||||
price_at_capture: float,
|
||||
cycle_id: str,
|
||||
) -> None:
|
||||
conn = get_conn()
|
||||
conn.execute(
|
||||
"""INSERT OR IGNORE INTO news_price_snapshots
|
||||
(article_hash, article_title, ticker, expected_direction,
|
||||
expected_impact_score, price_at_capture, capture_cycle_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)""",
|
||||
(article_hash, article_title, ticker, expected_direction,
|
||||
expected_impact_score, price_at_capture, cycle_id),
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_news_price_snapshots(max_age_days: int = 7, min_age_minutes: float = 30.0) -> list:
|
||||
conn = get_conn()
|
||||
rows = conn.execute(
|
||||
"""SELECT article_hash, article_title, ticker, expected_direction,
|
||||
expected_impact_score, price_at_capture, captured_at, capture_cycle_id
|
||||
FROM news_price_snapshots
|
||||
WHERE captured_at >= datetime('now', ? || ' days')
|
||||
AND captured_at <= datetime('now', ? || ' minutes')
|
||||
ORDER BY captured_at DESC""",
|
||||
(f"-{max_age_days}", f"-{int(min_age_minutes)}"),
|
||||
).fetchall()
|
||||
conn.close()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def purge_old_price_snapshots(older_than_days: int = 14) -> int:
|
||||
conn = get_conn()
|
||||
conn.execute(
|
||||
"DELETE FROM news_price_snapshots WHERE captured_at < datetime('now', ? || ' days')",
|
||||
(f"-{older_than_days}",),
|
||||
)
|
||||
deleted = conn.total_changes
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return deleted
|
||||
|
||||
|
||||
# ── Knowledge Base Decay ──────────────────────────────────────────────────────
|
||||
|
||||
def decay_kb_confidence() -> int:
|
||||
|
||||
Reference in New Issue
Block a user