Breakout-Karte vorbereitet (inaktiv bis Neustart) + Bewertung der Margin-Idee

User-Idee: 40 % Margin manuell, 50 % fuer Breakout reservieren, neue Karte.

Bewertung: (1) 40 % ist der groesste gemessene Hebel (MaxDD 82,8 %) und ein
Schalter ohne Neustart. (2) Reserve ist technisch moeglich (Konto ist
RETAIL_HEDGING), aber _check_auto_squeeze feuert 'nur FLAT' und engine.py hat 17
Einzel-Positions-Annahmen -- Kern-Umbau, kein Parameter. Zudem steht die
Zuteilung gegen die Messung: autonom -4,71 EUR/Lot gegen Mensch +1,56 EUR/Lot.
Live-Befund macht (1) dringlich: freie Margin -6,21 EUR, Margin-Level 99,3 %.
Es gibt derzeit nichts zu reservieren.

Gebaut (inaktiv): history.fetch_squeeze_since, engine._squeeze_b5_cached
(120 s gecacht), Snapshot-Feld squeeze_b5, Karte #card-brk. Eigenes Fenster ab
01.08. -- squeeze_monitor.live rechnet ueber alle 42 Trades, B5 zaehlt 11. Die
Karte zeigt beide Zahlen, weil der Monitor 'ontrack' aus der MECHANIK meldet,
waehrend live Verhaeltnis 0,14 / PF 0,39 steht.

Live aendert sich nichts: Karte ist hidden, renderBrk blendet sie aus solange
squeeze_b5 fehlt. Aktiv nach dem naechsten Neustart (wartet auf den Trade).

BEINAHE-SCHADEN: ein UnicodeEncodeError liess web/app.js mit 0 Bytes zurueck.
node --check bestand trotzdem -- eine leere Datei ist gueltiges JS. Gefangen hat
es erst der Groessenvergleich. Neue Regel: erst .tmp schreiben, Groesse pruefen,
dann os.replace.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Axel Hocks
2026-08-19 13:32:48 +02:00
co-authored by Claude Opus 5
parent 3affe51030
commit 30cb77b795
8 changed files with 8490 additions and 2 deletions
+53
View File
@@ -153,6 +153,58 @@ function beepRecommendation(sig, isNew) {
// muss jedes Gate EINZELN passieren. Ein Gate, das fällt, lässt sich nicht
// durch ein anderes ausgleichen.
// ══════════════════════════════════════════════════════════════════════════
// Breakout-Autotrader-Karte (2026-08-19). Nur ANZEIGE aus vorhandenen
// Snapshot-Feldern -- hier wird nichts neu gerechnet.
// Die Karte bleibt VERSTECKT, solange `squeeze_b5` fehlt (aelterer Server, das
// Feld gibt es erst nach einem Neustart). Eine halb gefuellte Karte waere
// schlimmer als keine: sie saehe aus wie ein Zustand statt wie eine fehlende
// Quelle.
function renderBrk(d) {
const box = $streng("card-brk");
if (!box) return;
const b5 = d.squeeze_b5;
if (!b5) { box.classList.add("hidden"); return; }
box.classList.remove("hidden");
const an = !!d.auto_squeeze;
const nh = (d.squeeze_night_hours || []).map((h) => h + ":00").join(", ");
$("brk-state").textContent = (an ? "AN" : "AUS")
+ (d.squeeze_pending ? " · ruhende Stop-Order" : " · Market-Fallback")
+ (nh ? " · Nachtsperre " + nh : "");
$("brk-state").className = an ? "ok" : "warn";
const sq = (d.wave || {}).squeeze || {};
const st = sq.state;
$("brk-squeeze").textContent =
st === "active" ? "AUSBRUCH " + (sq.dir || "") + " @ " + (sq.level ?? "?")
: st === "armed" ? "komprimiert — Ausbruch steht bevor"
: "keine Kompression (Box " + (sq.box_atr ?? "?") + "×ATR)";
const pl = d.pending_levels || [];
$("brk-pending").textContent = pl.length
? pl.length + " liegend (" + (d.pending_quelle || "?") + ")"
: "keine — " + (an ? "Squeeze nicht armiert oder Position offen" : "Trader aus");
// B5: der Stand der einzigen Regel, die die Autonomie beenden kann.
const r = b5.ratio, pf = b5.pf;
const erf = r != null && pf != null && r >= b5.latte && pf >= 1;
$("brk-b5").textContent = b5.n + "/" + b5.ziel + " Trades · Verhältnis "
+ (r == null ? "—" : r.toFixed(2)) + " · PF "
+ (pf == null ? "—" : pf.toFixed(2))
+ " · " + b5.sum_eur.toFixed(2) + " €";
$("brk-b5").className = erf ? "ok" : "bad";
const el = $("brk-note");
if (el) {
el.textContent = erf
? "Latte (Verhältnis ≥ 1,0 UND PF ≥ 1) erfüllt."
: "⚠ Latte verfehlt (Ziel: Verhältnis ≥ 1,0 UND PF ≥ 1). Der Monitor "
+ "im Statistik-Tab meldet daneben „ontrack“ — das kommt aus der MECHANIK "
+ "(Regel neu gerechnet), nicht aus diesen echten Trades. Die Lücke "
+ "zwischen beiden ist der Befund, kein Widerspruch.";
}
}
function renderM15(s) {
const st = $("m15-status");
if (!s) { st.className = "m15-status"; st.textContent = "— keine Daten"; return; }
@@ -936,6 +988,7 @@ function render(d) {
// ── Gesamtempfehlung (aggregiert) ───────
renderM15(d.m15_setup);
renderBrk(d);
renderKontext(d);
renderCircuitBreaker(d.circuit_breaker);
renderPatterns(d.patterns);