Quant review 2026-09-26: alert cooldown, plain-language alerts, M15 grade-A SELL block, 1R printed targets, panel/breach fixes
Live signals.db review (2026-09-04 → 09-25, 100 unique setups replayed on the scans' stored candles): the stop-hunt claim is refuted (71% of stop-outs ran ≥ 1R past the stop, the same as the books' 70–72%); −25.1R of the −37.8R raw live book were consecutive-bar re-entries the backtester's 5-bar cooldown never takes; the cooldown view sits at the 3rd–5th percentile of the books' three-week windows. Delivery (book-neutral): - telegram_bot: 5-bar alert cooldown per timeframe (_ALERT_COOLDOWN_BARS = backtest.cooldown_bars); setup block prints the trail first as the tested exit, TP1/TP2 as guides with their R, "Planned TP1 RR", and one validated-book line per setup class (agent_panel_base_rates.json); the informational 100-pip TP line is removed (owner request). - AI block rewritten for a new trader: "AI check: the odds look better than / worse than / about usual", the chance "in 100" against the usual odds, one reason for and one against, no verdict word or confidence figure; rendered whenever the verdict carries a probability. agent_panel: persona prompts ban trading jargon (PANEL_PROMPT_VERSION v2.1-2026-09-26); the macro-source verdict now carries its persona's p_win (every live v2 row had panel_probability NULL). Dashboard and guides mirror the wording. - telegram_bot: level-breach rescans skip the settlement-pause window (the 20:45 M15 bar was re-logged at 22:01/22:06/22:11 every evening). Signal (pre-registered rule-1 campaign, CUDA twin paired with gpu_backtest.py): - M15 grade-A SELLs blocked (sell_min_quality ["A+","B"], M15 override 6): W2 813/+154.15R PF 1.53 vs 931/+146.14R PF 1.43, OOS +68.5 vs +60.67, W3 max DD 20.9 vs 19.3R. PASSED a–f. - Printed target 1 floored at 1R in every generator (signals.tp_print_floor_rr), applied AFTER the min-RR and spread gates so no trade changes; mirrored in cuda_signal_kernels.py K2. Label-only re-pin of all four timeframes (only tp1/rr_planned columns move). A floor applied before the gate cost −24.6R and was rejected. - FAILED: M15 min_rr_ratio 1.0 (trade-identical, −2.0R). Owner's call: M5 tp_floor_rr 1.0 (+48.9R W2, max DD 10.1 → 15.9R), not shipped. New pins: M5 W2 e599c8a8…, M15 W2 5b65ecf6…, M15 OOS 09b8a8e7…, H1 W3 a44fd19b…, H4 W3 f3587bae…; twin and reference MD5s equal on every window. Base-rate table rebuilt from the new pins. Suite 558 passed. Evidence: backtest/research/rr_and_sell_campaign_2026-09-26.md (plus the 2026-09-18 loss-anatomy and wrong-direction reports it builds on).
This commit is contained in:
+12
-9
@@ -595,22 +595,24 @@ function planHTML(ts) {
|
||||
No trade plan. The signal did not clear the gate that releases an entry, stop and target.</div>`;
|
||||
}
|
||||
const buy = ts.direction === "BUY";
|
||||
// The trail is the tested exit (the backtester never exits at target 1);
|
||||
// the risk-reward shown is the PLANNED target-1 ratio, a guide only.
|
||||
const trail = (ts.trail_arm_r != null && ts.trail_dist_r != null)
|
||||
? `Stop starts trailing at ${ts.trail_arm_r}R of profit and follows ${ts.trail_dist_r}R behind.`
|
||||
: "Trailing uses the platform default.";
|
||||
? `Exit rule (tested): once the trade is ${ts.trail_arm_r}R in profit, the stop trails ${ts.trail_dist_r}R behind the best price, moved at candle close. Until then the stop is the exit; targets are guides.`
|
||||
: "Exit rule: the trailing stop uses the platform default; targets are guides.";
|
||||
return `<div class="plan ${buy ? "sig-buy" : "sig-sell"}">
|
||||
<div class="plan-head">
|
||||
<i class="fa-solid ${buy ? "fa-arrow-trend-up" : "fa-arrow-trend-down"}" aria-hidden="true"></i>
|
||||
${buy ? "Buy plan" : "Sell plan"}
|
||||
<span class="plan-strategy">${esc(ts.strategy || "")}</span>
|
||||
<span class="plan-rr">${(+ts.risk_reward).toFixed(1)} to 1</span>
|
||||
<span class="plan-rr" title="Planned target-1 distance divided by the stop distance. A guide only: the tested exit is the trailing stop.">planned ${(+ts.risk_reward).toFixed(1)} to 1</span>
|
||||
</div>
|
||||
<dl class="plan-grid">
|
||||
<div><dt><i class="fa-solid fa-right-to-bracket" aria-hidden="true"></i>Entry</dt>
|
||||
<dd>${fmt$(ts.entry)}</dd></div>
|
||||
<div><dt><i class="fa-solid fa-shield-halved" aria-hidden="true"></i>Stop</dt>
|
||||
<dd class="down">${fmt$(ts.stop_loss)}</dd></div>
|
||||
<div><dt><i class="fa-solid fa-bullseye" aria-hidden="true"></i>Target 1</dt>
|
||||
<div><dt><i class="fa-solid fa-bullseye" aria-hidden="true"></i>Target 1 (guide)</dt>
|
||||
<dd class="up">${fmt$(ts.take_profit_1)}</dd></div>
|
||||
<div><dt><i class="fa-solid fa-flag-checkered" aria-hidden="true"></i>Target 2</dt>
|
||||
<dd class="up">${fmt$(ts.take_profit_2)}</dd></div>
|
||||
@@ -873,21 +875,22 @@ function detailHTML(tf) {
|
||||
${esc(r.news_summary || "")}</div>`);
|
||||
}
|
||||
|
||||
if (r.panel_verdict && r.panel_verdict_source === "mean") {
|
||||
if (r.panel_verdict && (r.panel_probability || 0) > 0) {
|
||||
// v2 panel: a probability anchored to the base rate of this kind of
|
||||
// setup. Advisory only — no gate reads it, so it gets no verdict colour.
|
||||
// Same plain wording as the Telegram alert (2026-09-26).
|
||||
const base = (r.panel_context && r.panel_context.base_rate) || {};
|
||||
const usual = base.win_rate != null
|
||||
? ` Setups like this one have paid off about ${Math.round(base.win_rate)}% of the time.` : "";
|
||||
? ` Usual for this kind of setup: about ${Math.round(base.win_rate)} in 100.` : "";
|
||||
const takes = (r.panel_takes || []).map(t =>
|
||||
`<tr><td class="ind-k">${esc(t.persona)}</td>
|
||||
<td class="num text-end">${t.p_win != null ? Math.round(t.p_win) + "%" : "—"}</td>
|
||||
<td class="flat">${esc(t.reason_for || "")}</td>
|
||||
<td class="flat">${esc(t.reason_against || "")}</td></tr>`).join("");
|
||||
out += sec("AI estimate", `<div class="flat mb-2">
|
||||
About a <strong>${Math.round(r.panel_probability || 0)}%</strong> chance this trade pays off.${esc(usual)}
|
||||
It is advisory and still being tested — nothing in the signal reads it.<br>
|
||||
${esc(r.panel_rationale || "")}</div>
|
||||
Chance it pays off: about <strong>${Math.round(r.panel_probability || 0)} in 100</strong>.${esc(usual)}
|
||||
${esc(r.panel_rationale || "")}<br>
|
||||
This check is an experiment. Do not trade on it alone.</div>
|
||||
${takes ? `<div class="detail-scroll"><table class="table table-sm d-table">
|
||||
<thead><tr><th>Persona</th><th class="text-end">Chance</th><th>For</th><th>Against</th></tr></thead>
|
||||
<tbody>${takes}</tbody></table></div>` : ""}`);
|
||||
|
||||
Reference in New Issue
Block a user