Warum BRK heute nicht ausgeloest hat: drei Ursachen, zwei behoben
User: "warum wurde beim letzten anstieg kein Break Out trade ausgeloest?"
Der Squeeze HAT gefeuert - mit der echten `_squeeze_one` nachgerechnet: 8 Bars
`active` heute, davon 6 LONG (00:55 / 03:00 / 07:40 / 08:35 / 11:50 / 13:00).
`squeeze_entry_count` steht trotzdem auf 0. Im Log stehen 8
`AUTO-SQUEEZE-ENTRY`-Zeilen - die Order scheiterte JEDES MAL.
URSACHE 1 - "Position bereits offen!" (1x, 08:30:34). Der Market-Fallback lief
noch ueber Slot 1, der vom manuellen Trade belegt war. Genau die Zwei-Slot-
Luecke; der `_slot()`-Fix kam um 08:32 und hat sie geschlossen.
URSACHE 2 - "Lot-Fehler" (140x, ab 13:02 JEDER Versuch). Das ist der Hauptgrund
und er ist eine Einstellung, kein Defekt: `margin_brk = 10 %`, und `calc_lots`
nimmt einen Prozentsatz der FREIEN Margin, nicht des Kontos. Die manuelle
Position bindet 707 von 776 EUR -> 10 % von ~100 EUR frei = ~10 EUR, ein
Mindestlot braucht 7,47 EUR, und die freie Margin schwankt mit dem P&L. Damit
lag BRK den ganzen Tag auf der Kippe. NICHT eigenmaechtig geaendert - das Feld
ist eine User-Entscheidung.
URSACHE 3 - "Kurs hat das Level bereits passiert" (129x). Die BUY_STOP-Seite
war nicht platzierbar, weil das Box-Dach dem Kurs ENTGEGENKAM (rollierendes
Fenster) - die wandernde Marke aus backtest_squeeze_frozen.py, hier live.
BEHOBEN (1): LOG-DROSSEL GRIFF NIE. Der Merker lag in EINER Variable, die
beiden Seiten scheitern aber im selben Tick mit VERSCHIEDENEN Fehlern
("Level passiert" oben, "Lot-Fehler" unten) - der Wert wechselte bei jedem
Aufruf. Real: 269 Zeilen an einem Tag, 2 je Sekunde. Jetzt je Order-Seite
gemerkt. Eine Drossel, die nie drosselt, ist schlimmer als keine: sie verdeckt
im Log genau die Meldung, die zaehlt.
BEHOBEN (2): "Lot-Fehler" erklaert sich jetzt selbst (`mt5_utils.lot_grund`).
Statt zwei Woertern steht dort
"Einsatz 2 % von 101.90 EUR freier Margin = 2.04 EUR, Mindestlot 0.01
braucht aber 7.47 EUR"
Beide Aufrufer (Market `_send` und Pending `place_stop`) nutzen ihn. Live
gegengeprueft an drei Einsatz-Werten.
Pipeline gruen (check_nfalle, Stufe E, 97 Tests), deployt und verifiziert:
seit dem Neustart 0 Zeilen "nicht platzierbar".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a35ea38d31
commit
b448a7ade8
@@ -117,6 +117,36 @@ def calc_lots(sym: str, price: float, otype: int,
|
||||
return min(lots, si.volume_max)
|
||||
|
||||
|
||||
def lot_grund(sym: str, price: float, otype: int,
|
||||
buffer_pct: float | None = None) -> str:
|
||||
"""Warum liefert `calc_lots` 0? — als lesbarer Satz statt „Lot-Fehler".
|
||||
|
||||
⚠⚠ ANLASS (2026-08-20, real): der Breakout-Trader hat den ganzen Tag keinen
|
||||
Trade eroeffnet und meldete nur „Lot-Fehler". Die Ursache war ein
|
||||
Zusammenspiel, das man der Meldung NICHT ansah: das Feld „Einsatz je Pfad"
|
||||
stand auf 10 %, und weil `calc_lots` einen Prozentsatz der FREIEN Margin
|
||||
nimmt — nicht des Kontos —, blieben von 108 EUR frei nur 10,83 EUR uebrig,
|
||||
waehrend ein Mindestlot 7,47 EUR braucht und die freie Margin schwankt.
|
||||
Eine Fehlermeldung, die den Grund verschweigt, kostet hier Stunden.
|
||||
"""
|
||||
si, acc = mt5.symbol_info(sym), mt5.account_info()
|
||||
if not si or not acc:
|
||||
return "Lot-Fehler (kein Symbol/Konto)"
|
||||
mpl = mt5.order_calc_margin(otype, sym, 1.0, price)
|
||||
if not mpl or mpl <= 0:
|
||||
return "Lot-Fehler (Margin je Lot nicht berechenbar)"
|
||||
_man = get_manual_margin()
|
||||
if _man > 0:
|
||||
return (f"Einsatz {_man:.2f} EUR reicht nicht fuer das Mindestlot "
|
||||
f"{si.volume_min} (braucht {si.volume_min * mpl:.2f} EUR)")
|
||||
buf = (max(0.01, min(0.99, buffer_pct / 100.0))
|
||||
if buffer_pct and buffer_pct > 0 else get_margin_buffer())
|
||||
verf = acc.margin_free * buf
|
||||
return (f"Einsatz {buf * 100:.0f} % von {acc.margin_free:.2f} EUR freier "
|
||||
f"Margin = {verf:.2f} EUR, Mindestlot {si.volume_min} braucht aber "
|
||||
f"{si.volume_min * mpl:.2f} EUR")
|
||||
|
||||
|
||||
def calc_lots_risk(sym: str, price: float, otype: int,
|
||||
sl_distance: float | None, risk_frac: float) -> float:
|
||||
"""Risiko-basierte Lot-Größe: Verlust beim Initial-SL ≈ risk_frac × Equity.
|
||||
|
||||
Reference in New Issue
Block a user