news corpus for a local scorer + agent panel v2 + dashboard read-only (2026-09-17); books byte-identical
Agent panel v2: personas return p_win anchored to the book base rates with a code-computed decision context; verdict = equal-weight mean (verdict_source "mean"); only the macro persona runs live (agent_panel.personas ["macro"]); prompt version and exact payloads logged; offline replay harness scripts/panel_replay.py; base-rate table agent_panel_base_rates.json (scripts/build_panel_base_rates.py). Backtester `strategy` column now carries the generator's own stamp (label-only; five reference books re-pinned, all 62 other columns identical). News corpus (after evaluating the owner's ML-NEWS scikit model against DeepSeek: golden set 39/78 vs 78/78, out-of-sample agreement 64% against a 90% self-agreement ceiling; verdict: fallback only, not a replacement): - NewsSentiment.xau_score + archive column xau_score keep DeepSeek's gold score for every headline (930 of the first 1,546 DeepSeek rows had none); an existing newsdata.db gains the column in place on first open - headlines naming no tracked currency are scored and archived (currencies_json []) but never returned to the platform - _apply_llm_sentiment sends every new headline in its cycle, 25 per call; a failed call ends the cycle's sending Dashboard publisher never writes a database: main() calls app_config.set_db_writes_for_process(False), honoured by signal_log_enabled() and news_archive_enabled() (owner decision: the bot is the single writer). Test suite: the hermetic app config now points both writers at a suite-private temp dir — the RSS fixture tests were writing fixture headlines into the real logs/newsdata.db — with a Module 32 test pinning it. 529 tests.
This commit is contained in:
+15
-12
@@ -1634,16 +1634,16 @@ def _replay_span(span: Tuple[int, int]):
|
||||
if report.signal_quality not in bt_cfg.quality_filter:
|
||||
continue
|
||||
|
||||
# Strategy tag (from reasons[0] which the aggregator pre-pends).
|
||||
tag = "GENERIC"
|
||||
first_bull = report.bullish_reasons[0] if report.bullish_reasons else ""
|
||||
first_bear = report.bearish_reasons[0] if report.bearish_reasons else ""
|
||||
if "XAU PULLBACK" in first_bull or "XAU PULLBACK" in first_bear:
|
||||
tag = "XAU_PB"
|
||||
elif "XAU CHART PATTERN" in first_bull or "XAU CHART PATTERN" in first_bear:
|
||||
tag = "XAU_CP"
|
||||
elif "XAU STRATEGY" in first_bull:
|
||||
tag = "XAU"
|
||||
# Strategy tag: the generator's own stamp (XAU_ATR / XAU_PB /
|
||||
# XAU_CP / GENERIC), the same string the live log stores in
|
||||
# setup_json.strategy. Until 2026-09-17 this was inferred from the
|
||||
# text of the FIRST reason ("XAU STRATEGY" -> "XAU"), which
|
||||
# labelled every gold ATR setup whose first reason was another
|
||||
# indicator — and every SELL — as GENERIC (live review §6.3).
|
||||
# Label-only: entries, exits and R never depended on it, so the
|
||||
# books are trade-identical; the CSV `strategy` column changed
|
||||
# and the reference MD5s were re-pinned with that proof.
|
||||
tag = str(getattr(report.trade_setup, "strategy", "") or "GENERIC")
|
||||
|
||||
if bt_cfg.strategies_only and tag not in bt_cfg.strategies_only:
|
||||
continue
|
||||
@@ -2378,7 +2378,9 @@ def _parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
|
||||
"entries/stops/gates unchanged.")
|
||||
p.add_argument("--quality", default="A+,A,B,C", help="Comma-separated allowed grades")
|
||||
p.add_argument("--strategies", default="",
|
||||
help="Comma-separated strategy tags to include (XAU,XAU_PB,XAU_CP,GENERIC). Empty = all.")
|
||||
help="Comma-separated strategy tags to include "
|
||||
"(XAU_ATR,XAU_PB,XAU_CP,GENERIC; the legacy name XAU "
|
||||
"means XAU_ATR). Empty = all.")
|
||||
p.add_argument("--cp", action="store_true",
|
||||
help="Force-enable the chart-pattern entry (XAU_CP) regardless "
|
||||
"of the factory default — for validating the candidate.")
|
||||
@@ -2566,7 +2568,8 @@ def main(argv: Optional[List[str]] = None) -> int:
|
||||
max_hold_bars=args.max_hold_bars,
|
||||
use_cache=not args.no_cache,
|
||||
quality_filter=[q.strip() for q in args.quality.split(",") if q.strip()],
|
||||
strategies_only=[s.strip() for s in args.strategies.split(",") if s.strip()],
|
||||
strategies_only=[("XAU_ATR" if s.strip() == "XAU" else s.strip())
|
||||
for s in args.strategies.split(",") if s.strip()],
|
||||
spread=spread,
|
||||
workers=args.workers,
|
||||
fixed_rr_tp=args.fixed_rr_tp or 0.0,
|
||||
|
||||
Reference in New Issue
Block a user