signal_log: persist market snapshots

This commit is contained in:
Harwinder Sekhon
2026-08-18 15:24:37 -04:00
parent 71eb703355
commit 410bf5ebc4
5 changed files with 219 additions and 28 deletions
+73 -7
View File
@@ -7530,6 +7530,25 @@ def _make_log_report():
reward_pips=8.8, pip_value=1.0, strategy="XAU_PB",
trail_arm_r=0.70, trail_dist_r=0.85,
)
report.primary_analysis = TechnicalAnalysis(
symbol="XAU/USD", timeframe=Timeframe.M5.value,
timestamp=report.timestamp,
indicators={
"rsi": IndicatorSignal(
"RSI", 62.5, SignalStrength.BUY, 70.0,
"Momentum is bullish", 1.2),
"atr": IndicatorSignal(
"ATR", 5.25, SignalStrength.NEUTRAL, 0.0,
"Volatility context", 0.0),
},
composite_signal=SignalStrength.BUY,
composite_score=42.5,
confidence=76.0,
market_regime="trending_up",
volatility_regime="normal",
key_levels={"support": 2440.0, "atr": 5.25},
pattern_signals=["bullish_engulfing"],
)
return report
@@ -7547,7 +7566,10 @@ def _make_log_context():
news_headlines=[NewsSentiment(
headline="Fed signals rate hike", source="test",
timestamp=now, currencies_mentioned=["USD", "XAU"],
sentiment_score=1.0, keywords=["rate hike"])],
sentiment_score=1.0, keywords=["rate hike"],
sentiment_by_currency={"USD": 1.0, "XAU": -1.0},
link="https://example.test/fed", description="Policy update",
publisher="Example News")],
calendar_available=True,
llm_summary="Gold supported by soft dollar.",
)
@@ -7563,7 +7585,12 @@ def _():
lg = slog.SignalLogger(path)
report = _make_log_report()
context = _make_log_context()
lg.log(report, context=context, source="test", timeframe="M5")
candles = {
Timeframe.M5: make_ohlcv(20, seed=91),
Timeframe.H1: make_ohlcv(10, seed=92),
}
lg.log(report, context=context, source="test", timeframe="M5",
dataframes=candles)
lg.close()
conn = sqlite3.connect(path)
rows = conn.execute("SELECT * FROM signals").fetchall()
@@ -7600,7 +7627,21 @@ def _():
headlines = json.loads(row["headlines_json"])
assert headlines[0]["headline"] == "Fed signals rate hike"
assert headlines[0]["score"] == 1.0
assert headlines[0]["score_by_currency"]["XAU"] == -1.0
assert headlines[0]["currencies"] == ["USD", "XAU"]
assert headlines[0]["description"] == "Policy update"
indicators = json.loads(row["indicators_json"])
primary = indicators[Timeframe.M5.value]
assert primary["composite_score"] == 42.5
assert primary["indicators"]["rsi"]["signal"] == "BUY"
assert primary["indicators"]["atr"]["value"] == 5.25
candle_snapshot = json.loads(row["candles_json"])
assert len(candle_snapshot[Timeframe.M5.value]) == 14
assert len(candle_snapshot[Timeframe.H1.value]) == 10
bar = candle_snapshot[Timeframe.M5.value][0]
assert set(bar) == {"timestamp", "open", "high", "low", "close",
"volume"}
assert bar["timestamp"].endswith("+00:00")
finally:
slog.reset_loggers_for_tests()
os.remove(path)
@@ -7969,23 +8010,48 @@ def _():
con.execute(
"CREATE TABLE signals (id INTEGER PRIMARY KEY, logged_at TEXT,"
" symbol TEXT, timeframe TEXT)")
con.execute(
"CREATE TABLE outlooks (id INTEGER PRIMARY KEY, logged_at TEXT,"
" surface TEXT, bias TEXT, setup_forming TEXT, confidence REAL,"
" watch TEXT, note TEXT)")
con.commit()
con.close()
logger = slog.SignalLogger(path)
columns = {
row[1] for row in logger._conn.execute("PRAGMA table_info(signals)")
}
assert {"indicators_json", "candles_json"} <= columns
outlook_columns = {
row[1] for row in logger._conn.execute("PRAGMA table_info(outlooks)")
}
assert {"news_json", "indicators_json", "candles_json"} <= \
outlook_columns
result = mo.OutlookResult(
bias="bearish", setup_forming="sell", confidence=71.5,
watch="Wait for price to fail at resistance.",
note="Momentum is fading after a sharp rise.", created_ts=time.time())
rowid = logger.log_outlook(result, surface="test")
payload = {
"news": {"headlines": ["Gold firms"]},
"indicators": {"1h": {"rsi": {"value": 55.0}}},
"market_regime": {"1h": "trending_up"},
"volatility_regime": {"1h": "normal"},
"key_levels": {"1h": {"support": 4400.0}},
"candles": {"1h": {"bars": [[-0.2, 0.1, -0.3, 0.0]]}},
}
rowid = logger.log_outlook(result, surface="test", payload=payload)
logger.close()
con = sqlite3.connect(path)
row = con.execute(
"SELECT surface, bias, setup_forming, confidence, watch, note "
"SELECT surface, bias, setup_forming, confidence, watch, note, "
"news_json, indicators_json, candles_json "
"FROM outlooks WHERE id=?", (rowid,)).fetchone()
con.close()
assert row == ("test", "bearish", "sell", 71.5,
"Wait for price to fail at resistance.",
"Momentum is fading after a sharp rise.")
assert row[:6] == ("test", "bearish", "sell", 71.5,
"Wait for price to fail at resistance.",
"Momentum is fading after a sharp rise.")
assert json.loads(row[6])["headlines"] == ["Gold firms"]
assert json.loads(row[7])["market_regime"]["1h"] == "trending_up"
assert len(json.loads(row[8])["1h"]["bars"]) == 1
finally:
slog.reset_loggers_for_tests()
os.remove(path)