ebf10da00e3862936fb57bfaf792ba5509d26cb5
339
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a1a5d560b9 |
Charts-Tab komplett entfernt (User-Vorgabe)
Entfernt: Tab-Button, #view-charts, der gesamte app.js-Chart-Block (Kartenaufbau, renderChart, loadCharts, 20-s-Refresh, Resize-Handler), die Chart-CSS-Regeln, die vendorte Bibliothek web/lightweight-charts.standalone.production.js (164 KB) samt script-Tag - und die Backend-Kette dahinter: /api/bars und engine.get_bars (60 Zeilen). Beide existierten ausschliesslich fuer dieses Tab; geprueft, dass es keinen anderen Aufrufer gibt. Nicht betroffen (sahen nur aehnlich aus): die Chartmuster-Karte (Verdict-Gewicht 0,25, im Tab "SIG Live"), der MQL5-Indikator samt sr_levels.csv-Export (eigener Pfad ueber _write_levels_file) und die Analyse-Module structure/patterns/cone - die speisen den Snapshot, nicht das Chart. Der MT5-Chart bleibt voll bedient. Ein veralteter Kommentar in trader.py, der auf engine.get_bars verwies, wurde auf core/gaps.py umgehaengt. Verifiziert am laufenden Server: /api/bars -> 404, Bibliothek -> 404, data-view="charts" und id="view-charts" nicht mehr im ausgelieferten HTML, 6 Tabs zu 6 Views paarig, keine verwaisten JS-Referenzen, Klammern-Balance ok, keine Fehler im Log. v=142. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6ff3c15b1d |
Statistik geprueft: Aggregate exakt, aber die Netto-Rechnung ist um Faktor 4,7
zu pessimistisch
Geprueft gegen unabhaengige SQL-Rechnung: /api/stats ueber today/week/all mit
~50 Werten (n_trades, wins/losses/breakeven, total_pnl, avg_win/loss,
gross_win/loss, winrate, profit_factor), dazu die inneren Konsistenzen
(wins+losses+be = n, gross_win-gross_loss = total_pnl, Summe closed_by = n,
Summe hour_stats = wins/losses) und 8 Setup-Zeilen. Ebenso stats_compact und
day_pl. Alles stimmt bitgenau.
Der Defekt liegt in server._add_net / _add_net_setup:
net_pnl = total_pnl - gross_win x 26,375 %. Das unterstellt, die Quellensteuer
sei endgueltig verloren - sie wird aber groesstenteils erstattet, was CLAUDE.md
selbst dokumentiert ("erstattet via taegl. Tax settlement"), die Rechnung aber
ignoriert.
Empirisch aus den echten Broker-Buchungen (history_deals_get, gleicher Zeitraum
wie die Statistik): einbehalten -2236,10, erstattet +1789,65, tatsaechlich
verblieben -446,45. Das Modell rechnet mit -2097,10.
Angezeigtes Netto -1104,67 gegen reales Netto +545,98 - Abweichung 1650,65 EUR,
und das Vorzeichen dreht. Real verbleiben nur 21 % der modellierten Last.
Richtige Loesung waere, die tatsaechlichen WHT-/Tax-Deals zu verwenden statt zu
schaetzen (ueber history_deals_get + Kommentar-Filter exakt abrufbar, gecacht und
unter mt5_lock). Nicht gebaut - Umfang war die Pruefung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7009541c42 |
Squeeze-Trades bekommen den SL aus M5-ATR (User-Entscheidung), TP unveraendert
trader._calc_sl_tp bekommt die ATR-Zeitebene als Parameter (Default SL_TF = M15); _send/_send_locked/open_long/open_short und place_stop reichen sie durch. Gesetzt wird sie an genau zwei Stellen: engine._open bei source="auto_squeeze" und _manage_squeeze_pending bei quelle="squeeze". Manuelle Trades und Auto-Signal bleiben bei M15. Grundlage backtest_sl_basis.py: auf Squeeze-Entries ist der Ertrag zwischen beiden Basen ein Wash (alle Varianten innerhalb eines Standardfehlers), der Worst-Case sinkt aber von -8,83 auf -2,44 xATR_M5 = Faktor 3. Auf der Wellen-Population ist der weite M15-SL in BEIDEN Haelften besser - deshalb bewusst keine globale Umstellung. Die Multiplikatoren (1,8-2,2 xATR) sind nicht angefasst, nur die Zeitebene. TP bewusst NICHT betroffen (User: "nur fuer SL, der TP soll mit dem Runner mitwachsen"). Geprueft statt angenommen: der von _calc_sl_tp zurueckgegebene TP wird von KEINEM Aufrufer gesendet, beide setzen nur req["sl"]. Das Ziel verwaltet trailing.py dynamisch (3,5 x ATR der Wellen-Zeitebene). Warnkommentar im Code, warum der TP dort nicht mit in die Order darf. 4 Szenarien getestet. Dabei eigene Fehlannahme korrigiert: ohne Pivot greift der 1,2-%-Fallback, der beim M15 vom MINDEST-Deckel aufgeweitet wird - die 2,2x-Obergrenze wird dort gar nicht erreicht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
a6c43183e2 |
SL-Basis M5 vs M15 auf Level-Entries gemessen: Tail-Frage, keine Ertragsfrage
Strukturfund vorweg: exit_model.simulate nimmt EINEN atr fuer SL, TP, Trail und Breakeven - und alle Backtests uebergeben ATR_M5. Live kommt der SL aus ATR_M15 (Median 1,80x groesser). Praktisch jede Projekt-Messung modelliert damit 2,0xATR_M5, waehrend live ~4,0xATR_M5 gilt. Einzige bisherige Ausnahme war backtest_sl_width.py. Gemessen auf der NEUEN Level-Entry-Population (80k, 2 Halbjahre, nur die SL-Basis variiert): SQUEEZE: Ertrag ist ein Wash - alle Varianten innerhalb eines Standardfehlers, und die einzige beidhaelftig bessere Zelle (2,5) hat schlechtere Nachbarn. WELLE: der weite Live-SL ist in BEIDEN Haelften der beste, jede Verengung kostet. Der einzige robuste Unterschied ist das Tail-Risiko: Worst-Case -8,83 xATR (live, Squeeze H2) gegen -2,94 bei 2,5xATR_M5 = Faktor 3. Bei 3,5 Lots sind das ~-890 EUR gegen ~-300 EUR im schlechtesten Einzeltrade. Antwort auf die Frage: vertretbar ja, aber als Risiko- und nicht als Ertragsentscheidung. Saubere Umsetzung waere quellen-abhaengig (M5-ATR nur bei auto_squeeze) - strukturell begruendet, nicht data-mined. Nicht gebaut. Reproduziert NICHT backtest_sl_tf_mismatch.py (23.07.): dort Einstieg am Bar-Close, hier am Level - der Einstiegspreis hat den Befund gedreht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d8a243612a |
Gegen-Squeeze als Exit zum 3. Mal gemessen: der Mechanismus feuert praktisch nie
Anlass: Trade T=49423144 (-343 EUR) und der Wunsch, der Breakout haette frueher schliessen sollen - nachgeschaerft zu "bei einem Squeeze den SL sofort eng setzen". Beide Varianten gemessen, kanonischer Exit + stop_when-Hook (keine Exit-Kopie), Echtkosten, 2 Halbjahre, zwei Populationen. Der eigentliche Befund steht nicht in den Kennzahlen, sondern in den Ausloesungen: sofort-schliessen feuert 1x von 809 bzw. 1274 Squeeze-Trades, der enge SL 0x. Bei Wellen-Entries 8x bzw. 2-3x. Grund ist konstruktionsbedingt: ein Gegen-Ausbruch verlangt eine NEUE Kompression (Box ueber 10 M5-Bars = 50 min), waehrend die mittlere Haltedauer bei 12-18 min liegt. Der Gegen-Ausbruch trifft also in ~0,1 % (Squeeze) bzw. ~1 % (Welle) der Trades ein - der Fall des Users war einer davon. Damit sind die Kennzahl-Unterschiede Rauschen aus einer Handvoll Faelle, und keine Variante besteht auf beiden Populationen. Die abgeschwaechte Form (enger SL statt Close) adressiert zwar genau den alten Einwand (Gegen-Ausbrueche sind oft Fehlausbrueche), kann ihn aber nicht ausspielen, wenn sie 0-mal ausloest - und waere von einer Bar-Simulation ohnehin ueberschaetzt. Dritte Ablehnung, diesmal mit einer Begruendung, die nicht vom Exit-Modell abhaengt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c8c3e32926 |
Trail x Breakeven gemeinsam geprueft: keine Aenderung - und ein Aufloesungs-
Artefakt, das einen alten Schluss entwertet
Anlass: Frage zur Trail-Kalibrierung "jetzt bei 3 Lot". Zur Praemisse: die
Positionsgroesse aendert das Optimum NICHT (R ist ATR-normiert). Gemessen wurde
die echte offene Frage - be=1,3 stammt aus der Zeit mit Trail 1,5, mult wurde am
31.07. auf 1,0 gesenkt ohne das Breakeven neu zu pruefen.
(1) Breakeven ist praktisch wirkungslos: bei mult <= 0,6 sind alle be-Zeilen
identisch (der enge Trail erreicht den Einstand frueher als der BE-Boden). Bei
mult 1,0 ist be=0,6 um +0,019 besser - unter einem Standardfehler. Keine
Aenderung.
(2) Der Trail ist monoton besser bis hinunter zu 0,05 xATR (~3 Cent) - das waere
vom Spread allein ausgeloest. Ein Optimum, das bis an die physikalische
Unmoeglichkeit monoton bleibt, misst die Methode, nicht den Markt.
Aufloesungs-Artefakt nachgewiesen (analyze_trail_resolution.py): mit in DOLLAR
fixiertem Trail auf M5 gegen M1, 597 gemeinsame Einstiege, kippt das Vorzeichen
der Differenz bei ~0,3 xATR - die groebere Aufloesung ueberschaetzt enge Trails
(-0,027 bei 0,10) und unterschaetzt weite (+0,036 bei 1,0, +0,066 bei 1,5).
Damit ist der Befund vom 31.07. ("enger ist monoton besser") teilweise entwertet.
Erster Testentwurf war falsch konstruiert: der Trail wurde mit dem ATR der
jeweiligen Zeitebene skaliert, damit bleibt das Verhaeltnis Trail/Bar-Spanne
konstant und die Aufloesung wird gar nicht variiert.
Nebenbefund gegen die eigene Slippage-Vermutung: die Trade-Zahl ist ueber alle
Multiplikatoren fast konstant (2108 bei 0,3 gegen 2083 bei 1,0), Worst-Case
ueberall -2,44. Das Slippage-Argument traegt kaum, das Aufloesungs-Argument
traegt.
Ergebnis: Trail 1,0 / Breakeven 1,3 bleiben.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
4bc4625391 |
Auto-Flip-Close abgeschaltet (User-Entscheidung)
[trading] auto_flip_close = false. Grundlage: backtest_flipclose2.py - jede
Variante in BEIDEN Halbjahren negativ, beim Live-Wert 0,5 xATR -92 R (H1) /
-160 R (H2). Mechanismus verstanden: Trefferquote steigt 39 -> 45 %, Ertrag
faellt = Gewinner-Kappen, weil die nachlaufende EMA oft mitten im Pullback
dreht.
Die Live-Bilanz sprach dagegen (+284,22 EUR aus 4 Ausloesungen, kontrafaktisch
sogar +101 EUR besser als der kanonische Exit) - aber n=4, und +101 EUR steckten
in EINEM Trade am 04.08., dem Ausreissertag, der allein die 30-Tage-Bilanz
traegt. 4 gegen ~4.000 Trades.
Der ALARM bleibt unveraendert: _check_close_alert haengt an _run_analysis, nicht
am _pos_loop-Aufruf von _check_flip_close. Nur die automatische Ausfuehrung
entfaellt - damit ist der dokumentierte Ursprungszustand wieder da ("Flip bleibt
Alarm + menschliche Entscheidung", User-Uebersteuerungen 68 % WR).
Kein runtime_state.json-Override vorhanden (anders als bei auto_signal, wo ein
UI-Toggle die ini still ueberschrieb), die ini-Aenderung greift direkt. Live
verifiziert nach Neustart: flip_close=False. Neu im Config-Waechter mit
validated=false, damit ein Zurueckschalten auffaellt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
01e77bfb98 |
Live-Gegenprobe zum Auto-Flip-Close + Empfehlung zum Abschalten
Der einzige Einwand gegen die Backtest-Ablehnung war die Live-Bilanz von +284,22 EUR aus 4 Ausloesungen. Kontrafaktisch nachgerechnet (kanonischer Exit ab demselben Einstieg, Methode wie analyze_manual_close.py): ohne den Flip waeren es +183,51 EUR gewesen - der Flip war auf diesen Trades also +100,71 EUR BESSER. Das ist trotzdem kein Beleg: n=4, und +101 EUR stecken in EINEM Trade (04.08. 16:15). Der 04.08. ist genau der Ausreisertag, der allein die 30-Tage-Bilanz traegt. Gegen ~2.000 Trades je Haelfte im Backtest (jede Variante, beide Haelften negativ, -92/-160 R) wiegt das nichts - dieselbe Falle wie der 12k-Vorlauf beim Kerzen-Fade. Empfehlung: abschalten. Der Alarm bleibt (Blinken/Ton/Telegram), nur die automatische Ausfuehrung entfaellt - damit ist der dokumentierte Ursprungszustand wieder da. Nichts umgeschaltet, das ist eine User-Entscheidung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
71aec2e240 |
Korrektur der eigenen Verdict-Auswertung: die Gewichtung ist NICHT invertiert
Der Anteil "ueber alle Zeilen" mischt Gewichtung und Haeufigkeit. Entscheidend
fuer "ist die Gewichtung kaputt?" ist der Anteil, WENN ein Modul spricht:
Welle 44,4 % · H1 39,3 % · Squeeze 37,3 % · M30 31,9 % · Elliott 26,2 % ·
KI 16,2 %
Die Welle dominiert also mit dem hoechsten Wert im Feld, genau wie entworfen -
ihre 3,8 % im Alltag sind schlicht die 91 % gewollte Stille der Gates. Meine
vorherige Formulierung ("Gewichtung invertiert") war zu scharf und ist
korrigiert.
Was bleibt: H1 und Elliott haben in beiden Spalten fast denselben Wert, weil sie
praktisch nie schweigen - ein permanenter Hintergrund von ~65 %, gegen den die
episodischen Module anschieben muessen. Elliott ist dabei ueber 1.163 Episoden
flach (49 % Treffer).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
45c3cec5b5 |
Erste Auswertung der verdict_votes: die Gewichtung ist in der Praxis invertiert
analyze_verdict_modules.py, 13.568 Zeilen (24.07.-05.08.). Nominal-Gewicht sagt fast nichts darueber, wie stark ein Modul die Bias-Nadel bewegt - entscheidend ist, wie oft es ueberhaupt mitredet. Realer Anteil am Gesamtgewicht: H1 38,5 % · Elliott 26,0 % · M30 12,2 % · Squeeze 7,0 % · Liq-Trend 6,1 % · Orderbuch 4,1 % · Welle 3,8 % · Muster 1,8 % · KI-Copilot 0,5 % Die Welle hat das hoechste Nominal-Gewicht (3,0) und den drittkleinsten realen Einfluss - die Gates schalten sie zu 91 % stumm. Die Nadel wird faktisch von H1 + Elliott bestimmt (zusammen 64,5 %); die beiden validierten Module kommen zusammen auf 10,8 %. Dokumentations-Fehler korrigiert: CLAUDE.md behauptete, Elliott habe Gewicht nur bei gerichtetem Ziel (1,3 % der Zeilen). Real ist elliott_w > 0 in 13.558 von 13.568 Zeilen (99,9 %) - Elliott ist die zweitlauteste Stimme im Verdict. Praediktivitaet als Sichtung (Forward-Return 60 min, gegen die Drift-Null, Minutentakt zu Episoden zusammengefasst): Elliott -0,031/-0,020 bei 49 % Treffern ueber 1.163 Episoden - groesste Stichprobe, und flach. Uebrige Module zu duenn oder kippend. 12 Tage = ein Regime, deshalb Sichtung statt Urteil. Methodik-Korrektur beim Bau: erst wurde nur die Stimme gezaehlt, nicht das Gewicht (getrennte Spalten). Genau dabei kam heraus, dass elliott_w praktisch immer gesetzt ist. Nichts geaendert - die Bias-Nadel ist reine Anzeige, die Order steuert die Welle ueber die Headline. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
a13adb891b |
Zwei neue Tabs: "SIG Live" und "SIG Anzeige", Module nach WIRKUNG sortiert
User-Vorgabe. Sortiert wird nicht nach Thema, sondern danach, ob ein Modul die Empfehlung bewegt - und das ist am Code pruefbar: engine._verdict ruft add(name, vote, gewicht, ...); Gewicht > 0 heisst Einfluss auf die Bias-Nadel. SIG Live <- KI-Copilot (Gewicht 1,0) · Chartmuster (_PAT_W = 0,25) SIG Anzeige <- Marktstruktur · Kerzen-Anatomie (gemessen ohne Einfluss) Chartmuster landet damit bewusst in "Live", obwohl die Klasse als Signal verworfen wurde - seit 01.08. hat sie 5 % Stimmanteil. "Gewicht" heisst nicht "belegt"; genau deshalb ist die Trennung nach Wirkung sinnvoll: sie zeigt, was die Empfehlung TATSAECHLICH bewegt, unabhaengig von der Beleglage. Auf dem Dashboard bleiben Trade-Leiste, Gesamtempfehlung, Meldungen und Statistik (live). Die Meldungen-Karte enthaelt zwar einflussreiche Teile (Squeeze-Stimme, S/R-Close-Hinweis, Flip-Close), ist aber der Live-Meldungsstrom zum laufenden Trade und gehoert dorthin, wo gehandelt wird. Reiner Markup-Umzug: showView bildet data-view="siglive" auf #view-siglive ab, keine JS-Aenderung noetig. CSS-Regel analog zum Statistik-Tab, weil beide Views ausserhalb des <main>-Grids liegen. Die verschobenen Bloecke wurden aus git zurueckgeholt statt nachgetippt. Verifiziert am ausgelieferten HTML: 7 Tabs, 7 Views, keine doppelten IDs, keine verwaisten JS-Referenzen, section-Tags balanciert. v=141. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
65e12ab264 |
Kerzen-Anatomie zum dritten Mal gemessen: alle 40 Zellen negativ
backtest_candle_fade2.py. Bewusst nur EINE neue Achse geprueft - der Einstiegspreis, der am selben Tag Squeeze und Signal von negativ auf positiv gedreht hat: Market am Bar-Close gegen ruhende Limit-Order am Kerzen-Extrem, dazu der kanonische Exit (Trail 1,0 statt der alten Kopie mit 1,5). Sequentiell EIN Slot, Echtkosten, 80k M5, 2 Halbjahre, Kontrollgruppe ohne Volumen, Regel vorab fixiert. Ergebnis: keine einzige Variante ist irgendwo positiv - beide Einstiegsarten, alle Volumen-Schwellen, alle Gueltigkeitsdauern der Limit-Order. Der lehrreiche Teil: der Ausfuehrungs-Hebel ist NICHT universell. Beim Squeeze und beim Signal dreht die ruhende Order das Vorzeichen, hier macht sie es schlechter. Strukturell: eine Stop-Order fuellt einen BREAKOUT im Moment der Bestaetigung, eine Limit-Order fuellt einen FADE nur dann, wenn die Klimax sich weiter ausdehnt - also genau wenn man falsch liegt. Sichtbar an der Schere: Trefferquote steigt (38,0 -> 40,1 %, bei Vol>=2,5 auf 48,5 %), OeR faellt trotzdem. Merksatz: ruhende Order hilft bei Momentum-Entries, schadet bei Reversion-Entries. Nebenbefund: im 12k-Vorlauf gab es positive Zellen (bis +0,291), ueber 80k verschwinden sie restlos. Ein kleiner Lauf haette zum dritten Mal zum Fehl-Einbau gefuehrt. Kachel bleibt reine Anzeige, kein neuer Zaehl-Eintrag (dieselbe Klasse wie #18). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e55b866f29 |
Kachel "Erwartete Spanne" entfernt, Kernwerte komprimiert in die Gesamtempfehlung
User-Vorgabe. #card-cone/#cone-list raus; neu die einzeilige #vd-cone unter der Bias-Nadel: "erwartete Spanne · 30' 75,99-76,77 · 60' ... · trifft 77 %". Gezeigt wird nur noch das 80-%-Band je Horizont; das enge 50-%-Band und der Erklaer-Absatz stecken im title. Platzierung und Farbe sind Absicht: die Zeile steht UNTER der Nadel und ist neutral/randlos - sie zeigt Streuung, nicht Richtung, und darf optisch nicht mit dem Bias konkurrieren. Beschriftet bleibt sie mit der REAL gemessenen Abdeckung (~77 %), nicht mit dem Nennwert 80 %. Backend unveraendert aktiv (core/cone.py, Snapshot cone, MT5-Export CN;...). Verifiziert am ausgelieferten HTML: card-cone weg, vd-cone da, keine verwaisten JS-Referenzen, Klammern-Balance ok. v=140. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
516f1eaa7f |
Roast-Punkte 1-3: Erfolgskontrolle erweitert, flip_close sichtbar, WARTEN-Massstab
korrigiert - und ein eigener Messfehler gefunden
(3) backtest_dist_gated.py: der 43-%-Massstab war UNGUELTIG. backtest_dist.py
misst _build ALLEIN, ohne Breakout-Bestaetigung und ohne Entry-Raum-Gate - genau
die beiden sind live die groessten Blocker. Ueber 80k Bars: nur _build 77,9 %
gerichtet, voller Live-Stack 19,5 %, live 7,2 %. Der reale Abstand ist 12,3 Pp,
nicht 50. Damit ist der "93 statt 43 %"-Alarm entschaerft, der den TF-Churn-Fix
ausgeloest hat; die dortige Erfolgskontrolle ist hinfaellig. Ein Rest bleibt
(min_conf live 16,3 % gegen 0,9 % in der Sim) und ist als naechster Ansatzpunkt
notiert.
⚠ Dabei EIGENEN Fehler gefunden: set_entry_room(0.6) fehlte in DREI heute neu
gebauten Skripten - _entry_room_atr ist im Konstruktor 0.0, _room_gate ist dann
ein No-op. Aufgefallen, weil entry_room in der Verteilung mit 0 % auftauchte
statt mit 35 %. Alle drei korrigiert und die SIG-Messung WIEDERHOLT: Population
aendert sich stark (n 967->295 / 1327->524), die Schlussfolgerung nicht - Market
in 7 von 8 Feldern negativ, am Level bestehen alle vier Schwellen
(OeR +0,392/+0,356, PF 2,37/2,39), Slippage-Test haelt bis 0,20 xATR. Die
heutige Bau-Entscheidung ist gedeckt.
(2) auto_flip_close ist jetzt sichtbar (#flip-note, v=139) - mit Schwelle,
Zaehler UND der Messung im Text ("gemessen in beiden Halbjahren negativ"). Ein
blanker Zaehler haette wie ein Erfolg ausgesehen. Der Exit bleibt an.
(1) analyze_squeeze_entry_gap.py erfasst jetzt BEIDE Bot-Pfade (Squeeze +
Signal), Reminder entsprechend erweitert - sonst wartet er auf eine Population,
die vielleicht nie kommt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
90d77a2305 |
Pending-Pfad fuer SIG: ruhende Stop-Order am Bestaetigungs-Level
SIG laeuft damit auf der gemessen positiven Variante (OeR +0,35/+0,32, PF 2,2) statt auf der Market-Order (-0,09/-0,11). Der heikelste Punkt war nicht die Order, sondern die Kollision beider Pfade: trader.pending_orders() liefert ALLE magic-gleichen Orders, zwei getrennte Manager haetten sich gegenseitig storniert - sporadisch und im Log kaum erkennbar. Deshalb EIN gemeinsamer Ziel-Zustand (engine._pending_ziel), der Manager gleicht nur noch ab. Vorrang Squeeze > Signal (unabhaengig validiert, selten; das Signal feuert dauernd, es gibt einen Positions-Slot). Zwei additive Ergaenzungen in wave_rec._confirm_breakout: das Bestaetigungs-Level wird auch NACH der Bestaetigung veroeffentlicht (die Nachjagd-Bremse braucht es genau dann; pending bleibt False, Frontend unberuehrt), und conf = die Konfidenz VOR dem Stummschalten - sonst muesste die ruhende Order blind platziert werden. Nachjagd-Bremse jetzt auch fuer SIG (0,20 xATR, Haertetest-gedeckt). 12 Szenarien getestet, live am Snapshot verifiziert. Snapshot-Felder squeeze_pending_levels -> pending_levels + pending_quelle. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
12fb11fa44 |
Auto-Signal (SIG) neu gemessen: besteht erstmals - aber nur am Level, nicht am Markt
backtest_auto_signal_v3.py, voller Live-Gate-Stack (echte _build / _confirm_breakout / _room_gate), sequentiell EIN Slot, Live-Dedup, kanonischer Exit, Echtkosten, 80k M5, 2 Halbjahre. A) Einstieg am Bar-Close (= heutige Market-Order): in ALLEN acht Feldern negativ (Konf 55/65/75/85 x 2 Halbjahre). Bestaetigt die drei Vormessungen. B) Einstieg am Bestaetigungs-Level (_pend["level"], ruhende Stop-Order): besteht in ALLEN acht - WR 39,6 -> 53,2 %, PF 0,83 -> 2,20, und alle vier Nachbar-Schwellen halten mit. Haertetest Fill-Slippage (Konf>=65): +0,05 -> +0,315/+0,249 · +0,20 -> +0,148/+0,090 (noch beidseitig positiv) · +0,31 -> +0,026/-0,031. Die letzte Zeile ist die interne Kontrolle: bei Slippage gleich dem gemessenen Median-Abstand (0,311 xATR) konvergiert B gegen A. Nichts umgeschaltet. Grenzen dokumentiert: fuer SIG ist nicht verifizierbar, wo live zwischen A und B liegt (nur 4 echte Trades); _pend verankert sich staendig neu, eine ruhende Order muesste nachgezogen werden und faellt bei Nicht-Platzierbarkeit auf A zurueck; _pend steht nicht im Snapshot. Methodik-Fehler beim Bau gefunden und behoben: der erste Entwurf liess pend["level"] nach der Bestaetigung stehen und waere bei verzoegertem Einstieg zu einem laengst verlassenen Preis eingestiegen - sichtbar an einem unplausiblen Bruch zwischen Konf 65 und 75. Behoben ueber ein frisch-Flag. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
43b7756df3 |
Manuelle Trades, Letzte Trades und Kurslueken in den Statistik-Tab verschoben
User-Vorgabe: die drei sind Rueckschau, das Dashboard soll das
Handlungsrelevante zeigen. Reiner Umzug im Markup - keine Logik beruehrt.
Die Karten werden weiterhin von render() aus dem Snapshot gefuettert und
haengen NICHT an loadStats(); ein ausgeblendeter View ist nur display:none,
die Elemente bleiben im DOM.
Noetig war eine CSS-Regel: #view-stats > .card{margin:11px 10px}. Das
Dashboard ist ein <main>-GRID mit eigenem Padding, #view-stats eine schlichte
<section> - ohne die Regel klebten die Karten randlos aneinander und
.card.wide{grid-column:1/-1} liefe ins Leere.
Verifiziert am ausgelieferten HTML (alle drei nach id="view-stats",
card-stats-live bleibt im Dashboard), keine doppelten IDs, Tag-Balance
geprueft. v=138.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5f70980e59 |
Erfolgskontrolle fuer den Stop-Order-Umbau: Skript + Reminder
analyze_squeeze_entry_gap.py fuehrt die zwei noetigen Quellen zusammen - das Ausbruchs-Level steht NUR im Log, der tatsaechliche Fill NUR in trades - und splittet am Umbau-Stichtag. Die Erfolgsmeldung ist paradox: eine per Pending gefuellte Order erzeugt KEINE AUTO-SQUEEZE-ENTRY-Logzeile (die entsteht nur im Market-Fallback), Squeeze-Trades ohne Log-Treffer sind also der Erfolg. Das Skript weist sie deshalb getrennt aus. Als Messung squeeze_entry_gap im measurement_reminder.py hinterlegt (>=12 Squeeze-Trades ab dem Umbau). Stichtag exakt 05.08. 08:55 statt Mitternacht - der 08:33-Trade lief noch ueber die Market-Order und haette die Zaehlung verfaelscht (0/12 statt faelschlich 1/12). Zahlen-Korrektur: die zuerst dokumentierten +0,306 / +0,741 xATR stammten aus einer Scratchpad-Auswertung mit FESTEM Stundenversatz. DST-korrekt ueber zoneinfo sind es +0,275 / +0,686 (n=34 unveraendert). In CLAUDE.md, engine.py, trader.py und der ini nachgezogen; die Schlussfolgerung aendert sich nicht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5e0e8b00ca |
Squeeze-Einstieg ueber ruhende Stop-Orders + Meta-Labeling gemessen (verworfen)
1) STOP-ORDER STATT MARKET (gebaut, live). engine._manage_squeeze_pending haelt beide Box-Grenzen mit BUY_STOP/SELL_STOP bestueckt, solange der Squeeze armed ist; trader.place_stop/cancel_pending/pending_orders neu. Groesse und SL kommen aus denselben Funktionen wie die Market-Order, nur bezogen auf den Trigger. OCO-Ersatz: faellt eine Seite, wird die andere im selben Tick storniert. Der kritische Punkt bei einer ruhenden Order sind die Gates - sie waren bisher Laufzeit-Checks im Market-Pfad. Neu: engine._squeeze_guard() als EINE Quelle fuer beide Wege, jeden Tick neu bewertet; schlaegt ein Gate zu, werden die Orders storniert. Market bleibt Fallback mit Nachjagd-Bremse squeeze_max_chase_atr=0.20 (gemessen der noch positive Bereich). Behandelt: Broker-Mindestabstand, falsche Marktseite, Toleranz 0,02 xATR gegen Order-Churn, Log nur bei Fehleraenderung, Startup-Schonfrist. 10 Szenarien getestet, live am Snapshot verifiziert. 2) META-LABELING (backtest_metalabel.py) - VERWORFEN. Zweitmodell auf 12 kausalen Merkmalen, Fit/Test in BEIDEN Richtungen: AUC 0,508 und 0,479 = Muenzwurf, Kalibrierung im Top-Bucket 74 % vorhergesagt gegen 39 % real, und 8 von 12 Gewichten kippen das Vorzeichen. Die scheinbar besseren Schwellen sind reine Handelsvermeidung und reproduzieren gegenlaeufig nicht. 23. verworfener Signal-Eingriff - deckt sich mit dem Caveat der Quelle. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3b00820c15 |
Loesung fuer Fall 7 gemessen: ruhende Stop-Order am Level statt Market
Anstoss aus der Web-Recherche ("don't chase breakouts with market orders;
place orders just beyond the breakout level"). Variante E in
backtest_squeeze_entry.py: PENDING BUY_STOP/SELL_STOP, die schon liegt
waehrend der Squeeze armed ist, und vom Ausbruch selbst ausgeloest wird -
anders als die Limit-Order wartet sie NICHT auf einen Ruecklauf.
Ergebnis (80k M5, 2 Halbjahre, sequentiell, kanonischer Exit, Echtkosten):
Level +0,05 xATR -> OeR +0,397 / +0,553 PF 2,28 / 3,06
Level +0,10 xATR -> OeR +0,355 / +0,509
Level +0,20 xATR -> OeR +0,244 / +0,426 PF 1,62 / 2,25
gegen Market/Live -0,158 / -0,006. Selbst mit dem ~9-fachen Median-Spread
als unterstellter Fill-Slippage bleibt es beidhaelftig klar positiv.
Kernpunkt: nicht der Median-Abstand toetet den Edge, sondern der SCHWANZ
(live Median +0,306 xATR, Mittel +0,741, Max +4,339). Eine Stop-Order
deckelt den Einstiegspreis konstruktiv, die Market-Order auf dem 5-s-Poll
nicht. Die Extremfaelle stammen aus blockiert-dann-freigegebenen Ausbruechen.
NICHT gebaut - die Guards (Nacht/News/Cooldown/flat) wirken heute als
Laufzeit-Checks und muessten mit einer ruhenden Order ueber Platzieren/
Stornieren durchgesetzt werden; dazu MT5-Mindestabstand und Storno beim
Klaeren des Squeeze.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
8d93de9867 |
Deployment-Drift Fall 7: Squeeze wird zu einem Preis gehandelt, den die
Validierung nie unterstellt hat backtest_breakout_squeeze.py steigt AM LEVEL ein. Live schickt _check_auto_squeeze eine MARKET-Order - aus 34 echten Entries (Logs 16.07.-05.08., Level aus der Log-Zeile x Einstiegspreis aus der DB) liegt der Einstieg im Median +0,306 xATR ueber dem Level, nur 18 % innerhalb 0,10. Gemessen (backtest_squeeze_entry.py, 80k M5, 2 Halbjahre, sequentiell EIN Slot, kanonischer Exit, Echtkosten): allein der Einstiegspreis dreht das Setup - OeR +0,456 -> -0,158 (H1) und +0,611 -> -0,006 (H2), WR 56 -> 37 %. Ordnet den B4-Befund vom 01.08. neu ein: dort wurde die Luecke zwischen Mechanik (+0,102) und Live (-0,242) dem EXIT zugeschrieben. Die Mechanik-Zahl unterstellt aber denselben Level-Einstieg - es war ueberwiegend der ENTRY. Beide naheliegenden Reparaturen fallen durch (Regel vorab fixiert): Abstands-Bremse 0,10-0,40 xATR alle 5 durch (die NAHEN Ausbrueche sind pro Trade die schlechteren - Fehlausbruch-Effekt), LIMIT/Retest am Level in allen 5 Varianten schlechter als Market. Nichts abgeschaltet - der Befund staerkt die bereits fixierte B5-Abbruchregel, die Entscheidung bleibt beim User. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
cc4f1a0863 |
Provider-Failover bei hartem Fehlschlag + Einsatz-Prozentfeld im Dashboard
1) LLM-Failover (core/agent.py): ein hart gescheiterter Provider wird zeitweise uebersprungen, analyze() nimmt den naechsten aus der Kette. Hart = 401/402/403/ 404 (Key/Guthaben/Modell) -> 30 min, nicht erreichbar -> 5 min. Timeout/429/5xx loesen BEWUSST keinen Wechsel aus (voruebergehend; sonst kostet jede Lastspitze die volle Timeout-Summe aller Anbieter). Neu im Snapshot: agent.provider_dead mit Restminuten - der DeepSeek-Ausfall stand vorher nur im Log und blieb deshalb 18 h unbemerkt. 9 Szenarien getestet. 2) Einsatz-Prozentfeld (web, v=137): margin_buffer_pct hatte bisher keine UI. Neues Feld "Einsatz %" neben "Einsatz EUR", POST /api/marginpct -> engine.set_margin_pct -> config.set_margin_buffer, Snapshot margin_pct, neustart-fest. Der feste EUR-Betrag hat Vorrang; das Prozentfeld wird dann ausgegraut, damit nicht unklar bleibt was gilt. Auf 1-99 % geklemmt. Ende-zu-Ende getestet (50, 150->99, 0 und -5 abgelehnt, 95, persistiert). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7e9b0196a5 |
Copilot-Provider auf z.ai umgestellt (DeepSeek-Guthaben leer)
DeepSeek liefert seit 04.08. 14:52 durchgehend HTTP 402 "Insufficient
Balance" - 29 Fehlversuche. Alle konfigurierten Provider real getestet:
zai/glm-4.5-flash OK in 2,3 s (kostenlos), kimi-k2.6 OK in 7,6 s
(kostenpflichtig), deepseek 402, ollama nicht konfiguriert.
Gewechselt auf zai: kostenlos, schneller als DeepSeek, im Projekt schon
fuer daily_levels im Einsatz, und der _has_cjk-Retry deckt es ab. Live
verifiziert nach Neustart ("[zai] NEUTRAL (30%)").
Nebenbefund, dokumentiert aber NICHT behoben: die Fallback-Kette
deepseek->kimi->zai->local hat nicht gegriffen, weil _active_provider in
avail nur das Key-FORMAT prueft, nicht ob der Key noch funktioniert. Ein
Provider ohne Guthaben gilt als verfuegbar und blockiert die ganze Kette -
der Copilot lief ~18 h still ins Leere.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
1c9bb34095 |
Auto-Squeeze-Nachtsperre von 0-7 auf 3-6 Uhr verkuerzt (User-Vorgabe)
Gemessen (backtest_cost_gate.py, Teil 2): es gibt KEINE toten Stunden - alle 24 Stunden sind in beiden Halbjahren positiv, keine ist beidhaelftig negativ. Std 0 ist sogar die staerkste des Tages (OeR +1,48/+1,51) und lag im alten Gate. Jedes Fenster kostet also Ertrag; die Sperre kauft ausschliesslich Beaufsichtigungs-Ruhe. Gewaehlt wurde deshalb nach PREIS, nicht nach Edge: 3-6 ist das guenstigste Fenster mit noch >=4 h Schutz (SigmaR -12,5/-62,9 gegen -42,4/-242,6 bei 0-7 = ~27 %). Freigegeben: 0, 1, 2, 7 Uhr. Die 4-h-Untergrenze ist gesetzt, nicht gemessen. Umsetzung: neues [trading] auto_squeeze_night_hours (Default 3,4,5,6, leer = aus), genutzt von _check_auto_squeeze und _check_auto_signal. _SQUEEZE_NIGHT bleibt als STATISTISCHE Nacht-Definition fuer Entry-Checkliste und B4-Monitor - dort gilt die Kostenfalle weiter und der Altdaten-Vergleich bleibt stabil. 7 Parse-Faelle getestet (Default, fehlender Schluessel, leer, Muell, Rueckwaerts-Kompatibilitaet). Live verifiziert am NEUEN Snapshot-Feld squeeze_night_hours = 3,4,5,6 und am Startup-Log; genau eine Instanz auf 8000. Offen und als Reminder hinterlegt: der Backtest modelliert keine Slippage, und die freigegebenen Stunden liegen in der duennsten Liquiditaet. Nach 15 Squeeze-Trades aus 0/1/2/7 Uhr gegen die Erwartung pruefen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
cdee6eced7 |
Kosten-Gate gegen Stunden-Gate gemessen: Nachtsperre ist auf falscher Population begruendet
backtest_cost_gate.py — echte _squeeze_one, kanonischer Exit, Echtkosten,
80k M5, 2 Halbjahre, geteilte Entry-Liste + sequentielle 1-Slot-Sim.
(a) Kein Kosten-Gate ersetzt das Stunden-Gate nach der vorab fixierten Regel.
(b) Das Stunden-Gate selbst kostet in BEIDEN Haelften: sequentiell SigmaR
-42 (H1) / -243 (H2) gegen "kein Gate". Die geblockten Ausbrueche sind
in beiden Haelften positiv (OeR +0,496/+0,589).
Mechanismus belegt: die Nacht-Kostenfalle ist echt (alle Nacht-Bars Median
0,333 / Mittel 0,387 xATR, reproduziert backtest_realcosts), gilt aber nicht
fuer Squeeze-Ausbrueche (0,183/0,191 = Tag-Niveau). Der Squeeze verlangt
anziehenden ATR und selektiert sich damit aus der Falle heraus. Gemessen am
Wellensignal, angewandt auf den Squeeze = Deployment-Drift Fall 6.
KEINE Aenderung vorgenommen: Slippage ist nicht modelliert (groesste
Bedrohung des Befunds), die duenne Live-Stichprobe sagt das Gegenteil, und
der Beaufsichtigungs-Grund ist eine Praeferenz. auto_squeeze_skip_night
bleibt true.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
c9f1e8d039 |
Zeitzonen-Bug in analyze_tageszeit.py behoben + Squeeze-Nachtsperre 05.08. dokumentiert
Zeitzone: datetime.fromtimestamp(rates["time"], UTC+3) behandelt den MT5- Bar-Zeitstempel als echten UTC-Epoch - MT5 liefert dort aber bereits die Broker-Wallclock. Jede Stunde war 3 h zu spaet einsortiert. Empirisch gegen die Wallclock geprueft (letzte Bar 11:00 statt real 08:00). Helfer _berlin() mit korrekter Konvention; Rest des Projekts war nicht betroffen (geprueft). Neu gerechnet: ALLE VIER Tagesbloecke kippen zwischen den Haelften - es gibt gar kein Tageszeit-Muster. Der zuvor gemeldete "Nachmittag robust negativ" war der um 3 h verschobene Abend. Plausibilitaetstest, der es entlarvt haette: die duennen Stunden (n~650) muessen am Marktschluss liegen, nicht nachts. Squeeze 05.08.: 5 active-Ausbrueche zwischen 02:00 und 07:30 Berlin, alle von auto_squeeze_skip_night geblockt; Bot war ab 01:15 flat, also alleiniger Blocker. Mit kanonischem Exit + Echtkosten Sigma +3,56 R (~+95 EUR), davon 92 % in zwei Trades - n=5 an einem Tag ist kein Gegenbeleg zum Guard. Messbarer Ansatz notiert: kosten- statt stundenbasiertes Gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d75789ac72 |
Tageszeit-Drift gemessen: Morgens-runter/Nachmittags-rauf widerlegt
analyze_tageszeit.py misst die ROHE Kursdrift je Berliner Stunde (nicht den Signal-Edge). 80k M5-Bars, DST-korrekt, 2 Halften, Ueberschuss gegen den Tagesschnitt. Ergebnis: Vormittag 08-12 kippt zwischen den Halften, Nachmittag 14-18 ist robust NEGATIV - beide Halften der Vermutung fallen durch. Groessenordnung ohnehin unter dem Spread (staerkste robuste Stunde ~0,03 $/h vs 0,0225 $ Spread). Korrektur am eigenen Skript: der erste Entwurf hatte einen ATR-Filter (< 0,06 uebersprungen) plus ATR-Normierung. Der Filter verwarf ausgerechnet die ruhigen Morgenstunden der aelteren Periode (n 138-391 statt 1740) und erzeugte so den vermeintlichen Befund. Beides entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6af4c868bc |
Feste Einsatz-Margin (UI-Feld) + lokale Sprachausgabe via Piper
EINSATZ-FELD (User-Wunsch): Laufzeitwert MANUAL_MARGIN in core/config.py (set/get_manual_margin, Muster wie set_margin_buffer). 0 = automatisch wie bisher (margin_buffer_pct % der freien Margin), > 0 = Position wird auf genau diesen Margin-Einsatz gerechnet. - calc_lots setzt es um und DECKELT auf freie Margin x Buffer; ein zu hoher Wunschwert wird begrenzt und geloggt statt an den Broker durchgereicht. Reicht der Betrag nicht fuers Mindestlot -> 0.0 + Warnung, Trade sauber abgelehnt. - Vorrang vor dem Risiko-Modus in trader._send_locked: eine ausdrueckliche Groessenvorgabe schlaegt die Rechenregel. - Wirkt auf ALLE neuen Positionen, auch die autonomen. - UI-Feld "Einsatz" in der ORDER-Leiste (nicht in der Trade-Leiste: die ist nur bei offener Position sichtbar, der Einsatz muss vorher einstellbar sein), bernstein umrandet solange gesetzt. Enter blurrt nur, change sendet einmal. - POST /api/manualmargin, Snapshot manual_margin, neustart-fest ueber runtime_state.json. Ende-zu-Ende getestet (250 -> Snapshot -> 0 -> persistiert). - Lot-Logik isoliert geprueft: 200 EUR -> 0,58 Lots; 5000 EUR -> gedeckelt. SPRACHAUSGABE: Piper lokal (tools/speak.py). Windows-TTS funktioniert zwar, aber es ist KEINE deutsche Stimme installiert - weder SAPI5 noch OneCore (nur David/Zira/Mark, en-US); deutscher Text kaeme mit englischer Aussprache. Add-WindowsCapability scheitert ohne Adminrechte. Piper gewaehlt: laeuft lokal (passt zum Rest - WireGuard-only, Secrets in der ini, keine Cloud), kostet nichts, aus PowerShell/Python aufrufbar. Stimme thorsten-medium (de_DE), Real-Time-Faktor 0,08 (4,3 s Audio in 0,36 s). Das ZIP entpackt eine Ebene tiefer als erwartet (tools/piper/piper/piper.exe) - speak.py SUCHT Binary und Modell statt Pfade fest zu verdrahten. Der erste Entwurf scheiterte daran; der Fail-safe meldete die Pfade sauber statt stumm zu bleiben. Drei Modi getestet (Argument, Pipe, --wav). tools/piper/ ist gitignored (Binaries + 60-MB-Modell), speak.py versioniert. v=136. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
33b6b8f629 |
Letzte Trades: 5 -> 10 (User-Wunsch)
Zwei unabhaengige Begrenzungen mussten mitgezogen werden: - engine.snapshot -> history.last_closed_trades(5) -> (10) - app.js -> slice(0, 5) -> slice(0, 10) Nur eine davon zu aendern haette still weiter 5 gezeigt; beide sind jetzt gegenseitig im Kommentar vermerkt. Verifiziert: Snapshot liefert 10 Trades, v=135 ausgeliefert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1c976cc8fd |
M30-Level-Umstellung live gegengeprueft — bestaetigt, Normierung war entscheidend
Faellige Messung aus dem Reminder (28/30 erreicht). S/R-Auto-Closes vor/nach der Umstellung der Level-Quelle M5 -> M30 am 30.07. Zeitraum n Med.Lots EUR/Lot O Move vorher (M5-Level) 89 0,81 +17,53 0,202 $ nachher (M30-Level) 28 0,53 +36,92 0,427 $ Ertrag je Lot mehr als verdoppelt, O-Kursbewegung je Trade ebenfalls - deckt sich mit der Backtest-Erwartung und mit dem Mechanismus (M30-Level liegen 1,95xATR auseinander statt 0,61xATR, der Trade laeuft laenger). DIE NORMIERUNG WAR ENTSCHEIDEND, sonst waere der Schluss falsch gewesen: unnormiert sah der 04.08. wie der Treiber aus (O +55,41 EUR je Trade gegen +19,30 im Rest). Je Lot ist heute aber praktisch identisch zum Rest (+38,81 vs +35,87) - der Unterschied war reine Positionsgroesse (Median 1,36 statt 0,46 Lots, weil das Konto an dem Tag von ~800 auf ~1.400 EUR wuchs). O-EUR-Vergleiche ueber Zeitraeume mit unterschiedlicher Positionsgroesse sind ungueltig. NICHT der Level-Quelle allein zuzuordnen: am 31.07. kamen P(break)-Nachtraining und Schwelle 0,55->0,35 dazu. Getrennt: 30.07. (nur M30-Level, altes Modell) n=8, +19,88 EUR/Lot; ab 31.07. (M30 + neues Modell) n=20, +43,73 EUR/Lot. Das Fenster mit nur der Umstellung ist zu klein. Der kombinierte Effekt ist bestaetigt, die Ursachenaufteilung nicht. Messung im measurement_reminder ausgetragen (mit Ergebnis als Kommentar). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e558a8dd5b |
Reminder: Stufe 2 "Manuelle Trades" eingetragen
Neue Messung manual_ctx im measurement_reminder: faellig bei >=300 manuellen Trades mit gefuelltem ctx_*-Kontext (Sammlung laeuft seit 04.08.). Die Faelligkeitsbedingung ist pruefbar (Zeilenzahl), nicht nur ein Datum - wie alle anderen Eintraege auch. Der cmd-Text haelt die Methode fest (Fit auf der ersten Haelfte, validiert auf der zweiten, AUC + Kalibrierung wie bei backtest_pbreak_retrain.py) UND die Einschraenkung: 300 reichen fuer eine ERSTE SICHTUNG, nicht fuer ein Urteil - mit ~150 je Haelfte und mehreren Merkmalen ist die Overfit-Gefahr hoch. Ziel bleibt ein Hinweis im Order-Dialog, ausdruecklich kein Auto-Entry. Ohne diesen Eintrag waere die Sammlung genau so liegen geblieben wie die P(break)-Genauigkeit, die 2213 auswertbare Zeilen hatte bevor jemand hinsah. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
da7d8f5b90 |
Stufe 1: voller Entscheidungskontext beim Einstieg + Karte "Manuelle Trades"
Frage: kann der Bot aus den manuellen Trades lernen? Vorpruefung: noch NICHT.
1) Die entscheidenden Merkmale wurden nie gespeichert - beim Einstieg nur 5
Felder, davon ai_sentiment in 1,4 % und news_score in 34 % befuellt.
2) Das naive Lernziel ("wann steigt er ein") braucht unbeschriftete Negative;
brauchbar ist nur "welche Einstiege liefen gut" (Labels ueber P&L).
3) Die scheinbaren Muster sind Einzeltage: Stunde 13:00 zeigt +478 EUR ueber
n=69, davon +382 EUR (80 %) aus den fuenf Trades des 04.08.
Gebaut wurde Stufe 1 - reine Telemetrie, kein Verhalten:
- trades um 16 ctx_*-Spalten erweitert (DB-Backup .bak-2026-08-04, 1.148 Zeilen
unveraendert): p_break_target/-stop, dist_res_atr/dist_sup_atr, structure,
squeeze, htf_trend/h1_trend, spread_atr, session, block_reason, conf_pct,
atr_m5, bias, cone_pos, hour
- log_trade_open haengt die Spalten dynamisch an und ignoriert unbekannte
Schluessel -> aeltere DB ohne Migration laeuft weiter (fail-open)
- Kette: engine._run_analysis -> trader.set_open_context(ctx=) -> log_trade_open
Fallstrick beim Bau: wave_snap existiert in _run_analysis NICHT (nur in
snapshot()). Der erste Entwurf haette einen NameError erzeugt, den das umgebende
except still geschluckt haette - der Kontext waere dauerhaft leer geblieben ohne
dass es auffaellt. Jetzt self.wave.snapshot(); vd zusaetzlich per locals()-Guard.
Verifiziert auf einer DB-KOPIE: alle 16 Spalten korrekt geschrieben, unbekannter
Schluessel ignoriert, Basisfelder unberuehrt. Snapshot liefert manual_stats.
Dashboard-Karte "Manuelle Trades" (#card-manual, v=134): heute / 30 Tage /
gesamt / Bot-Vergleich plus Split mit vs ohne Signal-Deckung. Backend
history.manual_stats(30) mit ~120-s-Cache wie _alignment_cached. Bewusst neutral
gefaerbt und deskriptiv; eine Reifegrad-Zeile nennt die ctx-Abdeckung (heute
0 %), damit die Karte nicht ueberschaetzt wird.
Stufe 2 NICHT gebaut: erst bei ausreichender ctx-Abdeckung messen, was Gewinner
von Verlierern unterscheidet (Fit H1, validiert H2, AUC + Kalibrierung). Ergebnis
waere ein Hinweis im Order-Dialog, ausdruecklich KEIN Auto-Entry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7432be0e8c |
M30-Filter nach Vola-Regime geprueft — Hypothese invertiert, keine Aenderung
Anlass: Am 04.08. fiel WTI -4,12 $ (davon -4,16 $ in EINER Stunde), der Bot stand zu 93 % auf WARTEN, htf_counter blockte 160-mal. Hypothese: die nachlaufende M30-EMA sperrt in schnellen Umkehrungen das Richtige. Die Messung invertiert die Hypothese. Geblockte Signale, kanonischer Exit, Echtkosten, nach ATR-Terzil x 2 Halbjahre: Terzil geblockt H1 geblockt H2 durchgel. H1 durchgel. H2 niedrig -0,086 +0,107 -0,136 -0,134 mittel -0,172 +0,067 -0,198 -0,069 hoch -0,625 -0,329 -0,061 +0,014 Im HOHEN Terzil sind die geblockten Signale mit Abstand die schlechtesten des gesamten Datensatzes (PF 0,15 / 0,42) - der Filter ist dort am wertvollsten, nicht am schaedlichsten. Die durchgelassenen Hoch-Vola-Signale in H2 sind das einzige positive Feld der ganzen Tabelle. In den unteren Terzilen kippen die geblockten Signale zwischen den Haelften = Rauschen. Den Filter in schnellen Bewegungen zu lockern waere die schlechtestmoegliche Aenderung gewesen. 22. verworfener Eingriff. Auflösung des scheinbaren Widerspruchs: die 160 geblockten Signale und die 17 manuellen Gewinn-Trades desselben Tages sind VERSCHIEDENE Grundgesamtheiten. Die manuellen Trades liefen alle auf rec=WARTEN, stammen also gar nicht aus der Signal-Logik - der Filter hat den User nie gebremst. "Das Gate blockte X" und "der Mensch verdiente Y" gehoeren nur zusammen, wenn Y aus X stammt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
20137a3dd1 |
SL-Breite gemessen: Confounder bestaetigt, aber keine Aenderung (Regel greift)
Anlass: analyze_manual_close.py fand +1.229 EUR auf der Verlustseite, mit dem explizit benannten Confounder, dass simulate() 2,0xATR_M5 ansetzt waehrend live ATR_M15 gilt. backtest_sl_width.py trennt beides: gegatete Live-Population (1.224 Entries, Reversal aus, k=0,3), kanonischer Exit, variiert wird ausschliesslich die SL-Breite. ATR_M15 / ATR_M5 = 1,80 im Median -> der Live-SL ist rund 3,6xATR_M5 breit, nicht 2,0. Genau daraus entstanden die 1.229 EUR. Confounder bestaetigt. SL-Basis H1 OR/SR H2 OR/SR Worst H1/H2 2,0xATR_M5 -0,092 / -44 -0,024 / -18 -2,33 / -2,29 2,0xATR_M15 LIVE -0,145 / -69 +0,064 / +48 -4,77 / -5,64 1,5xATR_M5 -0,081 / -38 -0,038 / -28 -1,83 / -1,85 2,5xATR_M5 -0,121 / -58 -0,013 / -10 -2,83 / -2,79 3,0xATR_M5 -0,130 / -62 +0,018 / +13 -3,33 / -3,29 KEINE engere Variante schlaegt den Live-SL in BEIDEN Haelften - H2 bevorzugt den weiten Stop klar. Die vorab fixierte Regel ist nicht erfuellt: keine Aenderung. Das reproduziert backtest_sl_tf_mismatch.py (23.07., dort auf Squeeze-Entries mit eigenem Exit-Nachbau) jetzt auf der gegateten Population mit kanonischem Exit - der alte Schluss war korrekt. Der echte Unterschied ist das TAIL-RISIKO und damit eine SIZING-Frage: Worst-Case -5,64xATR (live) gegen -1,85xATR (bei 1,5xATR_M5), Faktor 3. Bei ATR 0,30 sind das ~1,7 $; unter 95 %-Margin auf ~800 EUR Konto ist ein solcher Trade ~19 % des Kontos. Der weite Stop kauft die H2-Performance mit genau diesem Tail. Wer ihn begrenzen will, senkt margin_buffer_pct - nicht die SL-Breite, die kostet gemessen H2. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3ec4d53022 |
Frueh-Kappen kontrafaktisch geprueft — Hypothese widerlegt, Leckage liegt woanders
analyze_manual_close.py simuliert fuer jeden real geschlossenen Trade ab dem echten Einstieg den kanonischen Exit und vergleicht gegen das tatsaechliche Ergebnis. EUR-Faktor 87,6 EUR/$/Lot, robust aus 251 Trades geschaetzt (trader.pnl enthaelt Swap, direkte Rueckrechnung waere verfaelscht). Schliessgrund n IST Bot-Exit Delta manual Gewinn 143 +1428 +962 -467 sr_close Gewinn 106 +1591 +1060 -530 emergency Verlust 98 -1750 -1235 +515 sl Verlust 69 -1926 -697 +1229 Die Frueh-Kappen-Hypothese ist WIDERLEGT: das diskretionaere Schliessen kostet nichts, es bringt +467 EUR MEHR als der kanonische Exit; in 62 % der Faelle war der manuelle Close besser. Dasselbe gilt fuer den S/R-Auto-Close (-530). Beide realisieren Gewinne besser als reines Trailing. Die Leckage liegt auf der VERLUSTSEITE: die 69 per Broker-SL geschlossenen Trades haetten mit dem kanonischen Exit 1.229 EUR weniger verloren, die 98 Notfall-Closes 515 EUR weniger. Ueber alle Trades waere der kanonische Exit rund +700 EUR besser gewesen, praktisch vollstaendig aus der Verlustseite. Confounder benannt: simulate() setzt den Initial-SL auf 2,0xATR_M5, live kommt er aus ATR_M15 und ist oft deutlich weiter - unter Margin-Sizing schlaegt das voll auf den EUR-Verlust durch. Der +1.229-Wert misst also erheblich SL-BREITE, nicht Exit-Logik. backtest_sl_tf_mismatch.py hat die M5-Umstellung schon geprueft und wegen H2 verworfen; dieser Befund gibt Anlass, das mit dem kanonischen Exit zu wiederholen. Zweite Grenze: Vergleich gilt pro Trade, nicht als Kontostand-Hochrechnung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
b376619663 |
Mini-Trades untersucht: Mindestgewinn-Gate erneut verworfen, Praemisse korrigiert
User-Frage: "es gibt immer noch Mini-Trades mit geringen Gewinnen, wie
verhindern wir das?"
1) Mindestgewinn-Gate mit dem NACHTRAINIERTEN P(break)-Modell nachgemessen -
Ablehnung bestaetigt, deutlicher als zuvor. Delta SR gegen minR=0:
0,1xATR -6 / +10
0,2xATR -720 / -42
0,3xATR -1136 / -157
0,5xATR -1998 / -683
0,8xATR -2887 /-1577
Monoton schlechter in BEIDEN Haelften. Uebersprungene Klein-Closes prallen am
haltenden Level ab und enden schlechter.
2) Die Praemisse stimmt so nicht. 295 Trades seit 20.07.: die 28 Gewinne <=2 EUR
bringen zusammen +21,11 EUR = 0,8 % der Brutto-Gewinne (2.770 EUR). Kein
Ertragsproblem. Entscheidend ist die Herkunft:
sr_close (Bot) n=81 Median +14,65 davon <=2EUR: 10 (+7,65)
manual (User) n=64 Median +6,37 davon <=2EUR: 18 (+13,46)
Zwei Drittel der Mini-Gewinne sind MANUELLE Closes, und der manuelle
Median-Gewinn ist weniger als die Haelfte des Bot-Medians. Die Klein-Closes
des Bots sind gemessen richtig; die Asymmetrie liegt im diskretionaeren
Frueh-Kappen. Ein Code-Gate am Bot-Exit adressiert das falsche Ende.
Keine Codeaenderung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
a172353cee |
Fibonacci-Retracements gemessen — verworfen (21. Signal-Eingriff)
Anlass: USOIL-Kommentar "ein Fibonacci-Retracement sollte den Kurs auf 79 $
druecken". Fib-Level waren im Projekt nie gemessen worden. Aufbau wie beim
P(break)-Training: Schwuenge aus M15-Pivots, Beruehrung <=0,15xATR, Ausgang
+/-0,5xATR in 12 M5-Bars, 80k Bars, 2 Halbjahre, ZWEI Kontrollgruppen.
Haltequote:
H1 H2
Fibonacci 54,3 % 54,5 %
(a) Zufalls-Level 55,7 % 53,8 %
(b) M30-Pivots 56,6 % 55,4 %
Handelbarkeit (Bounce, kanonischer Exit, Echtkosten):
H1 OR -0,168 / PF 0,71 H2 OR -0,082 / PF 0,85
Der aufschlussreichste Wert ist die Zufalls-Kontrolle: ~55 % Haltequote. Ein
BELIEBIGES Level haelt in diesem Markt in gut der Haelfte der Faelle - das ist
die Basisrate kurzfristiger Mean-Reversion, keine Eigenschaft von Fibonacci.
Damit ist auch das Selbsterfuellungs-Argument entkraeftet: dann muesste Fib
ueber der Zufallslinie liegen; es liegt darunter bzw. gleichauf.
Bestaetigt umgekehrt die Struktur-These: M30-Pivots - Stellen, an denen real
gehandelt wurde - halten in BEIDEN Haelften besser als beide gerechneten Linien.
Dieselbe Trennlinie wie beim Regressionskanal und beim P(break)-Modell:
"Linie im Chart" ist nicht "Struktur im Markt".
Zur konkreten Aussage: 79,00 ist beim aktuellen M15-Schwung (78,808 -> 82,680)
gar kein Fib-Level, sondern ein Retracement von 95 %. Die naechsten echten
Marken sind 80,29 (61,8 %) und 79,64 (78,6 %). Der kalibrierte Kegel legt 79,00
in allen drei Horizonten ausserhalb des 80-%-Bandes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
3dc56e8571 |
breakout_k mit vollem Live-Gate-Stack gemessen
Nachgeholt, was in der Vollpruefung offen blieb: die ungegatete Messung zeigte k=0,5/0,8/1,0 besser als den Live-Wert 0,3 - aber ohne min_conf, HTF-Filter und Entry-Raum. backtest_breakout_gated.py schliesst die Luecke mit den ECHTEN Methoden (_build, _confirm_breakout-Mechanik, _room_gate mit kausalen M5-Pivots). k=0,0 H1 -0,173/-193 H2 +0,003/ +7 k=0,2 H1 -0,185/-149 H2 -0,012/ -16 k=0,3 H1 -0,160/-122 H2 -0,036/ -47 (LIVE) k=0,5 H1 -0,127/ -85 H2 -0,041/ -47 k=0,8 H1 -0,101/ -54 H2 -0,012/ -11 k=1,0 H1 -0,096/ -45 H2 -0,016/ -12 Bestaetigt: k=0,5/0,8/1,0 schlagen 0,3 in BEIDEN Haelften, die Nachbarn halten mit, und die OR verbessert sich in H1 monoton - also nicht nur Handelsvermeidung. Die vorab fixierte Regel ist erfuellt. TROTZDEM keine Umstellung empfohlen, und der Grund ist kein Messfehler sondern eine Zweckfrage: alle Werte bleiben negativ (PF 0,70-1,01), das Gate begrenzt Schaden statt Edge zu erzeugen; der Auto-Signal-Pfad ist ohnehin aus, das Signal ist ein Vorschlag fuer den Menschen, und dessen gemessener Vorteil entstand auf der k=0,3-Population; k=0,8 kuerzt die Empfehlungen um ~39 % und treibt den WARTEN-Anteil weiter hoch, der mit 93 % ohnehin im Fokus steht. Zwei benannte Abweichungen der Simulation: - _confirm_breakout misst seinen Timeout mit time.time() gegen 3600 s. Im Bar-Loop vergeht keine Wall-Clock-Zeit, der Timeout wuerde nie feuern. 3600 s sind auf M5 exakt 12 Bars, so wird gezaehlt. Merke: jede time.time()-Messung im Live-Code ist in einer Bar-Simulation stumm. - hour=None, weil die EIA-Pruefung in _build ueber datetime.now(_BERLIN) laeuft - mit Bar-Stunde wuerde ein Lauf am Mittwoch 15:30-16:30 alle Bars blocken. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
80a5be7fe5 |
Vollpruefung aller 87 Skripte + Nachrechnung der verworfenen Modelle
Phase 1 - Lauffaehigkeit: 87 von 87 Skripten laufen fehlerfrei (8000 Bars, Timeout 900 s). Kein Defekt durch die heutigen wave_rec-Aenderungen. Werkzeug: run_all_backtests.py, probiert die uneinheitlichen Aufruf-Signaturen adaptiv durch (Bar-Zahl / TF+Bars / zwei TFs+Bars). Phase 2a - breakout_k: die dokumentierte Begruendung REPRODUZIERT NICHT. k=0,3 war mit dem LEGACY_BE10-Exit (Breakeven 1,0) validiert. Erstmals mit dem kanonischen Exit nachgerechnet (backtest_breakout_canon.py, echte _confirm_breakout-Mechanik, 80k M5, 2 Halbjahre, Echtkosten): k=0,0 H1 -0,180/-569 H2 -0,054/-250 k=0,3 H1 -0,170/-356 H2 -0,069/-217 (LIVE) k=0,5 H1 -0,142/-262 H2 -0,074/-208 k=0,8 H1 -0,112/-166 H2 -0,032/ -73 k=1,0 H1 -0,101/-130 H2 -0,004/ -8 k=0,5/0,8/1,0 schlagen den Live-Wert in BEIDEN Haelften (bis +226/+209 SR). TROTZDEM keine Aenderung empfohlen: (a) alle Werte negativ (PF 0,70-0,99), es ist eine Wahl zwischen Verlusten; (b) Optimum lag am Rand -> Gegenprobe bis k=3,0 zeigt kein sauberes Optimum (H2: -8 -> -17 -> -20 -> -19); (c) gemessen wurde das UNGEGATETE Signal, live laufen min_conf/HTF/Entry-Raum davor. Naechster Schritt waere eine gegatete Neumessung, bevor ein Gate angefasst wird, das 63 % der WARTEN erzeugt. Phase 2b - verworfene Modelle bei vollen Bars: ALLE bleiben verworfen. 14 Klassen (ORB, Doppeltop, Volume Profile, Liquidity Sweeps, Konsolidierung, Handbuch-Level, Marktstruktur, Momentum, Inter-Market, Chop-Gate, Reversal-Lockout, S/R-Close-Signal, MACD/ADX/RSI, HTF-Winkel) - keine kippt ins Positive. Bei ~14 Tests waere bei 5 % Fehlalarmquote ein falsch-positives Ergebnis zu erwarten gewesen; es gab keins. Regel vorab fixiert. Kein Freibrief fuer regelmaessiges Nachrechnen - die Begruendung gegen woechentliche Laeufe steht unveraendert. Anlass war die einmalige Signalaenderung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
9e6e81dd34 |
Backtest-Audit: alle 87 Skripte geprueft
Lauffaehigkeit in Ordnung: alle 87 kompilieren, 12 repraesentative (alle die
WaveRecommender konstruieren) laufen fehlerfrei. Die heutigen wave_rec-
Aenderungen brechen nichts - der Modul-Default _reversal_enabled=True haelt die
Altmessungen stabil. Drei Skripte nehmen [TF] [N] statt einer Bar-Zahl als
erstes Argument (signal/pullback/htf_filter); mit einer Zahl als TF gibt es
KeyError. Kein Defekt, nur die Signatur beachten.
angle=-Befund: 11 Skripte, NICHT 26.
Methodik-Fehler bei mir selbst, korrigiert: die erste Pruefung per Regex
(_build\([^)]*angle\s*=) meldete 26 Treffer - die Zeichenklasse [^)]* bricht an
der ersten Klammer ab, sodass Aufrufe wie
w._build(..., htf_trend=m30s(T[i]), angle=ang) faelschlich als "ohne Winkel"
galten. Die AST-Pruefung ergibt 11 echte Faelle und erkennt zusaetzlich
positional uebergebene angle-Argumente. Regex ist fuer Aufruf-Analysen das
falsche Werkzeug.
Wirkung, gemessen ueber 37.577 M5-Bars:
mit Reversal ohne Reversal (live seit heute)
Signal weicht ab 19,1 % 1,1 %
Konfidenz-Differenz +7,7 -4,4
ueber dem 55%-Gate 79,4->90,6 % 79,4->78,5 %
Das Reversal-Abschalten von heute hat die Luecke nebenbei fast geschlossen.
Solange das Reversal aktiv war, sahen die 11 Skripte eine Signal-Population,
die sich in jedem fuenften Bar unterschied - das betrifft den Grossteil der
Projekt-Historie. Ab jetzt sind sie naeherungsweise gueltig.
Bewusst NICHT getan: die 11 Skripte "repariert". Ein angle= zu ergaenzen aendert
ihre Zahlen - das waere laut Migrations-Regel keine Refaktorierung, sondern eine
Neumessung. Sie bleiben unveraendert und reproduzierbar.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
81c4c195da |
Auto-Signal nach dem Reversal-Abschalten gemessen — immer noch nicht tragfaehig
Frage: liefert der Auto-Signal-Entry mit den heutigen Aenderungen positive Ergebnisse? Antwort: nein, aber deutlich naeher dran. LIVE-Konfiguration (Reversal aus, Winkel modelliert), conf>=75: H1 OR -0,047 PF 0,94 n=678 H2 OR +0,120 PF 1,17 n=710 H1 bleibt negativ -> 2-Stichproben-Regel weiterhin NICHT erfuellt. Kein Konfidenz-Schwellwert rettet das (55: -0,103 - 65: -0,111 - 75: -0,047). Das Reversal-Abschalten wirkt aber konsistent. Delta OR: conf 55 +0,015 / +0,099 conf 65 +0,001 / +0,047 conf 75 +0,099 / +0,087 An der Live-Schwelle verbessern sich BEIDE Haelften um ~+0,09; H1 geht von -0,145 auf -0,047, PF von 0,82 auf 0,94. Erste Bestaetigung der gestrigen Entscheidung auf dem GESAMTEN Signal statt nur dem isolierten Trigger. DABEI GEFUNDEN - die Messung vom 30.07. war strukturell unvollstaendig: backtest_auto_signal.py ruft _build OHNE angle= auf. Der Default 90,0 macht ad = 0, damit konnte dort weder der Reversal-Zweig feuern noch der Winkel-Konfidenzterm (+/-15 Punkte) greifen - obwohl die Docstring "echte _build-Logik inkl. Reversal-Zweig" behauptet. Der Winkelterm allein hebt H1 bei conf 75 von -0,123 auf -0,047. Deployment-Drift Fall 5. Die Originaldatei bleibt unveraendert (ihre Zahlen sind dokumentiert); die live-treue Variante steht als backtest_auto_signal_norev.py daneben und sollte kuenftig die Referenz sein. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
dcdd53b703 |
Winkel-Beschriftung korrigiert (Zahlen unveraendert) + Spiegeltest bestanden
Anlass: "pruefe die Logik im umgekehrten Fall, fallender Kurs". 1) Spiegeltest bestanden. Mit reversal_enabled=false ist das Verhalten ueber die ganze Ueberdehnungs-Spanne exakt symmetrisch (steigend/LONG <-> fallend/SHORT): gleiche Signale, gleiche Konfidenz, gleicher Anti-Ueberdehnungs-Schnitt bei 3,5. 2) Dabei gefunden: die Winkel-Beschriftung war ueberall invertiert. calc_trend_angle liefert 0 Grad = AUFWAERTS ... 180 = ABWAERTS, also ist ad = angle-90 NEGATIV bei steigendem Kurs. Ein LONG in einem steigenden Markt bekam daher "Winkel gegen EMA" (-10), ein LONG in einem fallenden "Winkel bestaetigt" (+5). ABER: backtest_angle.py benutzt DIESELBE verdrehte Beschriftung (a5_dis = a5 < 90-dead fuer LONG heisst "dagegen", ist aber STEIGEND). Der dokumentierte Befund "dafuer/neutral +0,055 vs dagegen +0,025" bedeutet richtig gelesen: LONG bei FALLENDEM Kurzfrist-Winkel (= Pullback) traegt doppelt so gut. Das ist der mehrfach belegte Pullback-Effekt. => Die Gewichtung war von Anfang an NUMERISCH RICHTIG. Nicht umgedreht. Geaendert wurden nur die Reason-Texte und Kommentare. Verifiziert: Konfidenzwerte vorher/nachher identisch (60/70/75 je Richtung). Lehre: der erste Verdacht "systematisch invertierte Logik" war falsch - die Zahlen stimmten, die Sprache log. Bei einer verdrehten Konvention erst pruefen, ob die MESSUNG dieselbe Verdrehung teilt, bevor man den Code "repariert". Beim Reversal war es anders: dort wies die eigenstaendige Messung das Setup unabhaengig von der Beschriftung als negativ aus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1a67944842 |
Reversal-Setup abgeschaltet (User-Entscheidung nach der Messung)
backtest_reversal_angle.py hat den Trigger in JEDER Variante beidhaelftig negativ gemessen (IST -0,122/-0,031 - vorzeichenkorrigiert -0,173/-0,061 - ohne Winkelbedingung -0,099/-0,023). Ausschlag gab aber nicht nur die Zahl: das Setup hebelt ZWEI gemessen POSITIVE Schutzmechanismen aus - die Anti-Ueberdehnung und den M30-Gegen-Trend-Filter (Edge x2). Ein Setup ohne eigenen Edge, das validierte Filter umgeht, ist der unguenstigste Fall. Umsetzung: neuer Schalter [trading] reversal_enabled (Config-Default im Engine false). WICHTIG: der Modul-Default in wave_rec bleibt True - saemtliche Backtests rufen dasselbe _build, ein False-Default haette alle bestehenden Messungen still veraendert. Abgeschaltet wird ausschliesslich im Live-Pfad. Verhaltensaenderung nur im Band |stretch| 3,0-3,5: dort kam vorher ein antizyklisches REV-Signal, jetzt das normale Trendsignal; ab 3,5 greift wie gehabt die Anti-Ueberdehnung. Verifiziert: - 3 Szenarien: ueberkauft+steigend SHORT/WAVE_REV_SHORT -> LONG/WAVE_LONG, ueberverkauft+fallend LONG/WAVE_REV_LONG -> SHORT/WAVE_SHORT, normaler Trend unveraendert - Live nach Neustart: bei 3,18xATR Ueberdehnung jetzt WARTEN/setup=WAVE/ reversal=None statt REV_SHORT; Log "Reversal-Setup AUS" - measurement_reminder CONFIG_DEPS ergaenzt, 11 Werte alle korrekt Die Winkelbedingung wurde bewusst NICHT vorzeichenkorrigiert - die korrigierte Variante misst sich schlechter. Die irrefuehrenden Kommentare sind jetzt als solche markiert. Bounce-Anzeige bleibt unveraendert (nur Warn-Kontext). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d052905319 |
Reversal-Winkelbedingung gemessen: alle drei Varianten fallen durch
Anlass: User-Frage "warum SHORT im starken M5-Aufwaertstrend?". Antwort war ein
WAVE_REV_SHORT (3,25xATR ueberdehnt). Beim Nachrechnen kam heraus, dass die
Winkelbedingung gegen ihre eigene Dokumentation laeuft:
calc_trend_angle liefert 0 Grad = starker AUFWAERTStrend, 180 = ABWAERTS.
ad = angle-90 heisst also: ad<0 = STEIGEND. Der Code triggert
stretch>=+3.0 and ad<=-2 -> SHORT, kommentiert als "Winkel ab" - feuert also bei
ueberkauft UND WEITER STEIGENDEM Winkel, waehrend CLAUDE.md "Einstieg IN
Winkel-Richtung" beschreibt. Dasselbe Vorzeichen im Konfidenz-Block: ein SHORT
bekommt "Winkel bestaetigt" (+5), waehrend der Kurs steigt. Mit synthetischen
Reihen direkt nachgestellt.
Erklaert zwei dokumentierte Befunde: ~50 % Richtungstreffer der Bounce-Anzeige
und "blutet in starken Trends".
Statt das Vorzeichen blind zu drehen (alle Messungen beruhen auf dem
IST-Verhalten): backtest_reversal_angle.py, 80k M5, kanonischer Exit,
Echtkosten, 2 Halbjahre, drei Varianten.
IST -0,122 / -0,031 PF 0,79/0,94 n=1100/1615
KORRIGIERT -0,173 / -0,061 PF 0,68/0,89 n= 106/ 163
KONTROLLE -0,099 / -0,023 PF 0,82/0,96 n=1153/1693
(a) Die Vorzeichenkorrektur ist SCHLECHTER - gut, dass sie nicht blind eingebaut
wurde. Sie feuert zudem kaum, weil bei 3xATR Ueberdehnung die 14-Bar-
Regression fast immer noch steigt.
(b) Die Kontrolle OHNE Winkel ist die beste der drei - die Winkelbedingung
entfernt Trades, die im Schnitt besser waren als die behaltenen.
(c) Der Trigger ist in jeder Variante beidhaelftig negativ.
Gemessen wurde der ROHE Trigger ohne Konfidenz-/Raum-Gate; der Legacy-Recheck
der gegateten Variante kam auf ~Breakeven (PF 0,93/1,06), dieselbe Richtung.
Keine Messung stuetzt die dokumentierten "+0,185 / PF 1,35" mehr.
Noch KEINE Strategieaenderung - das Abschalten ist eine User-Entscheidung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
94fbde1dba |
News-Sentiment war gesaettigt — Beweismengen-Gewichtung eingebaut
Anlass: Frage nach X-Anbindung fuer den Copiloten. Vorher geprueft, ob der vorhandene Textstrom ueberhaupt traegt. Er trug nichts, weil der Score kaputt war. calc_news_sentiment bildete ein REINES VERHAELTNIS (bull-bear)/total, ohne Bezug zur Beweismenge. Eine einzige bullische Schlagzeile bei null baerischen ergab +1,00. Diagnose: - 173 von 173 Log-Eintraegen auf +/-1,00 gesaettigt (100 %) - in 100 % der Faelle eine Seite exakt 0 - Median-Beweismenge nur 2,8 gewichtete Headlines - ueber die DB (54.548 Zeilen): 63,9 % auf exakt +1,00 Real am 03.08.: +1,00 waehrend WTI -5,9 % stand. Der Wert trug ein Bit und loeste im Entry-Check dauerhaft falsche "News-Konflikt"-Warnungen aus. Die Keyword-Listen sind NICHT die Ursache (56/48, keine Ueberschneidung). Fix: Shrinkage score = raw * total/(total+4,0). Die 4,0 ist begruendet, nicht optimiert: bei der realen Median-Beweismenge 2,8 bleibt eine einseitige 3-Headline-Lage unter der 0,5-Warnschwelle, ~10 Headlines ergeben 0,71. Zusaetzlich raw_score und evidence im Rueckgabewert, damit unterscheidbar wird ob "ausgewogene Lage" oder "kaum Daten". Leer-Fall liefert dieselben Felder. 6 Szenarien getestet, live verifiziert: bei identischer Beweislage (bull=1.8, bear=0.0) +1,00 -> +0,31. EHRLICH: das repariert die Kalibrierung, nicht die Aussagekraft. Parallel gemessen (Forward-Return 120 min, 38.213 Paare, 84 Tage, 2 Haelften, gegen die Regime-Drift gelesen): der stark-bullische Bucket liegt in BEIDEN Haelften bei null bis negativ, der baerische kippt das Vorzeichen. News-Sentiment ist nicht robust praediktiv. Bleibt Kontext-Chip ohne Verdict-Stimme. Methodik-Falle dokumentiert: der erste Messlauf nutzte candles_m1 (nur ~14 Tage) -> bisect lieferte fuer aeltere Zeitstempel denselben Randwert, alle Forward-Returns exakt 0,0000. Erst der Lauf mit MT5-M5-Bars plus Deckungspruefung war gueltig. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fe7a1acb97 |
Kurslueckenerkennung: zwei Fehler behoben
User-Meldung "die Kurslueckenerkennung funktioniert nicht richtig". Zwei Fehler
gefunden:
1) Die groesste Luecke des Jahres wurde um 3 Cent verfehlt. Die Definition
verlangte ein lueckenloses Vakuum zwischen den TAGESSPANNEN. Am Wochenende
31.07.->03.08. fiel WTI von Schluss 86,33 auf Eroeffnung 79,76 = -6,57 $ -
unsichtbar, weil Montags Hoch (81,67) das Freitags-Tief (81,64) um 0,03 $
ueberlappte. In einem 24/5-Markt ueberlappen die Tagesspannen fast immer;
die strenge Regel fand im ganzen Jahr nur 5 Gaps.
2) Alle Gap-Datumsangaben waren einen Tag zu frueh: int(b["time"]) minus
_BROKER_OFFSET_S zog 3 h von einer Bar-Zeit ab, die MT5 bereits als naive
Broker-Zeit liefert. Die gemeldete Luecke "2026-07-26" war real der 27.07.
Am Jahreswechsel haette es zusaetzlich den year-Filter verschoben.
Fix: zwei getrennte Gap-Begriffe (kind).
- vacuum = alte strenge Definition. NUR diese speisen zone_lines() ->
_sr_levels -> Wellen-Konfidenz, denn nur auf ihnen wurde
gemessen (backtest_gaps.py). Strategie-Eingang bitgenau
unveraendert: zone_lines() liefert vorher wie nachher [88.288].
- close_open = Schluss->Eroeffnung, das was ein Mensch "Kurslucke" nennt.
REINE ANZEIGE, ab 0,50 $, fuellt auch am selben Tag.
Live: 4 offene Luecken statt 1 (1 Vakuum + 3 Eroeffnungsluecken), darunter
endlich die -6,57-$-Wochenendluecke mit Fill bei 86,33. Frontend kennzeichnet
beide Arten mit Tooltip. v=133.
Bewusst NICHT getan: close_open in die Konfidenz einspeisen - das waere ein
ungemessener Strategie-Eingriff, und der vorhandene Befund beruht auf der
Vakuum-Definition.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5f94917014 |
Kanal-Pullback ueber alle Zeitebenen gemessen — 24/24 negativ
Anlass: User-Beobachtung im M5-Chart "der Kurs folgt dem Marktstrukturkanal und bricht die untere Linie nicht — koennen wir das nutzen?". Die vorhandene Messung (backtest_structure.py, 20.07.) lief NUR auf M30; M5 war ungetestet. Neues Skript backtest_structure_tf.py — bewusst mit dem KANONISCHEN Live-Exit (exit_model.LIVE: Trail 1,0 + Time-Stop + TP) statt der Exit-Kopie der alten Datei (Trail 1,5, kein Time-Stop). Die alte Datei bleibt unveraendert, weil die Migrations-Regel eine Umstellung nur bei identischen Zahlen erlaubt. Getestet: M5/M15/M30 x zwei Lesarten des M5-Kanals (60 Bars = 5 h "was man im Chart sieht" und 360 Bars = 30 h zeitgleich zu M30) x drei Regel-Varianten, 80k Bars je Zeitebene, 2 Haelften, Echtkosten. Ergebnis: 24 Zellen, ALLE negativ, PF 0,66-0,99. - Trefferquote 37-43 % ueber 1200-2400 Beruehrungen je Haelfte: der Kanalrand haelt in WENIGER als der Haelfte der Faelle. Die im Chart sichtbaren "Halter" sind Selektion. - M5 ist die SCHLECHTESTE Zeitebene (-0,201 vs -0,103 auf M30). - Keine Parameterfrage: 60-Bar- und 360-Bar-Kanal liefern identische Zahlen. Legacy-Recheck-Bonus: die M30-Zeile reproduziert den Befund vom 20.07. (-0,103/-0,019 gegen damals -0,05...-0,11) — der alte Schluss war NICHT durch das abweichende Exit-Modell verzerrt. Mechanismus: hinter einer Regressionslinie liegt nichts — keine Order, kein Pivot. Darin liegt der Unterschied zu P(break) auf einem echten S/R-Level. 19. verworfener Signal-Eingriff. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
00c78201fa |
KI-Copilot: zwei Prompt-Fehler behoben + kalibrierte Groessen ergaenzt
Diagnose zur Frage "Bias fast immer neutral": es ist NICHT der Prompt, es ist
der Provider. Bruch exakt am 20.07. (DeepSeek-Wechsel) - bis 19.07. war der
Copilot zu 42-90 % gerichtet, ab 21.07. nur noch zu 1,5-9,3 %. Der Prompt war
unveraendert. Und er hedged aus KORREKTER Schlussfolgerung: ~90 % WARTEN-Signal,
negativer Track-Record, plus die Prompt-Anweisung, genau dann NEUTRAL zu sagen.
Gemessen, ob mehr Meinung ueberhaupt Wert haette: KI-LONG n=286 +0,29 $ / 76 %
Treffer, KI-SHORT n=93 -0,02 $ / 55 %. ABER die 286 sind 20 Episoden an 5 Tagen
(Minutentakt-Logger), die 93 sind 16 Episoden -> effektiv n~20 gegen n~16, ein
Regime. Kein Beleg. Deshalb BEWUSST nicht am Prompt gedreht, um Meinung zu
erzwingen; Verdict-Gewicht unveraendert.
Zwei echte Prompt-Fehler behoben (Korrektheit, keine Meinungsmache):
- _SYS beschrieb das Wellen-Signal als "ATR-ZigZag" - es ist EMA12 vs EMA50
- _SYS nannte "TradersUnion-Tachos" als Input - TU ist seit 19.07. raus
Kalibrierte Groessen ergaenzt: _tool_market gab dem Copiloten NUR Wellen-Signal
und Session. Neu: p_break_target / p_break_stop (AUC 0,65 bzw. 0,68-0,72) und
cone (80%-Baender mit der REAL gemessenen Abdeckung 77 %), plus Lese-Anleitung
im Prompt (45-55 % explizit als Muenzwurf markiert).
Zwei Fallen an Live-Daten korrigiert: p_break steht bereits in PROZENT (die
zuerst gebaute x100-Umrechnung haette 300 erzeugt), und die Engine-Felder plus
die engine-Referenz im Agent existierten gar nicht - der Fail-safe haette still
nichts geliefert. Snapshot weist die Werte jetzt nur zu, rechnet sie nicht neu.
DeepSeek max_tokens 4000 -> 8000: das JSON brach regelmaessig mitten im Text ab
("Unterminated string"), real 2x in ~14 Zyklen = ~14 % stille Ausfaelle.
Kerzen/Muster bewusst NICHT eingespeist - die Lehrbuch-Lesart ist hier gemessen
invertiert (langer Koerper im Trend -0,132/-0,042; 2x Volumen -0,117/-0,204;
Muster-Kursziel trifft nur 13-38 %). Roh eingespeist wuerden sie schaden.
Verifiziert: Stub-Test von _tool_market (Werte unveraendert durchgereicht, nur
80%-Baender, ohne Engine kein Absturz); Prozess juenger als beide Dateien.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
20cd04caa7 |
Review-Durchlauf: Telemetrie-Epochen, doppeltes Verdict, Doku-Korrektur
Erster vollstaendiger Durchlauf von docs/review-prompt.md. KEINE Strategie-Aenderung - alles Telemetrie, Doku und toter Code. 1) analyze_divergence.py kannte keine Epochen und war damit selbst driftanfaellig. D0 mischte Vorhersagen des alten und des am 31.07. nachtrainierten P(break)-Modells und meldete dessen Fehlkalibrierung als aktuellen Alarm (das neue Modell hat n=0, Markt seit Fr zu). B las die Prae-Migrations-NULLs von block_reason als blinden Fleck. C druckte bei 0 Zeilen ein "OK", obwohl es fehlende Daten waren. Neu: _EPOCHS + _clamp(). 2) Konsens-Pfeil AR;K: der MQL5-Export rechnete im ~5-s-Takt ein komplettes zweites _verdict(), obwohl der Indikator die Zeile seit v1.33 per Default verwirft. Neu [trading] export_consensus_arrow (Default false). Verifiziert ueber die exportierte CSV: AR;K weg, AR;L und AR;S bleiben. 3) /api/autosqueeze loggt jetzt die Herkunft ([WEB] ...) wie /api/autosignal. Vorher war ein Zustandswechsel nicht als Nutzeraktion belegbar. 4) CLAUDE.md: die Reversal-Kennzahl "OR +0,185 / PF 1,35 / 70 %" stand unkorrigiert an der Fundstelle, die Widerlegung 2000 Zeilen weiter im Legacy-Recheck. Korrektur an die Fundstelle geholt. 5) core/notify.py: zwei tote "import datetime" entfernt (beide Funktionen nutzen _time), funktional nachgetestet. Geprueft und sauber: 0 fehlende Frontend-IDs von 86, nur 2 Config-Schluessel ohne Leser (beide dokumentiert dormant), Snapshot-Median 13 ms und alle DB-Abfragen <13 ms -> keine Performance-Massnahme, 124 Datei- und 83 Funktionsreferenzen in CLAUDE.md stimmen. Zwischenverdacht zurueckgezogen: "block_reason erklaert nur 33 % der WARTEN" war ein Migrations-Artefakt; seit 01.08. 100 % Abdeckung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3124fe5b4f |
Doku: wiederverwendbarer Review-Prompt fuer die Gesamtpruefung
docs/review-prompt.md — projektspezifisch statt generisch. Die gefaehrlichsten Fehler hier sind nicht Syntax, sondern "Messung != Betrieb", deshalb ist Deployment-Drift ein eigener Durchgang. Enthaelt die harten Grenzen (Secrets, DB-Backup, eine Instanz, keine Strategieaenderung ohne 2-Stichproben-Backtest, dokumentierte User- Entscheidungen nicht anfassen) und als Pruefliste genau die Fehlermuster, die in diesem Projekt real aufgetreten sind: stille catch-Bloecke, zu weite Plausibilitaetsfenster, aus stalen Eingaben abgeleitete Werte, zwei Quellen fuer denselben Zustand, null-unsichere DOM-Zugriffe, Ticket-Wechsel-Races. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |