Circuit Breaker: Tagesverlust-Stopp (daily_loss_limit_pct=8) — Überlebens-Basis

User-Ziel autonomes Handeln → Notbremse im Code (vorher abgelehnt, reaktiviert).
Erreicht der Tages-P&L (realisiert+offen) -8% der Balance, schließt der Bot die
Position und sperrt neue Auto-Trades bis zum naechsten Tag. _check_circuit_breaker
im _pos_loop (Startup-Grace, ~30s realized-cache, Berlin-Datum-Reset), blockt
Auto-Squeeze, Snapshot + roter Frontend-Banner (v=115). 80%-Margin bleibt (User).
Mit 5 Szenarien getestet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-07-27 17:39:55 +02:00
co-authored by Claude Opus 4.8
parent 873b67a521
commit cd8ee5b01b
6 changed files with 148 additions and 5 deletions
+20
View File
@@ -205,6 +205,25 @@ function renderStructure(s) {
}
}
// Circuit Breaker — roter Banner wenn ausgelöst, bernstein wenn nah (>60% des Limits).
function renderCircuitBreaker(cb) {
const el = $("circuit-banner");
if (!el) return;
if (!cb || !cb.enabled) { el.className = "circuit hidden"; el.textContent = ""; return; }
const limit = cb.limit_eur, day = cb.day_total;
if (cb.tripped) {
el.className = "circuit tripped";
el.textContent = `🛑 CIRCUIT BREAKER AKTIV — Tagesverlust ${fmt(day, 2)} € erreicht ` +
`(Limit ${fmt(limit, 0)} €). Keine Auto-Trades mehr heute.`;
} else if (limit && day < 0 && Math.abs(day) >= 0.6 * limit) {
el.className = "circuit near";
el.textContent = `⚠ Tagesverlust ${fmt(day, 2)} € — Stopp bei ${fmt(limit, 0)}` +
`(${Math.round(100 * Math.abs(day) / limit)} % erreicht)`;
} else {
el.className = "circuit hidden"; el.textContent = "";
}
}
function render(d) {
// ── Header ──────────────────────────────
$("conn").className = "dot " + (d.connected ? "on" : "off");
@@ -294,6 +313,7 @@ function render(d) {
// ── Gesamtempfehlung (aggregiert) ───────
renderVerdict(d.verdict || {}, d);
renderCircuitBreaker(d.circuit_breaker);
renderStructure(d.structure);
renderStatsCompact(d.stats_compact, d.market);
renderGaps(d.gaps, d.market);