9887e3d5da96e3262e587104f9ca1181af58af7c
100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9887e3d5da |
pytest-Suite: 13 Tests in ~1 s, mutations-geprueft
Im Projekt sind ueber Monate dutzende Szenario-Tests entstanden ("mit 10
Szenarien getestet", "mit 18 synthetischen Szenarien") — alle als
Wegwerf-Skripte, keiner lief je ein zweites Mal. Bei einem System, das man vor
jeder Aenderung neu starten und live verifizieren muss, ist das der teuerste
Teil der Schleife.
Erfasst sind die beiden juengsten Pfade:
· _check_pending_fill (6 Faelle) — u.a. "fremde Position NICHT taggen" und
"derselbe Fill zaehlt nur einmal"
· Selbst-Kalibrierung (7 Faelle) — Episoden-Dedup, WARTEN re-armt, Auswertung
in beide Richtungen inkl. Broker-Offset, fehlende Bar bleibt offen,
Aggregation
Drei harte Regeln in tests/conftest.py: keine Live-DB (frische Temp-Datei je
Test), kein MT5 / kein laufender Server (gestubbt), kein Netz. Das Schema legen
die ECHTEN Konstruktoren an — HistoryLogger UND CandleLogger, denn candles_m1
gehoert nicht zum History-Schema. Ein handgebautes Test-Schema wuerde
irgendwann vom Produktivstand abweichen.
Warum Temp-DB statt Kopie der Live-DB: am 06.08. haben echte candles_m1-Zeilen
in einem vermeintlich leeren Fenster einen Test verfaelscht — zweimal sah es
nach einem Code-Fehler aus, es waren Testfehler.
MUTATIONS-GEPRUEFT, weil eine Suite die immer gruen ist wertlos waere: eine
absichtlich eingebaute "fremde Position wird doch getaggt"-Regression wird
gefangen. Nebenbefund: der Fill-Dedup ist DOPPELT gesichert (_pending_tagged
und der pop aus _pending_tickets) — nur eines zu entfernen faellt nicht auf,
beides zusammen bricht sofort zwei Tests. Gewollte Redundanz, kein
ungetesteter Zweig.
tests_rec_outcomes.py (Wegwerf-Fassung von gestern) und die verwaiste
test_pbreak.db entfernt.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
79f3e8efe1 |
Konfidenzintervalle (scipy-Bootstrap) — und sie korrigieren den Befund vom 06.08.
backtest_cost_gate.ci95(): 95-%-Bootstrap-KI des Mittelwerts (Perzentil, 2000 Resamples, random_state fest -> reproduzierbar, ab n>=20). kennzahlen() liefert es als neuen Schluessel `ci` — rein additiv, alle 11 Aufrufer lesen weiter nur n/wr/oer/sr/pf, keine dokumentierte Zahl verschiebt sich (geprueft). Sofortiger Ertrag: der erste Lauf relativiert das `3 von 7 tragen` vom 06.08. Auf der entscheidenden Spalte C (Beruehrungs-Fill): KONTROLLE Squeeze H1 [+0,037…+0,229] H2 [+0,225…+0,366] PDH / PDL H1 [-0,032…+0,544]⚠ H2 [+0,155…+0,764] Equal H/L H1 [+0,001…+0,425] H2 [-0,035…+0,356]⚠ Asian Range H1 [-0,067…+0,357]⚠ H2 [-0,060…+0,332]⚠ Nur der Squeeze hat in BEIDEN Haelften ein Intervall klar ueber null. Bei Asian Range enthalten beide die Null — als Ueberlebender war das zu stark formuliert. Formulierung auf `1 gesichert, 2 unklar` korrigiert. Zwei verschiedene Fragen, beide noetig: die 2-Stichproben-Regel prueft die Stabilitaet des VORZEICHENS ueber Regime, das KI die Unterscheidbarkeit vom RAUSCHEN innerhalb einer Stichprobe. Hier war Ersteres erfuellt, Letzteres nicht. Ein KI, das die Null enthaelt, heisst nicht widerlegt, sondern nicht belegt — und zwei gleichgerichtete Haelften sind zusammen mehr Evidenz als jede fuer sich. Grenze dokumentiert: der Bootstrap unterstellt unabhaengige Ziehungen. Fuer die sequentielle Sim mit EINEM Slot passt das; fuer ueberlappende Fenster (analyze_hl_funding.py) ist er zu optimistisch — dort braeuchte es einen Block-Bootstrap. ci95 ist dafuer ausdruecklich NICHT gedacht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e69907edbe |
pyflakes eingebunden — zwei echte Fehler in core/trader.py gefunden
Auf die Frage nach einem Lint-Modul: pyflakes installiert und als Stufe A2 in tools/check_nfalle.py eingebunden. py_compile prueft nur die SYNTAX; ein Tippfehler in einem NAMEN ist syntaktisch einwandfrei — und dieses Projekt hat sehr viele breite except-Exception-Bloecke, in denen ein NameError unsichtbar bleibt. Beim ERSTEN Lauf zwei echte Fehler, beide in core/trader.py, beide nutzten log. (den Namen gibt es dort nicht, nur log_trade/log_hist): · _broker_offset_s(): der NameError lief in das except-pass UND nahm die darunter stehende Zuweisung self._boff = int(off) mit -> ein echter Broker-Zeitzonen-Wechsel waere nie uebernommen worden, dauerhaft und lautlos. Ausgerechnet der Zweig, der als Deployment-Drift Fall 4 gebaut wurde (falscher Offset -> Time-Stop-Alter negativ). · modify_sltp(): steht NICHT in einem try -> der Fehler lief bis in /api/sltp. Der Broker hatte SL/TP bereits geaendert, der User bekam trotzdem eine Fehlermeldung, und set_sltp kam nie bis trail.deactivate() — das Trailing blieb an und haette die Handeingabe zurueckgezogen. Seit dem Initial-Commit drin. Beide behoben (log_trade). Zusaetzlich die Annotation 'HistoryLogger | None' ueber if TYPE_CHECKING sauber importiert (String-Annotation, kein Laufzeit-Import, kein Zirkel). Projektweit jetzt 0 undefinierte Namen. Schweregrad-Trennung ist Absicht: nur undefined name / syntax error werden gemeldet, die ~105 kosmetischen Hinweise unterdrueckt. Auch 'redefinition of unused' bleibt draussen — es trifft das legitime Muster hook = None + bedingtes def hook (in zwei Backtests geprueft, beide korrekt). Eine Pruefung mit Dauer-Treffern wird ignoriert, und mit ihr die eine echte. Backtest-Dateien nicht angefasst (Zahlen). Neustart verifiziert, Log sauber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
394786b312 |
CLAUDE.md: die \n-Falle als Dauerregel festgehalten
Nachtrag zum Scanner-Commit — die Doku-Ergaenzung war dort durchgefallen, weil mein eigenes Heredoc an den deutschen Anfuehrungszeichen scheiterte. Damit ist die Regel dreimal an EINEM Tag belegt: engine.py, measurement_reminder.py und das Dokumentieren der Regel selbst. Regel jetzt in CLAUDE.md: mehrzeilige Strings mit \n oder Text mit deutschen Anfuehrungszeichen nie per Heredoc schreiben, sondern ueber den Edit-Weg. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
5a89544a27 |
tools/check_nfalle.py: Scan gegen die \n-Falle — Projekt ist sauber
Auftrag "ueberpruefe alle dateien auf \n-Falle". Die Falle: ueber ein
Shell-Heredoc geschriebener Code macht aus einem gemeinten \n einen ECHTEN
Zeilenumbruch mitten im String-Literal. Heute zweimal passiert (Telegram-Text
in engine.py, Reminder-Eintrag in measurement_reminder.py).
Der Scan prueft in beide Richtungen:
A) kompiliert alle .py (161 Dateien) — sauber
B) JS: unabgeschlossene String-Literale — app.js sauber
C) UMGEKEHRT: literales \n als sichtbarer Text in HTML-title= und Markdown
— alle sauber
D) Signatur der beiden heutigen Faelle (Zeile endet offen, naechste besteht
nur aus einem Quote) — keine
⚠ Fehlalarm im Scanner selbst gefunden und behoben: Quotes zu ZAEHLEN meldet
'"' als offenes Literal (gueltiges JS mit einem Anfuehrungszeichen darin, real
in app.js). Der Scan verfolgt jetzt zeichenweise den AKTIVEN Quote-Typ.
Die betroffene app.js-Stelle trotzdem aufgeraeumt: schliessendes
Anfuehrungszeichen jetzt als U+201C statt ueber eine Konkatenation mit '"'.
Regel in CLAUDE.md ergaenzt: mehrzeilige Strings mit \n nicht per Heredoc
schreiben, sondern ueber den Edit-Weg.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
b858ae9aa2 |
Liq-Trend und die uebrigen offenen Modul-Fragen fuer die 25.000er-Messung notiert
Auf die Frage nach Liq-Trend: es bleibt vorerst mit Gewicht 0,5 drin, kommt aber
mit einer ausdruecklichen Begruendung auf die Liste der Verdict-Modul-Messung
(measurement_reminder.py + CLAUDE.md), statt jetzt ohne Datenbasis gehandelt zu
werden.
Offene Punkte fuer den Lauf:
(a) Liq-Trend (0,5) — +0,20/+0,32 ueber nur 132 Episoden. ⚠ Dieselbe Quelle wie
das am 06.08. entmachtete Orderbuch-Modul, und HL-Preisdaten laufen gemessen
hinter Pepperstone her (51 % Treffer nach 6 s). Als einziges verbliebenes
HL-Modul mit Stimmrecht zuerst pruefen.
(b) Muster (0,25) — +1,27/+0,67 bei n=88, zu duenn.
(c) H1 (1,5) — nur 19 Episoden, traegt aber 38 % des Nadel-Einflusses;
praediktiv nicht beurteilbar.
(d) Elliott und Orderbuch sind entmachtet, werden aber WEITER geloggt — die
Reihe darf fuer diese Messung nicht abreissen.
Stand 15.591 von 25.000 Verdicts (62 %). Auswertebefehl auf
analyze_verdict_modules.py praezisiert, mit Hinweis auf die Episoden-Bildung.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
4155afb434 |
Widerspruch "stark LONG" bei WARTEN aufgeloest (v=149)
User-Fund: Headline "◌ WARTEN · M30", darunter "stark LONG · 2 von 2
stimmberechtigten fuer LONG (7 ohne Aussage)". Beide Zahlen stimmten, die
Kombination war irrefuehrend. Zwei Ursachen:
(1) Die Headline nannte den Grund nicht. Er stand im Snapshot
(wave_signal.block = min_conf, conf 49 gegen 55 % — die Welle HATTE eine
LONG-Richtung, ihr fehlten sechs Punkte), gerendert wurde er aber nur bei
breakout_pending. ⚠ Meine Luecke vom 06.08.: ich habe die Tages-Verteilung
(#vd-blocks) gebaut und den AKTUELLEN Grund vergessen. Jetzt Mapping fuer
alle neun Gate-Codes an der Headline.
(2) "2 von 2" las sich wie Einstimmigkeit — es waren 2 von 7 sichtbaren
Modulen (H1 1,5 und Liq-Trend 0,5), und die Welle, die als einzige die
Order steuert, war nicht dabei. bias=1,0 ist arithmetisch korrekt, aber die
Basis war winzig. Das Entmachten von Elliott/Orderbuch hat das Problem
nicht erzeugt, aber verschaerft.
Neu: Zeile fuehrt mit der Basis, "stark/leicht" entfaellt solange weniger
als die Haelfte der Module spricht, stumme Welle wird ausdruecklich genannt.
Live gegengerechnet:
"◌ WARTEN · M30 · Konfidenz 49 % < 55 % — Setup zu schwach"
"2 von 7 Modulen sprechen, alle fuer LONG · die Welle ... schweigt"
Reine Anzeige — Gewichte, Gates und Order-Logik unveraendert.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
cf94679022 |
Setup- und Lauf-Zeile aus den Meldungen entfernt (v=148)
Beide .kv-Zeilen samt JS-Zuweisungen (wave-setup, wave-move) raus. Das Setup
steht ohnehin in der Verdict-Headline und den Gruenden, der "Lauf" beschrieb
die Vergangenheit ohne Handlungsbezug.
⚠ Fallstrick beim Entfernen, korrigiert: die Zeile
`const w = d.wave_signal || {}, ws = ...` stand direkt ueber der
Setup-Zuweisung und ist zunaechst mit rausgefallen — `w` wird aber weiter
unten noch achtmal gebraucht (Gruende, Button-Blinken, Close-Alarm,
News-Konflikt). Ein ReferenceError mitten in render() bricht den GESAMTEN
Render ab und friert das Dashboard ein.
Gegenprobe ergaenzt: alle $("id")-Zugriffe der app.js gegen die IDs der
index.html geprueft — 0 verwaiste Referenzen. Klammern-Balance ok,
v=148 ausgeliefert, eine Instanz auf 8000.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
caa937f87d |
Gesamtempfehlung: nur noch Module mit Stimmrecht · Tooltips ueberall (v=147)
· Modul-Chips: neues `used`-Flag in _verdict.add(). used=False = dauerhaft entmachtet (Elliott, Orderbuch — beide heute gemessen ohne Inhalt), das Frontend filtert sie aus. ⚠ Sie bleiben im Snapshot und in verdict_votes: log_verdict_votes speist daraus die Telemetrie und die 25.000-Verdict-Messung braucht die Reihe weiter. Ausgeblendet wird die Anzeige, nicht die Messung. Module mit weight=0 aus SITUATIVER Stille (Welle bei WARTEN, Squeeze ohne Ausbruch) bleiben sichtbar. · #vd-note (Muenzwurf-Hinweistext) entfernt, samt CSS. Die Aussage steht weiter im Karten-Tooltip. · Tooltips auf allen Dashboard-Anzeigen (59 title-Attribute): Karten, Header-Boxen, Trade-Leiste, Anzeige-Elemente. Wo eine Messung existiert, steht sie drin. Gesetzt ueber set_tooltips.py — idempotent, ergaenzt nur fehlende title=. Verifiziert: keine Anzeige mehr ohne Tooltip, keine doppelten IDs, Tag-Balance ok, v=147 ausgeliefert, Elliott/Orderbuch used=False, eine Instanz auf 8000. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
38b493de35 |
signal_pending_entry abgeschaltet (User-Entscheidung)
Der Touchfill-Test hat den Pfad in allen sechs Feldern negativ gezeigt (-0,18 bis -0,48, PF 0,38-0,71) und damit schlechter als der Markt-Einstieg: an einem WANDERNDEN Level faengt eine ruhende Order systematisch die Fehlausbrueche ein (441 statt 328 Fills). ini auf false; der Schluessel lebt nicht in runtime_state.json, die ini greift also direkt. Backup angelegt. Live verifiziert: signal_pending=False, squeeze_pending=True (dort steht die Box still, Test bestanden). Neu im Config-Waechter (14 ueberwachte Werte, validiert = false). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ec6a2c5842 |
SIG-Pending faellt durch: Look-ahead 0,8 R, schlechter als der Markt-Einstieg
Der offene Test aus dem Fill-Befund ist gelaufen (backtest_signal_touchfill.py, 80k M5, voller Live-Gate-Stack, kanonischer Exit, Echtkosten): Konf A) Markt B) Close-Bruch C) BERUEHRUNG (real) >=55 -0,015/-0,172 +0,381/+0,315 -0,392/-0,338 >=65 -0,024/-0,085 +0,367/+0,385 -0,478/-0,471 >=75 -0,148/-0,310 +0,288/+0,136 -0,184/-0,202 C ist in allen sechs Feldern negativ (PF 0,38-0,71). Der Look-ahead-Aufschlag betraegt 0,77-0,85 R — groesser als beim Momentum (0,45) und Squeeze (0,32). ⚠ C ist sogar schlechter als der Markt-Einstieg. Sichtbar am Trade-Zaehler: C hat MEHR Fills als B (441 gegen 328, 659 gegen 455) — die zusaetzlichen sind die Beruehrungen, die zurueckfallen. Eine Order an einem WANDERNDEN Level faengt systematisch die Fehlausbrueche ein. Damit ist die Vorhersage bestaetigt: entscheidend ist nicht "Level statt Markt", sondern ob das Level STILLSTEHT. Squeeze-Box haelt (+0,124/+0,292), _pend und Momentum wandern und fallen durch. Empfehlung dokumentiert: signal_pending_entry = false. Nicht eigenmaechtig umgestellt — Live-Schalter sind User-Entscheidungen, und auto_signal ist ohnehin aus (der Pfad platziert derzeit keine Orders). Migrations-Pruefung ehrlich vermerkt: der Vorher/Nachher-Vergleich war nicht bitgenau (ein Trade in H2), Ursache sind zwischenzeitlich eingetroffene Live-Bars, nicht der Patch — H1 war identisch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
2cdd1ba0e8 |
Hyperliquid geprueft: Orderbuch-Stimme raus, Funding gemessen (traegt nicht),
Kontext in die Meldungen (v=145)
Direkt gegen die HL-API geprueft statt aus dem Code geschlossen.
ANGEBOT: 4 Oel-Maerkte (2 liquide: xyz:CL OI 3,07 Mio, xyz:BRENTOIL 2,25 Mio),
je Markt mark/oracle/funding/open_interest/day_volume + l2Book (20 Level je
Seite). Historie: fundingHistory 5.095 Stundenwerte ueber 7 Monate inkl.
premium. Open Interest hat KEINE Historie -> waere sammelpflichtig.
Netz-Frage geklaert: config sagt testnet (leeres Buch, 0 Bids/0 Asks), aber es
sind zwei Schalter — [hyperliquid] network steuert das Handeln (aus),
[sim] price_network die Daten (mainnet, live bestaetigt).
(1) Mehr Orderbuch-Daten: NEIN. Zweimal unabhaengig gemessen — bookflow_report
0,2-1,0 bp gegen eine ~3-bp-Schwelle und KIPPT; Lead-Lag: Pepperstone
fuehrt, HL trifft nach 6 s zu 51 %.
(2) Modul "Orderbuch" Gewicht 0,5 -> 0. Ueber 2.688 Episoden beidhaelftig
negativ (-0,054/-0,066, 49 % Treffer). Chip bleibt.
(3) analyze_hl_funding.py: Funding/Premium gegen den CFD, 2 Haelften.
⚠ Der erste Lauf meldete mehrere "robuste" Buckets und war FALSCH —
ueberlappende Forward-Fenster (aus n=506 werden ~21 unabhaengige Faelle)
und global gebildete Quintile (Bucket mit der Zeit konfundiert). Dass
Funding- und Premium-Tabelle fast identisch waren, war der dritte Hinweis:
HL rechnet das Funding aus dem Premium. Entueberlappt haelt kein Bucket.
(4) hl_ctx in den Meldungen (#hl-note) als reine Anzeige.
⚠ Zwei Bau-Fallen behoben: der Aufruf erbte den 2-s-Timeout der Waende und
lief still ins Leere (braucht real 7,2 s), und er haette den Trend-Loop
blockiert -> Daemon-Thread wie beim Wirtschaftskalender.
Live verifiziert: hl_ctx befuellt, Orderbuch weight=0 bei erhaltenem Chip,
v=145 ausgeliefert, eine Instanz auf Port 8000.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
874ee16e00 |
Gesamtempfehlung: Selbst-Kalibrierung, voller Ausrichtungs-Split, Block-Gruende,
Elliott entmachtet (v=144)
Vier Verbesserungen, alle aus dem Gemessenen abgeleitet — kein neues Signal.
Ausgangspunkt: die Karte hat genau eine belegte Funktion, das Veto; als Prognose
ist sie ein Muenzwurf (48-51 % ueber 1.071 Episoden).
(1) SELBST-KALIBRIERUNG. Neue Tabelle rec_outcomes: eine Zeile je EPISODE
(Richtungswechsel, nicht je Minute), Auswertung ~alle 5 min gegen candles_m1
nach 30/60 min, Snapshot rec_track, Zeile #vd-selfcal. Gegen 50 % zu lesen.
Warum der groesste Hebel: die Qualitaet war bis heute unsichtbar und musste
auf Nachfrage rueckwirkend gemessen werden. Dasselbe Muster
(pbreak_predictions) hat den Ausfall des P(break)-Modells LIVE aufgedeckt.
Mit 4 Szenarien getestet (tests_rec_outcomes.py). Zwei Fehlschlaege dabei
waren Testfehler, keine Code-Fehler — dokumentiert.
(2) alignment_stats auf die VOLLE Historie (1.216 statt 40 Trades) und
zusaetzlich je Lot. Absolute Euro-Vergleiche sind bei wechselnder
Positionsgroesse ungueltig (Lehre 04.08.). Damit steht die einzige
beidhaelftig robuste Aussage der Karte auf ihrer vollen Stichprobe.
(3) Block-Gruende sichtbar (block_mix -> #vd-blocks): "heute X % ohne Block ·
entry_room … · min_conf …". Bisher nur per DB-Abfrage zu beantworten.
(4) ELLIOTT: Verdict-Gewicht 1,0 -> 0. Gemessen ueber 15.544 Zeilen hatte es mit
1.384 Episoden die groesste Stichprobe der Tabelle und ist darin flach
(-0,075/+0,032, 50 % Treffer) — bei 25,9 % Einfluss auf die Nadel, weil es
in nur 1 % der Zeilen schweigt. Chip bleibt, Stimme entfaellt.
⚠ Folge: die Nadel schlaegt staerker aus (real +0,33 -> +1,00).
⚠ Namenskollision beim Bau gefunden und behoben: die neue Klasse hiess zuerst
.vd-track — so heisst bereits die Schiene der Bias-Nadel; sie waere
ueberschrieben worden. Jetzt .vd-selfcal.
Live verifiziert: alignment je Lot, block_mix (93 von 1381 ohne Block),
rec_outcomes angelegt, Elliott weight=0 bei erhaltenem Chip, v=144 ausgeliefert,
eine Instanz auf Port 8000.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
4f85d2ce75 |
Ausrichtungs-Split ueber die ganze Historie: die Empfehlung ist ein Veto
Bisher stand dazu nur alignment_stats(40). Ueber alle 1.216 geschlossenen Trades, je Lot normiert und in zwei Haelften: MIT Signal n=354 WR 56,5 % +3,22 EUR/Lot (H1 +0,37 / H2 +5,62) GEGEN Signal n= 87 WR 40,2 % -6,60 EUR/Lot (H1 -7,01 / H2 -5,68) OHNE Signal n=775 WR 56,6 % +0,36 EUR/Lot (kippt: -2,68 / +0,76) Die schaerfste Zeile ist MIT gegen OHNE: 56,5 % zu 56,6 %, identisch. Der Empfehlung zu FOLGEN bringt gegenueber "ohne Empfehlung handeln" gemessen nichts. Nur sie zu VERLETZEN kostet — und das robust in beiden Haelften. Damit ist die Rolle praezise: Veto, keine Prognose. Das ist zugleich die einzige Richtungsaussage ueber die Gesamtempfehlung, die den 2-Stichproben-Test besteht. Grenze benannt: gegen hat n=87 und die Zuordnung ist konfundiert (der Mensch waehlt aus, wann er gegen das Signal geht). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7e03e481ca |
Verworfene Setups auf der Ausfuehrungs-Achse — und der Squeeze steht mit auf null
User: "backteste alle verworfenen Signale". Bewusst kein Komplettlauf (der lief am 04.08., 14 Klassen, alle blieben verworfen) — neu ist genau eine Achse, der Einstiegspreis, angewandt mit der heutigen Korrektur (Fill bei BERUEHRUNG statt bei Schluss-Bruch) und nur dort, wo sie greifen kann: stehendes Level + Ausbruchsrichtung. Ergebnis (Variante C, 80k M5, 2 Halbjahre): KONTROLLE Squeeze +0,133/+0,293 (reproduziert touchfill — Pipeline ok) ORB (4 Varianten) faellt durch (bestaetigt 2026-07-17) PDH/PDL +0,246/+0,464 Asian Range +0,142/+0,134 Equal H/L +0,218/+0,170 Alle drei nachbar-robust (11 Zellen, keine kippt). ⚠ Das sind keine drei neuen Signale: PDH/PDL, Asian-Range-Extrem, Equal H/L und die Squeeze-Box sind dasselbe — waagerechtes Level aus frueheren Extremen, gebrochen, ruhende Order, kanonisches Trailing. Deckt sich mit der Kontrolle "beliebige Box" aus dem Multi-Instrument-Lauf. ⚠⚠ Mit der gemessenen Exit-Slippage bleibt fast nichts uebrig. Beim guenstigsten Wert (0,0124 $, Tagfenster): PDH/PDL +0,099/+0,386 haelt, Equal H/L duenn, Asian Range faellt — und der LIVE laufende Auto-Squeeze steht in H1 bei -0,002. Die Edges dieser Familie liegen in derselben Groessenordnung wie die Ausstiegskosten, und die Slippage-Zahl ist eine Untergrenze. Konsequenz: kein neues Setup bauen. Der naechste Hebel ist die Ausfuehrungsqualitaet am EXIT, nicht ein weiteres Einstiegs-Signal. Offen und benannt: Volume-Profile-LVN und die Chartmuster-Nackenlinie qualifizieren sich, wurden aber nicht gemessen (Laufzeit bzw. Detektor). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
45bfc87153 |
Squeeze auf 9 Instrumenten · Momentum neu gemessen · Fill-Annahme korrigiert · UI
Drei Messungen und eine UI-Aenderung, ausgeloest von der Frage, ob das Konzept zu ueberdenken ist. 1) SQUEEZE AUF ANDEREN INSTRUMENTEN (backtest_squeeze_multi.py): 7 von 9 halten alle vier Bedingungen, alle nachbar-robust. Die zwei Durchfaller (Gasoline, USDX) sind exakt die mit Spread >= ATR — der Test scheitert, wo er muss. ⚠ 7 sind nicht 7 unabhaengige Tests (Crude/Brent, Gold/Silber, NAS/GER40 korrelieren), und die Kompression traegt weniger als der Ausbruch selbst (Kontrolle "beliebige Box" ist ueberall positiv). 2) MOMENTUM (backtest_momentum_v2.py): bleibt verworfen. Mit Level-Order sah es nach +0,4 aus — das war Look-ahead. Eine liegende Order fuellt bei der ersten BERUEHRUNG, nicht erst wenn der Bar jenseits des Levels SCHLIESST. Ehrlich gerechnet: -0,04..-0,09 in H1. Struktureller Grund: das Momentum-Level wandert jede Bar mit C[i-N] und ist damit kein Ort, an dem eine Order liegen bleibt. 3) FILL-ANNAHME (backtest_squeeze_touchfill.py): dieselbe Frage fuer den Squeeze. Er haelt (+0,124/+0,292, PF 1,24/1,64) und die Umstellung auf ruhende Orders bleibt richtig (Market -0,158/-0,006). ABER die heute zitierten +0,456/+0,611 sind als Live-Erwartung ~0,32 R zu hoch. Die Beruehrungs-Variante trifft fast genau das original validierte Band +0,14..+0,23. ⚠ OFFEN: derselbe Test fehlt fuer den SIG-Pending-Pfad, der seit 05.08. live ist — und dort ist ein schlechteres Ergebnis zu erwarten, weil das _pend-Level wandert statt stillzustehen. 4) UI (v=143): fester Vorbehalt unter der Headline und "Score" statt nackter Prozentzahl am Ring. Statisches Markup, kein JS. Eigener Fehler dokumentiert: der erste Momentum-Entwurf pruefte nicht, ob das Level als Stop-Order auf der richtigen Marktseite liegt, und lieferte ØR +2,2 — unmoeglich, und genau daran erkennbar. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
64eef14871 |
analyze_signal_live.py: die Richtungsaussage der Empfehlung ist ein Muenzwurf
User-Beobachtung "die Empfehlungen heute waren fast immer gegenlaeufig" — vor einer Konzeptdebatte gemessen, und zwar an den TATSAECHLICH ausgegebenen recommendations-Zeilen (nach allen Live-Gates), nicht im Backtest. 20.365 Zeilen -> 1.071 Episoden (08.05.-06.08.), gegen die Drift der jeweiligen Haelfte gelesen. Trefferquote ueber alle sechs Felder 48,3-51,1 %. Bester Ueberschuss +0,085xATR bei 60 min — unter der B3-Huerde (0,1) und weit unter den realen M5-Kosten (0,265). Auf 120 min ist H2 mit -0,259 klar negativ. Der Anlasstag war typisch, kein Ausreisser: 8 von 10 Episoden auf 30 min gegenlaeufig; die fuenf Vormittags-SHORTs liefen gegen einen Tag, der von 75,5 auf 78 stieg. Wichtige Einordnung, damit daraus nicht der falsche Schluss gezogen wird: dasselbe Signal ist mit ruhender Order am Bestaetigungs-Level in beiden Haelften klar positiv (+0,35/+0,32, PF 2,2) und am Markt negativ. Der Ertrag kommt aus Einstiegspreis und Exit-Asymmetrie, nicht aus der Trefferquote — wie beim Squeeze (43-46 % Treffer, trotzdem positiv). Die Headline ist damit kein Kursurteil, sondern ein Ausloeser fuer eine Level-Order. Die Suche nach einem besseren Richtungssignal folgt daraus NICHT — die ist mit 23 verworfenen Eingriffen beantwortet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
58af6eba43 |
Automatischen S/R-Close abgeschaltet (User-Vorgabe)
auto_sr_close = false in der ini UND in runtime_state.json — beide Stellen noetig, weil die Runtime-Datei die ini beim Start ueberschreibt (genau die Falle, durch die auto_signal am 31.07. unbemerkt weiterlief). ⚠ Das ist eine Abweichung von der Messung, kein Nachvollzug einer: mit dem am 31.07. nachtrainierten P(break)-Modell schlaegt der gegatete S/R-Close die Trailing-Baseline in BEIDEN Haelften (Schwelle 0,35: H1 +357 R, H2 +1418 R gegen die Baseline). Nicht zu verwechseln mit dem PAUSCHALEN S/R-Close, der 2x verworfen wurde — das P(break)-Gate ist der Unterschied. Abgeschaltet ist nur die Ausfuehrung. Der App-Hinweis, die P(break)-Chart- Linien, der Copilot-Kontext und das Prognose-Tracking laufen weiter (_sr_close_hint wird in snapshot() unabhaengig vom Schalter berechnet). Schutz weiterhin: Broker-SL 2xATR, Trailing, Time-Stop. Neu im Config-Waechter (validiert = true), damit die Abweichung sichtbar bleibt; er meldet sie jetzt korrekt. Backups der ini und runtime_state angelegt. Live verifiziert: snapshot.auto_sr_close=False, Log "S/R-Close=aus", eine Instanz auf Port 8000. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
217981ccf5 |
analyze_slippage_holdtime.py: die offene Zahl gemessen — M1 ist entschieden
Der M1-Squeeze hing an der Exit-Slippage bei kurzer Haltedauer. Die bisher zitierten "Median 0,017 / Ø 0,234" waren die Statistik NUR ueber die Ausreisser — analyze_execution.py zaehlt ausschliesslich Faelle, die schlechter als der Initial-SL endeten. Sauber ist E[Slippage] >= P(gap>0) x Ø(gap|gap>0). Unkontaminiert, weil das Trailing den gap nur negativer machen kann: ein positiver gap ist zwingend Slippage. Ueber 317 SL-Closes, <30 min: alle Stunden 0,0370 $ (0-15 min allein 0,0470) nur 10-17 Uhr 0,0124 $ (0-15 min allein 0,0058) Der Schwanz sitzt ausserhalb von 10-17 — bei kurzen Trades dort 8x kleiner. Gleiche Ursache wie beim Spread (Buchtiefe), also Mechanismus statt Zufall. Endvergleich mit dem gemessenen Wert je Fenster: M1 alle Stunden -0,107/-0,161 PF 0,83/0,76 FAELLT HART DURCH M1 10-17 +0,354/+0,247 ΣR +150/+121 M5 alle Stunden +0,401/+0,261 ΣR +108/+71 M5 10-17 +0,751/+0,444 ΣR +68/+45 Der ΣR-Vorsprung von M1 ueber alle Stunden war reines Artefakt der Annahme "keine Exit-Slippage". Auf demselben Fenster bleibt ein echter Zielkonflikt: M5 doppelt so gut je Trade, M1 doppelt so gut in der Summe — bei EINEM Slot. Urteil: nicht umstellen. Der entscheidende Parameter ist nur als Untergrenze bekannt und M1 hat davon nur ~3x Luft bis zur Kippgrenze (M5 ~7x); die Stichproben sind duenn; 80 Tage = ein Regime. Die Bedingung fuer ein spaeteres Ja ist in CLAUDE.md benannt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
92187d7d32 |
backtest_squeeze_m1.py: Squeeze auf M1 gemessen (Variante B)
Nicht ausgeschlossen — aber in JEDER Variante schlechter je Trade als die M5-Kontrolle auf demselben Fenster (beste M1-Variante +0,474/+0,387 gegen +0,605/+0,491). Alle Nachbar-Parameter halten, Einstiegs-Slippage bis 0,20xATR haelt, der skalierte ATR-Floor erzeugt den Befund nicht (Kontrolle ohne Floor bestaetigt), Broker blockt nicht (trade_stops_level = 0). Entscheidend ist die EXIT-Slippage, und sie trifft M1 doppelt so hart, weil sie absolut ist: M1 kippt bei ~0,04 $, M5 erst bei ~0,09 $ (Faktor 2,2 = das ATR-Verhaeltnis). Gemessener Median 0,017 $ -> beide halten; gemessener Ø 0,234 $ -> beide fallen. Die entscheidende Zahl — Slippage bedingt auf Haltedauern <30 min — ist ungemessen. Urteil: nicht umstellen. M1s Vorteil kommt allein aus der 4,3-fachen Frequenz, und genau die multipliziert die ungemessene Groesse. Zwei Methodik-Lehren dokumentiert: der Haertetest lief zuerst auf der schwaechsten statt der besten Variante (Auswahl nach Reihenfolge statt nach Ergebnis), und die Regel "nicht schlechter als die Kontrolle" war wieder unterspezifiziert (ØR und ΣR zeigen gegenlaeufig) — deshalb gibt zeig() jetzt beide Spalten aus. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c888bcc3e8 |
analyze_scalping_costs.py: B3-Check fuer ein M1-Scalping-Modul
User-Frage "wie sinnvoll waere ein Scalping-Modul auf 1M-Basis". Vor dem Bau gemessen, weil es zuerst eine Kosten- und keine Signalfrage ist: der Spread ist absolut ~konstant und skaliert nicht mit der Zeitebene, die Bewegung schon. Spread/ATR im Median: M1 0,319 · M5 0,193 · M15 0,133. Eine mittlere M1-Kerze ist nur 3,4x so gross wie der Spread. Noetige Trefferquote bei 1:1 steigt von 50 auf 65,9 %; um 01:00 uebersteigt der Spread mit 1,051xATR_M1 die gesamte durchschnittliche Bar-Spanne. Dazu drei Gruende, die schwerer wiegen als die Kosten: - M1-Historie ist hart bei 80.000 Bars / 80 Tage gedeckelt -> kein 2-Stichproben-Test ueber verschiedene Regime moeglich - das Aufloesungs-Artefakt vom 05.08. trifft M1 am haertesten (Scalp lebt in 2-3 Bars, Bar-Sim ueberschaetzt enge Stops) - der Slippage-Schwanz ist absolut: Ø 0,234 $ uebersteigt einen 2xATR_M1-Stop (0,174 $) bereits im Mittel Empfehlung: kein eigenstaendiges Modul; messbar waere der Squeeze auf M1 (offene Variante B) beschraenkt auf 10-17 Uhr. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
bf838b4d03 |
analyze_squeeze_entry_gap: nur noch echte Bot-Trades zaehlen
Das Skript zaehlte im Abschnitt "per Pending gefuellt" JEDEN Trade seit dem Umbau — es meldete "31 Trades, davon 30 ohne Market-Log-Zeile". Real waren es 5 Bot-Trades (1 Market-Fallback + 4 Pending-Fills); der Rest waren manuelle. Moeglich war die Verwechslung genau deshalb, weil ein Pending-Fill bis zum Fix von heute ohne `setup` gebucht wurde. Jetzt Filter auf SQUEEZE_*/AUTOSIG_* und Setup in der Ausgabe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3c1442109d |
Pending-Fill: Bot-Trades wurden nicht als solche gebucht
Auftrag "überprüfe die heutigen autotrades": die DB meldete für den 06.08. null Bot-Trades, das Log vier gefüllte SQZ-STOP-Orders. Beides stimmte. Ein Pending-Fill läuft nicht über engine._open — die Position wird von trader._refresh_locked per magic-match adoptiert, und dieser Pfad loggt nur Ticket/Symbol/Richtung/Lots/Preis. Es fehlten setup, sl_at_entry und alle 16 ctx_*-Spalten. Damit war genau die Messpipeline, die den Pending-Umbau vom 05.08. kontrollieren soll, blind für ihn (B4-Monitor, squeeze_b5, squeeze_entry_gap zählten null) — Deployment-Drift Fall 8, erste Variante, bei der nicht die Strategie driftet, sondern ihre Beobachtbarkeit. - history.tag_bot_trade(): UPDATE nur wenn setup IS NULL, stiller Fail-open - engine._pending_tickets: Ticket -> Quelle, beim Platzieren/Stornieren gepflegt - engine._check_pending_fill() im _pos_loop vor dem Pending-Manager; Zuordnung über Positions-Nr == Order-Nr (an allen 4 Fills verifiziert), setzt zusätzlich _bot_open_ticket/_source und die Entry-Zähler 6 Szenarien getestet, darunter die zwei gefährlichen: fremde Position wird nicht getaggt, derselbe Fill zählt bei Folge-Ticks nur einmal. Die 4 Trades des 06.08. nachgetragen (Backup .bak-2026-08-06). ctx_*/sl_at_entry bewusst NICHT nachgetragen: rekonstruiert wären sie später von gemessenen Werten nicht unterscheidbar. Dabei gefunden, dokumentiert, NICHT behoben: der Signal-Pfad setzt/storniert dieselbe Order 4x in 76 s bei identischem Level, weil block_reason zwischen entry_room und breakout_pending pendelt (Drift Fall 9). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
730219fce8 |
Wenige Empfehlungen nachgeprueft: Telemetrie-Luecke bei min_conf gefunden und
geschlossen Der 05.08. hat 1427 Zeilen geloggt (Soll ~1440), die Erfassung ist also intakt. 5,0 % gerichtet - und auffaellig ist die Verteilung: alle 71 gerichteten Empfehlungen fielen vor 10:00, danach 16 Stunden lang genau eine. Gegen den gueltigen Massstab (backtest_dist_gated.py, 19,5 % gerichtet) ist entry_room NICHT der Unterschied - es ist live mit 36,5 % sogar seltener als im Backtest (41,4 %). Die Luecke tragen die live-only-Gates, allen voran min_conf (16,1 % live gegen 0,9 % im Backtest), dazu htf_counter, EIA und stale. Telemetrie-Luecke: min_conf-Zeilen schrieben conf_pct = 0, die verworfene Konfidenz stand nur als Fliesstext in den Gruenden. Damit war beim zweitgroessten Blocker nicht feststellbar, ob die Signale knapp (50-54) oder weit (20-30) unter der Schwelle lagen. wave_rec._build gibt den Wert jetzt mit - reine Telemetrie, das Signal bleibt WARTEN. Erste Live-Zeile: conf 52. Das beantwortet noch nicht, ob 55 die richtige Schwelle ist: backtest_conf.py hat das Band 40-54 % als negativ gemessen, eine Senkung ist nicht angezeigt. Die Zahl sagt nur, wieviel Signalmenge direkt hinter der Schwelle steht. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
89e4af4561 |
HL-Kurs: Rohkurs anzeigen + Basis bei stehendem Broker einfrieren
User-Fund: app.hyperliquid.xyz zeigt WTIOIL-USDC bei 81,392, das Dashboard 86,424. Dahinter steckten zwei Fehler. (1) Falsches Label (vom 01.08.): angezeigt wurde mid_mt5 = HL + Basis, also der auf Pepperstone-Niveau umgerechnete Wert - unter der Beschriftung "HYPERLIQUID KURS". Jetzt steht dort der ROHE HL-Kurs (exakt die Zahl von der HL-Seite); das CFD-Aequivalent ist in den Tooltip gewandert. (2) Die Basis-Korrektur war bei geschlossenem Markt ZIRKULAER. Gegenstueck im HL-Projekt (eigener Commit): die Basis wird jetzt auf dem letzten Stand mit lebendem Broker eingefroren und als basis_stale durchgereicht. Belegt aus leadlag.db: Basis bei lebendem Broker konstant +0,42...+0,58, nach dem Freeze +5,03. Der Wochenend-Move war echt (So 03:00->05:00 von 85,51 auf 80,84, danach 13 h stabil um 81 bei ~600 Messungen/h). Materielle Folge: die offene SHORT-Position (0,57 ab 86,163, TP 84,123) wurde mit -15,02 EUR angezeigt; mit eingefrorener Basis sind es +211 EUR, und der TP liegt 2,3 $ ueber dem echten Niveau. Vorbehalt bleibt (Oracle-Perp) -> weiter "≈". Ausserdem dokumentiert: restart_server.bat hat zweimal still NICHT neu gestartet. Eine korrekt ausgelieferte app.js?v=N belegt NICHTS ueber den geladenen Python-Code (statische Dateien werden je Request von der Platte gelesen). Zuverlaessig nur: Prozess killen, direkt starten, danach an einem NEUEN Snapshot-Feld pruefen. v=132. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d18d8712db |
Auto-Signal abgeschaltet + B5-Abbruchregel fuer Auto-Squeeze fixiert
Auto-Signal AUS (auto_signal=false via Toggle -> runtime_state.json). Gruende sind NICHT die Live-Bilanz (n=4 sagt nichts): - gemessen in H1 durchgehend negativ (backtest_auto_signal.py, alle 8 Varianten) - beide Auto-Pfade konkurrieren um den EINEN Positions-Slot -> solange beide laufen, ist die B5-Pruefung des Auto-Squeeze nicht sauber messbar B4-Befund Auto-Squeeze (Anlass: negative Auto-Trades vom 31.07.): Mechanik (isolierter Einstieg): WR 46 %, OR +0,102, PF 1,15 Live (n=31, 17.-31.07.) : WR 45 %, OR -0,242, PF 0,49 Die Trefferquote stimmt ueberein - der Einstieg ist intakt. Die Luecke von 0,34 R/Trade entsteht im EXIT (O-Gewinn +11,02 vs O-Verlust -19,83). Alle drei Ursachen wurden am 31.07. behoben (P(break) nachtrainiert, 15-Min-Regel aus, Trail einheitlich 1,0), der Live-Zeitraum liegt also VOR den Reparaturen. Deshalb kein Rueckbau, sondern vorab fixierte Latte: >=20 Squeeze-Trades ab 01.08., dann Verhaeltnis < 1,0 ODER PF < 1 -> aus. measurement_reminder.py: - neue Messung squeeze_b5 (loest autosig_b4 ab) - CONFIG_DEPS um auto_signal (soll false) und auto_squeeze (soll true) ergaenzt - ⚠ _cfg_now() liest jetzt AUCH runtime_state.json und bildet dessen Vorrang ab. Vorher verglich der Waechter nur die ini -> er meldete "alles auf dem gemessenen Stand", waehrend auto_signal per persistiertem UI-Toggle lief. Mit Szenario verifiziert (runtime true gegen validiert false -> gemeldet). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
d0f3b78796 |
Muster-Verdict-Gewicht 1,0 -> 0,25 (5%) + Korrektur der adverse15-Anekdote
Muster-Stimme (User-Vorgabe "geben wir dem Muster doch 5%"): _PAT_W = 0.25 statt fest 1,0; "forming" weiter die Haelfte. Empirisch gesetzt: ueber die letzten 4.000 verdict_votes liegt die Gewichtssumme der uebrigen Module im Median bei 4,50 -> Anteil 5,3 % (vorher 18,2 %). Muster hat in 24,7 % der Verdicts ueberhaupt eine Richtung, max. Nadel-Verschiebung 0,053. Reine Anzeige - der Bias steuert keine Order. Korrektur in CLAUDE.md: Die Anekdote zum Abschalten der 15-Minuten-Regel war falsch. "+19,28/+17,60 moeglich" und "32 EUR weiter dagegen" waren MAXIMALE AUSLENKUNG, nicht das, was der Exit gefangen haette. Mit core/exit_model.py nachgerechnet waere der 11:44-Trade OHNE Regel besser gewesen (-21,43 statt -26,31) und der 20:00-Squeeze schlechter (-23,27 statt -13,77). Ueber alle 7 Bot-Trades des 31.07. haette das Abschalten -16,42 EUR gekostet. Die Entscheidung bleibt richtig - sie ruht auf backtest_adverse15_squeeze.py (16/16 Kombinationen in beiden Haelften negativ), nicht auf einem Tag mit n=3. Der Tagesgewinn kam aus Trail 1,5 -> 1,0 (+24,86 EUR auf denselben Trades). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7d68dfc4db |
Doku: restart_server.bat nicht mit Output-Umleitung aus PowerShell aufrufen
Der Batch startet das Oil-Backend im Vordergrund. Mit `& .\restart_server.bat *>&1 | ...` blockiert der Aufruf bis zum Timeout und der abgeschnittene Tail zeigt ein irrefuehrendes "===== Server beendet =====", obwohl der Server laeuft. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
b8bb1d260f |
Fix: Broker-Offset bei geschlossenem Markt (-9,5 h statt +3 h)
`_broker_offset_s()` leitete die Zeitzone aus `tick.time - now` ab. Das misst die Zeitzone nur bei FRISCHEM Tick; steht der Markt, misst es die Veraltung. Real am 01.08. (letzter Tick Fr 23:54): -34210 s -> gerundet -34200 (-9,5 h) statt +10800. Die Pruefung [-12h,+14h] liess das durch. Folgen (die Laufzeit-Uhr war nur das Sichtbare): - open_time 12,5 h in der Zukunft -> Laufzeit 0:00 - Time-Stop-Alter (trailing.py:504) negativ -> 120-min-Stop haette nicht ausgeloest - deal.time-Umrechnung beim externen Close, alle MQL5-Chart-Anker Fix: Offset nur noch aus frischem Tick bestimmen, sonst letzter gueltiger Wert (vorbelegt UTC+3 = dieselbe Konstante wie engine.broker_utc_offset). Frische am bereits bekannten Offset gemessen -> nicht zirkulaer. Schwelle 900 s < halbes Rundungsraster. Zeitzonen-Wechsel wird uebernommen und geloggt. Ausserdem: - market_closed greift sofort nach Neustart: _last_bid_move_ts wird aus dem echten Tick-Alter vorbelegt statt bei null zu starten (vorher 180 s blind) - pollSnapshot: der stille catch umschloss render() -> Render-Fehler wurden lautlos verschluckt, das Dashboard fror ohne Konsolen-Fehler ein. Jetzt ist nur noch der fetch im try. - Header-Labels ausgeschrieben: "PEPPERSTONE KURS" / "HYPERLIQUID KURS" - v=131, CLAUDE.md (Deployment-Drift Fall 4) Verifiziert: market_closed sofort True, tick_age gegen die Rohwerte 0 s Abweichung, open_time -> 31.07. 22:54 (Laufzeit +15,8 h). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
2ea17ce3e0 |
Dashboard fror bei gecachter alter HTML ein - neue Elemente jetzt null-sicher
User: "ich sehe die Aenderungen nicht im dashboard". Server war korrekt:
v=129 samt #hdr-hl ausgeliefert, Cache-Control: no-store gesetzt, kein
Service-Worker, hl_live im Snapshot vorhanden.
Ursache: index.html und app.js werden vom Browser UNABHAENGIG gecacht.
Trifft neue JS auf eine alte, gecachte HTML, wirft
$("hdr-price-lbl").textContent = ... eine TypeError - und weil das mitten in
render() passiert, bricht der GESAMTE Render ab. Das Dashboard friert ein
und zeigt Altwerte, obwohl alles andere stimmt. Genau das Symptom.
Fix: neue Elemente ueber const el = $("id"); if (el) { ... } ansprechen.
Dann laeuft der Rest weiter und nur das neue Feld fehlt, bis die HTML
nachgeladen ist. Betrifft hdr-price-lbl und hdr-hl.
Regel in CLAUDE.md aufgenommen - das ?v=N-Bump bustet nur app.js/style.css,
NICHT die index.html selbst.
v=130.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
7427c36922 |
Hyperliquid-Kurs neben dem Broker-Kurs + G/V-Schaetzung bei geschlossenem Markt
User: "wenn Pepperstone closed ist trotzdem Kurs und Liquiditaet von
Hyperliquid einbinden" -> nachgeschaerft zu "blende den HL-Kurs NEBEN den
Pepperstone-Kurs ein" (ehrlicher als ein stiller Tausch) -> plus "bei
geschlossenem Markt auch den G/V mit HL berechnen".
Snapshot: hl_live {mid_mt5, hl_mid, basis, age_s, bid/ask, bid_sz/ask_sz,
imb5, trend, slope_per_h, vs_mt5} - IMMER befuellt. mid_mt5 = HL-Mid +
gemessene Basis, also direkt mit dem Broker-Kurs vergleichbar. Dazu
market_closed, tick_age_s, pnl_hl.
core/hl_walls.py liefert jetzt zusaetzlich hl_mid/mid_mt5/age_s.
Dashboard v=129: eigene Header-Box "HL" neben KURS mit Tooltip (Rohkurs,
Basis, Alter, Abweichung). Bei geschlossenem Markt: Label "KURS · ZU",
Session-Zeile "MARKT ZU", und das G/V wechselt auf die HL-Schaetzung, mit
"≈" markiert.
MT5 v1.34: HL;<mt5_aequiv>;<alter>;<bid>;<ask>;<U|D|-> -> bernsteinfarbenes
Label unter Kurs und G/V (InpShowHL/InpHLColor).
DREI SACKGASSEN dokumentiert, damit sie niemand wiederholt:
1) tick_local_ts ist die ABHOLZEIT, nicht das Tick-Alter.
2) tick_server_ts minus _broker_offset_s() ist ZIRKULAER - die
Offset-Funktion leitet den Versatz selbst aus dem letzten Tick ab und
misst bei geschlossenem Markt die Veraltung (-7,41 h statt +3 h); das
Alter hebt sich auf (-347 s).
3) pnl / Kursbewegung als EUR-je-Punkt ergab 155 statt ~86, weil
trader.pnl den Wochenend-Swap enthaelt.
Verwendet wird stattdessen: Markt zu = der Kurs hat sich seit 180 s nicht
BEWEGT (_last_bid/_last_bid_move_ts). Und der G/V nutzt die vorhandene,
korrekte trader.live_pnl(bid, ask) mit dem HL-Kurs +- halbem Spread.
Live verifiziert: market_closed=True nach 198 s, Broker 86.333 eingefroren,
HL 86.349 (7 s alt), Broker-P&L -15,02 -> HL-Schaetzung -14,37 EUR.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
35f9b567c8 |
Pfeile: Konsens-Pfeil per Default aus - er erzeugte wieder einen Trichter (v1.33)
User: "trichter anstatt pfeil wird angezeigt". Der Kegel war korrekt raus
(keine CN-Zeile mehr in der CSV) - was zu sehen war, waren MEINE zwei
Pfeile:
AR;L;85.233;85.110;63% Abprall blau, nach UNTEN
AR;K;85.233;85.479;Konsens +1.00 grau, nach OBEN
Beide starten am aktuellen Kurs und liefen auseinander - optisch exakt der
Kegel, den sie ersetzen sollten. Gefragt war EIN Pfeil, gebaut waren drei.
Behoben:
InpShowConsensus per Default FALSE (der Konsens steht ohnehin als
Bias-Nadel im Dashboard)
InpArrBars 14 -> 8 (kuerzer, Pfeilspitze im sichtbaren Bereich)
Normalfall jetzt: EIN Pfeil (L, der kalibrierte). S kommt nur beim
Squeeze-Ausbruch dazu. InpShowConsensus=true holt K zurueck.
Lehre fuer die Doku: "sie messen Verschiedenes, also duerfen sie
auseinanderzeigen" ist logisch richtig und als BILD trotzdem falsch - zwei
Linien aus einem Ursprung liest niemand als zwei Aussagen.
v1.33 ins richtige Terminal kompiliert und dort gegengeprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
00ca2406f1 |
15-Minuten-Regel ganz abgeschaltet (adverse_15min_atr = 0)
User-Frage "vielleicht die auto close auf 30 min setzen?" -> Zeit-Achse
mitgemessen (backtest_adverse15_squeeze.py um Zeitpunkt und zweite
Population erweitert): 15/30/45/60 min x 0,5/0,8xATR, Squeeze- UND
Wave-Signal-Entries, kanonischer Exit, Echtkosten, 2 Halbjahre.
Zeit Schwelle Squeeze H1/H2 Wave H1/H2
15 0,5 -18 / -34 -25 / -41 (war live)
30 0,5 -20 / -35 -22 / -13
45 0,8 -12 / -18 -3 / -7
60 0,8 -8 / -10 -3 / -3
ALLE 16 Kombinationen sind in BEIDEN Haelften negativ. Die Regel wird nur
monoton weniger schaedlich, je spaeter und lockerer sie prueft - die
"beste" Variante ist praktisch die, die nie feuert. 30 min haette den
Schaden halbiert, nicht beendet.
Damit ist auch meine Einschaetzung von vor einer Stunde korrigiert ("auf
dem Auto-Signal-Pfad ~neutral"): sie stuetzte sich auf
backtest_auto_signal.py mit eigenem Exit-Modell (+0,001 vs +0,026); mit dem
kanonischen Exit sind es -25/-41. Sechster Fall desselben Musters an einem
Tag.
Schutz-Stack bleibt vollstaendig: Broker-SL 2xATR + Trailing + Time-Stop
120 min. Die Squeeze-Ausnahme bleibt im Code, falls die Regel je wieder
eingeschaltet wird.
Config-Waechter-Anker auf 0 gezogen, mit Begruendung im Eintrag.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
6cf2730dc3 |
15-Min-Regel: Squeeze-Trades ausgenommen (gemessen schaedlich)
Analyse der negativen Autotrader-Trades. Von den drei heute per adverse15
geschlossenen Bot-Trades hat die Regel bei EINEM gerettet (Auto-Signal
11:44, -26,31 EUR; danach lief der Kurs 32 EUR weiter dagegen) und bei den
beiden SQUEEZE-Trades zu frueh gekappt (20:15 / 20:36, -13,77 / -28,09 EUR;
danach waeren +19,28 bzw. +17,60 EUR moeglich gewesen - aus candles_m1
nachgerechnet).
Verdacht bestaetigt: die Schwelle 0,5xATR wurde in backtest_auto_signal.py
auf WAVE-SIGNAL-Entries kalibriert und dann auf ALLE Bot-Trades angewandt.
Wieder ein Kalibrierungs-Bruch.
backtest_adverse15_squeeze.py (NEU, 80k M5, 2 Halbjahre, Echtkosten,
Exit-Kern): auf SQUEEZE-Entries schadet die Regel bei JEDER Schwelle in
BEIDEN Haelften:
0,3 -> -25/-38 · 0,5 -> -18/-34 · 0,8 -> -12/-39 · 1,2 -> -5/-18
Monoton, also ist die Regel selbst das Problem, nicht ihre Einstellung.
Ohne Regel H1 -54 / H2 +220, mit 0,5 H1 -72 / H2 +186.
Grund: der Squeeze ist runner-abhaengig (43 % Treffer, Ertrag im Tail) -
ein Schnitt nach 15 min trifft genau den Tail.
Umsetzung: _bot_open_source merkt beim Oeffnen, WOMIT eroeffnet wurde;
_check_adverse15 steigt bei auto_squeeze aus. Mit 7 Szenarien getestet.
Fuer den Auto-Signal-Pfad bleibt die Regel aktiv - dort gemessen ~neutral
(OeR +0,001 mit vs +0,026 ohne), also eine Versicherung mit kleiner Praemie.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
be2c318745 |
CLAUDE.md: Richtungs-Pfeile dokumentiert (im vorigen Commit gescheitert)
Die Doku-Ergaenzung war im letzten Commit an einem deutschen Anfuehrungszeichen im Python-Heredoc gescheitert (SyntaxError), waehrend der Code durchging. Jetzt nachgeholt: die drei Pfeil-Arten mit ihrer jeweiligen Beleglage, das 45-55-%-Totband und der ALBL_-Namensraum-Fallstrick. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
81614a3128 |
Richtungs-Pfeile im MT5 statt des Kegels (v1.32) + Handbuch-Muster ergaenzt
PFEILE (User: "anstatt des Trichters einen Pfeil, der die wahrscheinlichste
Kursentwicklung anzeigt"). Randbedingung: die FREIE Richtungsfrage ist
gemessen ein Muenzwurf (analyze_reversal.py, AUC 0,499-0,509 oos, in-sample
nur 0,52). Ein frei schwebender Prognose-Pfeil waere unbelegt - und
gefaehrlicher als der Kegel, weil er ueberzeugender aussieht. Deshalb DREI
Pfeile mit jeweils eigener, benannter Beleglage:
L blau naechstes Level, aus dem kalibrierten P(break)
(AUC 0,65 oos, live 27 % vorhergesagt vs 28 % real)
S neongruen Squeeze-Ausbruch - das EINZIGE validierte Richtungssignal
K grau Konsens der Module - NICHT kalibriert, heisst deshalb
"Konsens" und nicht "Prognose"
L hat ein TOTBAND 45-55 %: dort waagerechter Pfeil "unentschieden", statt
aus einem Muenzwurf eine Richtung zu zeichnen.
MQL5 v1.32: OBJ_ARROWED_LINE + Label an der Spitze. Label heisst ALBL_* und
NICHT T* - sonst zieht RepositionLabels() es an den rechten Rand und loest
es von der Pfeilspitze.
Kegel bleibt im Code und in der Dashboard-Kachel; der Bot exportiert ihn nur
nicht mehr ins Chart ([trading] export_cone=false).
CHARTMUSTER: alle Handbuch-Muster ergaenzt - Dreifach-Top/-Boden, Flagge,
Wimpel, Rechteck, Steigender/Fallender Keil. ALLE mit measured=False, sie
tragen die Verdict-Stimme NICHT: das Gewicht 1,0 stammt aus einem
Kontrolltest, der nur die alten Typen abdeckte. engine._verdict waehlt jetzt
nur Muster mit measured=True.
Bug beim Bau gefunden: der fallende Keil feuerte in 20.000 Bars KEIN
EINZIGES MAL - die Bedingung stand auf dh > dl, bei einem fallenden Keil
faellt aber die OBERE Linie schneller (sonst konvergiert nichts). Beim
Spiegelbild (steigender Keil) stimmte es.
backtest_patterns_v2.py (NEU) misst die neuen Typen - mit dem ECHTEN
Detektor (core.patterns._detect statt einer Nachbildung) und dem
kanonischen Exit, plus Kontrollgruppe "generischer Swing-Bruch".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
365a0584e5 |
Prognose-Kegel war unsichtbar: Indikator landete im falschen MT5-Terminal
Der Kegel wurde heute frueh gebaut, exportiert (CN;30/60/120 stehen korrekt in der CSV) und kompiliert - war aber nie zu sehen. Ursache: unter %APPDATA%\MetaQuotes\Terminal\ liegen VIER Instanz-Ordner. Meine Kopier-Zeile bestimmte das Ziel ueber "hat MQL5\Indicators" + Select-Object -First 1 und traf 0BA5CADA..., waehrend der Bot nach D0E8209F... schreibt und der Chart dort laeuft. Folge: der Chart lief seit heute frueh weiter auf v1.29 - ohne Prognose-Kegel UND ohne die Konsolidierungs-Beschriftung (v1.30), obwohl beide "gebaut und mit 0 Fehlern kompiliert" gemeldet waren. Behoben: v1.31 in das Terminal kopiert und kompiliert, das die CSV schreibt. Verifiziert: #property version 1.31, ex5 frisch, CN-Handler und TCONSOL-Label im Terminal-Quelltext vorhanden. CLAUDE.md: Fallstrick dokumentiert samt der richtigen Ziel-Ermittlung (ueber die vom Bot geschriebene CSV, nicht ueber die blosse Existenz von MQL5\Indicators) und der Gegenprobe nach jedem Kompilieren. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3314b6e9b1 |
Flip-Close bekommt Nachrang gegenueber dem S/R-Close (gemessen)
User-Frage "sollten wir den S/R close auch deaktivieren?" -> nein, die
beiden sind gegensaetzlich gemessen. Aber sie konkurrieren seit dem Einbau
um dieselben Trades, und die S/R-Freigabe lief OHNE Flip-Close.
backtest_exit_combo.py (NEU, 80k M5, 2 Halbjahre, Echtkosten, Exit-Kern aus
core/exit_model.py, 5 Varianten auf IDENTISCHEN Entries):
nur S/R-Close H1 +59 · H2 -14 (535/284 S/R-Closes)
nur Flip-Close H1 -1 · H2 -43
BEIDE H1 +56 · H2 -50 (507/252)
BEIDE, Flip nachrangig H1 +62 · H2 -49 (516/260)
KOLLISION BELEGT: der Flip nahm dem S/R-Close 28 bzw. 32 Trades weg
(5-11 %) - genau die, fuer die dieser validiert ist. Mit Nachrang ist es in
BEIDEN Haelften besser als ohne.
Umsetzung: liegt ein S/R-ZIEL <=0,6xATR entfernt (dieselbe Schwelle wie der
Live-Hinweis), haelt der Flip sich zurueck.
[trading] auto_flip_close_subordinate (Default true).
Mit 4 Szenarien getestet: in Reichweite, ausser Reichweite, kein Level,
Nachrang aus.
EHRLICH DAZU: auch mit Nachrang kostet der Flip in H2 rund 35 R gegenueber
"nur S/R-Close" (-49 vs -14). Der Nachrang begrenzt den Schaden, er dreht
ihn nicht um.
METHODIK-FEHLER BEIM BAU, KORRIGIERT: der erste Lauf liess die sequentielle
Sim nach dem Exit bei xb+1 weiterlaufen - dadurch hatte JEDE Variante eine
ANDERE Trade-Folge und die Zahlen waren nicht vergleichbar. Jetzt feste,
geteilte Entry-Liste wie in backtest_pbreak_rvalue.py. (Die zunaechst
gemeldeten Deltas -195/-144 stammten aus diesem konfundierten Lauf.)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
fea91fddb3 |
Auto-Flip-Close gebaut (User-Wunsch) - trotz erneut negativer Messung
User: "schliesse den trade automatisch beim close signal". Dreht die
Empfehlung gegen die offene Position und steht sie >=0,5xATR im Plus ->
close(reason="flip_close").
VORHER NEU GEMESSEN, weil das alte Urteil (backtest_flipclose.py,
16.07.) auf einem VIERTEN Exit-Modell fusste: Trail fest 1,5 (live jetzt
1,0), keine Lock-Phase, kein Time-Stop, kein Initial-TP, _MAXH 288 statt
200, Phasen ueber den Bar-Close statt ueber das High-Water.
backtest_flipclose2.py (80k M5, 2 Halbjahre, Echtkosten, Exit aus
core/exit_model.py) bestaetigt das alte Urteil - deutlicher:
Basis ohne Flip H1 SigmaR -537 · H2 -140
Flip ab 0,0xATR Delta H1 -126 · H2 -221
Flip ab 0,3xATR Delta H1 -77 · H2 -216
Flip ab 0,5xATR Delta H1 -92 · H2 -160 <- mildeste, Default
Flip auch im Minus Delta H1 -205 · H2 -364
JEDE Variante ist in BEIDEN Haelften schlechter. Trefferquote steigt
39 -> 45 %, Ertrag faellt = Gewinner-Kappen (die nachlaufende EMA dreht
oft mitten im Pullback).
Gebaut wurde die mildeste Variante (0,5xATR Mindestgewinn), abschaltbar
ueber [trading] auto_flip_close.
Fuer die Neumessung bekam exit_model.simulate() einen stop_when-Hook
(+ ret_bar), damit die Phasen-Mechanik nicht zum fuenften Mal kopiert
werden musste. Rueckwaertskompatibilitaet verifiziert: ohne Hook bitgenau
identisch (die zunaechst gemeldeten Abweichungen kamen allein aus
LIVE.mult 1,5 -> 1,0, gegengeprueft mit mult=1.5 -> identisch).
Mit 10 synthetischen Szenarien getestet: beide Richtungen, aus, unter
Schwelle, gleichgerichtet, WARTEN, im Minus, flat, Startup-Schonfrist,
Ticket-Dedup - alle korrekt.
B4/B5-Pflicht: Live-Ertrag gegen die Erwartung halten, bei Drift
auto_flip_close=false.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
f1cc3775f9 |
Gesamtempfehlung zeigt jetzt, WARUM sie wartet (v=126)
User-Fund: "WARTEN · M15" neben "Modul-Konsens: stark LONG" liest sich wie
ein Widerspruch. Ist keiner - die Welle HAT eine Richtung und haengt nur an
einem Gate. Der Grund stand aber nur als Textzeile in der Meldungen-Karte,
also weit weg von der Stelle, an der die Frage aufkommt.
wave.breakout {pending, dir, level, need} wurde berechnet und im Snapshot
gespeichert, vom Frontend aber NIRGENDS gerendert. Jetzt haengt es direkt
an der Headline:
"◌ WARTEN · M15 · LONG, noch 0.02 bis zur Bestaetigung"
Erste Auswertung der gestern eingebauten block_reason-Telemetrie (3 h):
breakout_pending 63 %
entry_room 20 %
min_conf 18 %
Totband / HTF-Gegen-Trend: KEIN EINZIGES MAL
Das beantwortet die offene Frage aus dem TF-Churn-Fix: die 93 % WARTEN
kommen nicht daher, dass die Welle richtungslos waere, sondern von den
Gates - allen voran der Breakout-Bestaetigung, die bis zum Fix desselben
Tages rechnerisch gar nicht fertig werden konnte.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
df092674cb |
Konsens-Zeile korrigiert: falscher Bezug + Nenner passte nicht zu den Chips
User-Fund: "Modul-Konsens: stark LONG · 4/4 Module fuer WARTEN" - dabei sind
9 Module sichtbar. Zwei echte Fehler.
(a) FALSCHER BEZUG: der Text lautete "... Module fuer ${sig}" mit der
HEADLINE als Bezug. Seit dem ref-Fix vom 30.07. zaehlt `agree` bei WARTEN
aber die Uebereinstimmung mit der BIAS-Richtung - deshalb stand dort
"stark LONG ... fuer WARTEN". Die Richtung kommt jetzt als verdict.ref_dir
vom Backend, statt im Frontend aus `bias` nachgebaut zu werden (dort galt
ein +-0,05-Totband, im Backend `bias > 0` - die Nachbildung waere am Rand
auseinandergelaufen; dieselbe Sorte Divergenz wie die fuenf
Deployment-Drift-Faelle desselben Tages).
(b) ANDERER NENNER ALS DIE CHIPS: `total` zaehlt nur Module MIT Aussage
(Gewicht>0, ohne die Welle). Nach den Gewichts-Fixes des Tages schweigen
deutlich mehr Module -> "4/4" bei 9 sichtbaren Chips. Neu ist
verdict.silent (Module mit Gewicht 0) dabei, sodass die Summe aufgeht.
Live verifiziert: "Modul-Konsens: leicht LONG · 3 von 5 stimmberechtigten
fuer LONG (4 ohne Aussage)" - 5 + 4 = 9. Sonderfall "kein Modul mit klarer
Aussage" abgedeckt. v=125.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
a1f471f163 |
Timer-Erinnerung fuer den zweiten Modul-Audit angelegt
measurement_reminder.py: neuer Punkt "Modul-Audit: zweiter Durchgang", faellig 28 Tage nach dem ersten (also ab 2026-08-28). Begruendung im Eintrag: am 31.07. wurden an EINEM Tag 5 Deployment-Drift- Faelle UND 5 Modul-Inkonsistenzen gefunden - bei gezielter Suche in wenigen Stunden. Die Trefferquote spricht dafuer, dass weitere existieren. analyze_divergence.py meldet die Klasse "Betrieb != Messung" inzwischen selbst; die Klasse "Modul-Inkonsistenz" (Gewichte, stale Quellen, tote Config, Sonderfaelle) braucht dagegen einen bewussten Durchgang. Kein neuer Windows-Task noetig - OilMeasurementReminder laeuft bereits taeglich 18:00 und prueft alle Eintraege. Task testweise ausgeloest: LastTaskResult 0, Arbeitsverzeichnis korrekt gesetzt. (Ein Erinnerungssystem, das still scheitert, waere schlimmer als keins - genau dafuer gibt es das Ding.) CLAUDE.md-Tabelle auf den Stand 31.07. gebracht; erledigte Punkte ausgetragen (P(break)-Genauigkeit -> analyze_pbreak_live.py, Modell daraufhin nachtrainiert; Chartmuster-Kontrolltest -> 30.07.). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
367d70eb7a |
Modul-Audit: 5 Inkonsistenzen behoben + Secret-Luecke in .gitignore geschlossen
Systematische Pruefung aller Verdict-Module gegen die Regel "keine Aussage
-> Gewicht 0", dazu Config-, Frontend- und Level-Quellen.
(1) KI-COPILOT - der groesste Rest des Musters. Ein explizites "NEUTRAL"
zaehlte als echte Stimme mit Gewicht 1,0. Gemessen (verdict_votes, n=7.084):
das ist in 93,1 % der Faelle der Zustand (Elliott: 1,3 %) - also der
Normalzustand des Copiloten, kein abgewogenes Urteil. Damit hatte
ausgerechnet das Modul mit der schwaechsten Beleglage
(analyze_verdict_calibration.py: nicht robust praediktiv) den GROESSTEN
daempfenden Einfluss auf die Bias-Nadel.
(2) ELLIOTT analog: Gewicht nur bei gerichtetem Ziel.
Kumulierte Wirkung aller Gewichts-Fixes des Tages:
Oe|bias| 0,370 -> 0,441 -> 0,569 (= 1,54x), betrifft 79,5 % der Zeilen
Live verifiziert: KI "NEUTRAL" -> Gewicht 0,00, bias 2,5/4,5 = 0,556
statt 2,5/5,5 = 0,455.
(3) STALE [zones] SPEISTEN DIE WELLEN-KONFIDENZ - entfernt. _sr_levels zog
beide Kanten jeder [zones]-Zone als S/R-Linien heran: 16 Kanten aus einem
~10 $ TIEFEREN Regime (72,90-77,00 bei Kurs 85,3). Aus dem Chart waren sie
am 14.07. schon entfernt worden, WEIL sie stale sind - in die Konfidenz
liefen sie weiter. Realer Audit-Fall: market.sr hatte gar keine
Widerstaende (M15-Cluster sind in frischen Trends oft leer) -> der
"naechste Widerstand" kam aus der fvg-Zone bei 88,00 (2,66 $ weg), der
echte lag bei 85,315 (0,03 $ weg). Der Abzug "dicht unter Widerstand"
(-12) greift nur innerhalb 0,5xATR und feuerte deshalb NIE.
(4) TOTE CONFIG entfernt: [trading] trail_timeframe (nirgends gelesen, Name
suggeriert faelschlich die Trailing-TF) und die komplette [setups]-Sektion
(11 Schluessel).
(5) raise StopIteration als Sprung in einem breiten except durch ein if
ersetzt - funktionierte, waere aber fragil sobald dort Logging dazukommt.
SICHERHEIT: beim Anlegen des Config-Backups fiel auf, dass .gitignore nur
"oil_widget_config.ini" abdeckt, NICHT "...ini.bak-<datum>". Das Backup lag
ungeschuetzt als untracked im Repo und enthaelt dieselben Live-Keys.
Muster ergaenzt. Gegenprobe: die .example-Datei enthaelt 10 secret-artige
Felder, davon 0 identisch mit der echten ini - alles Platzhalter.
Sauber geblieben: Frontend<->Backend (0 verwaiste Element-IDs), alle
uebrigen Verdict-Gewichte, alle anderen Config-Schluessel.
OFFEN (messpflichtig): die Wellen-Konfidenz aus _draw_levels speisen statt
aus dem Misch-Set - wuerde den -12-Abzug tatsaechlich ausloesen, also die
Konfidenz senken und das 55%-Gate verschieben.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
23c68e8837 |
Verdict: M30/H1 bekommen Gewicht 0 ohne Aussage (Bias-Fix Teil 3)
Anlass war die User-Frage "H1 aus der Gesamtempfehlung entfernen, da wir
jetzt mit M30 arbeiten?". Antwort NEIN, aber die Frage hat einen echten
Defekt freigelegt.
Zur Praemisse: auf M30 umgestellt wurde die S/R-LEVEL-QUELLE, nicht die
Zeitebenen-Logik. H1 war nie Basis-TF (tf_max=M30), sondern immer Kontext.
Zur vermuteten Doppelzaehlung - gemessen an verdict_votes (n=7.074):
bei gerichteter Welle stimmt M30 nur zu 14,9 % mit ihr ueberein, H1 zu
47 %, M30 und H1 untereinander nur zu 33,8 %. Keine redundanten Stimmen
(Reversals heben den M30-Filter bewusst auf, und M30 ist meist gar nicht
gerichtet). H1 fliesst zwar auch als Konfluenz-Bonus in die Konfidenz -
aber in eine ANDERE Kennzahl (Ring vs. Nadel), nicht zweimal in dieselbe.
DER ECHTE DEFEKT: add("M30", ...) und add("H1", ...) hatten Gewicht 1,5
UNBEDINGT, auch bei Stimme 0. Damit derselbe Fehler wie beim Wellen-Modul
(Bias-Fix Teil 2 vom 30.07.), hier uebersehen. Eine 0-Stimme heisst
"EMA-Abstand im Totband" = keine Aussage, nicht "neutral" - mit vollem
Gewicht im Nenner zog sie die Bias-Nadel dauerhaft zur Mitte.
Gemessen an 7.074 Verdicts: M30 ist in 57,9 % der Faelle ohne Aussage
(H1 nur 1,8 %). Oe-Bias-Betrag 0,371 -> 0,441, Median-Verstaerkung 1,30x,
in 33,3 % der Zeilen deutlich staerkere Nadel.
Fix: 1.5 if vote != 0 else 0.0 fuer beide. `others` filtert bereits auf
weight>0, die "x/y einig"-Zaehlung zieht damit automatisch mit.
Live verifiziert: M30 "flach" -> Gewicht 0,00, bias -1,5/4,5 = -0,333
statt -1,5/6,0 = -0,250 (genau die gemessene 1,33x-Verstaerkung),
agree 3/5 statt 3/6.
REINE ANZEIGE - die Order-Logik haengt an der Wellen-Headline, nicht am
Bias.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
fe5c2aae0a |
Legacy-Recheck vervollstaendigt: Bounce und ER-Chop-Gate nachgerechnet
backtest_legacy_recheck.py um zwei Abschnitte erweitert (Reversal-Flag und
Efficiency Ratio je Trade), damit alle vier Befunde abgedeckt sind, die auf
dem vereinfachten Legacy-Exit ruhten.
BOUNCE / REVERSAL - relative Aussage haelt, absolute NICHT:
H1 Reversal -0,034 (PF 0,93) vs Trend -0,174 (PF 0,68)
H2 Reversal +0,029 (PF 1,06) vs Trend -0,073 (PF 0,86)
Reversal schlaegt Trend in BEIDEN Haelften (+0,140/+0,102) - robust. Aber
die dokumentierte Kennzahl "OeR +0,185 / PF 1,35 / 70 % Treffer"
REPRODUZIERT NICHT: mit echtem Exit + Echtkosten liegt das Setup bei
~Breakeven. Die alten Werte stammen aus dem vereinfachten Exit ohne Kosten.
Das Setup bleibt sinnvoll als nachrangiges Zweitsignal (so ist es live auch
eingebaut), ist aber kein +0,185-Ertragsbringer.
ER-CHOP-GATE - Ablehnung BESTAETIGT: alle vier ER-Baender liegen gleichauf
(H1 -0,137..-0,172, H2 -0,049..-0,067). Die Efficiency Ratio trennt auch mit
dem echten Exit nicht. Gate bleibt zu Recht verworfen.
Damit sind alle sechs Legacy-Skripte abgedeckt: EIA bestaetigt, Dead-Hours
nicht selektiv, Bounce nur relativ, ER-Gate zu Recht verworfen.
Einschraenkung unveraendert: der Recheck handelt die UNGEGATETE EMA-Richtung
(ohne min_conf, Breakout-Bestaetigung, HTF-Filter, Raum-Gate) - fuer die
Vergleiche neutral, die absoluten Werte sind nicht das Live-Signal.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
bb17ecff0a |
Beide offenen Vorschlaege umgesetzt: Trail 1,0 + Legacy-Recheck
VORSCHLAG 1 - Trail-Multiplikator 1,5 -> 1,0 (core/exit_model.py LIVE.mult),
live verifiziert ("AKTIVIERT ... mult=1.0x").
Voller Sweep mit FIXEM SL 2,0 (backtest_trailmult.py, 8 Werte 0,5-3,0):
enger ist MONOTON besser. Wave-Signal H1/H2 SigmaR:
0,5 +1258/+2418 · 0,8 +852/+1668 · 1,0 +80/+1360
1,5 -220/+1305 · 2,0 -394/+1198 · 2,5 -1072/+1327
Optimum am RAND = Warnsignal, deshalb Gegentest auf SQUEEZE-Entries mit
Echtkosten (--squeeze): das Setup lebt von Laeufern, muesste also
dagegenhalten - tut es NICHT (1,0: H1 -0,202/H2 +0,010 · 1,5:
-0,219/-0,032). Deshalb 1,0 (besser als 1,5 in beiden Haelften auf BEIDEN
Signalmengen), aber NICHT 0,5: Randwert, und die Sim modelliert keine
Exit-Slippage - ein engerer Trail loest viel haeufiger aus und ist davon
staerker betroffen (real bis 0,75xATR ueber den Stop).
VORSCHLAG 2 - backtest_legacy_recheck.py (NEU): die beiden Legacy-Befunde
nachgerechnet, die live ECHTE Gates steuern.
EIA-Blackout BESTAETIGT: auch mit echtem Exit + Echtkosten in BEIDEN
Haelften schlechter als der Rest (-0,097 / -0,119). Gate ist gedeckt.
DEAD-HOURS reproduzieren NICHT als selektiver Befund: 19 von 22 Stunden
sind in beiden Haelften negativ, keine robust positive Stunde. Die alte
Auswahl (0-7, 12, 16) ist damit nicht mehr gestuetzt. Praktisch folgenlos
(dead_hours ist leer), aber eine Reaktivierung auf der alten Begruendung
waere nicht gedeckt.
Einschraenkung selbst benannt: der Recheck handelt die UNGEGATETE
EMA-Richtung (ohne min_conf, Breakout-Bestaetigung, HTF-Filter, Raum-Gate).
Fuer den Vergleich neutral, die absoluten Werte sind nicht das Live-Signal.
Konsequenz fuer den TF-Churn-Fix: "WARTEN Richtung 43 %" ist eine
Haeufigkeits-, keine Ertragsgroesse - mehr Signale sind nur dann besser,
wenn die freigegebenen Setups auch tragen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
4c1a68a7e1 |
Stufe 3: geteilter Exit-Kern (core/exit_model.py) + Korrektur der Stufe-1-Begruendung
core/exit_model.py (NEU): LIVE:ExitParams als EINZIGE Quelle der Exit-
Parameter; core/trailing.py leitet _TRAIL_START_ATR, _BREAKEVEN_ATR,
_PHASE4_* und _MULT_BY_TF jetzt davon ab statt eigene Zahlen zu halten.
Aendert jemand LIVE.mult, aendern sich Live-Verhalten UND Messung gemeinsam
-> Deployment-Drift-Fall 3 ist konstruktiv unmoeglich geworden. Dazu die
kanonische simulate() fuer Backtests mit Flags timestop/use_tp, um
Teilmodelle EXPLIZIT zu machen statt zu verstecken.
BEFUNDE BEIM REFACTOR - schlimmer als angenommen:
(1) Es gibt mindestens DREI materiell verschiedene Exit-Modelle:
A) Phasen ~ live (_trailing/_exit/_atrfloor/_candle_fade)
B) EINFACH - _TPTRAIL=0.5, kein Breakeven, kein Lock, kein Time-Stop,
_MAXH=240 (_hourly, _hourly_split, _bounce, _events, _deadhour,
_chopgate)
C) Phasen mit be_on=1.0 statt 1,3 (_breakout, _confluence_angle)
=> Dead-Hours, EIA-Blackout, Bounce, Chop-Gate, Stunden-Analyse und
breakout_k ruhen auf einem Exit, der dem Live-System nicht entspricht.
Bewusst NICHT stillschweigend umgestellt (wuerde historische Schluesse
rueckwirkend aendern); als LEGACY_SIMPLE / LEGACY_BE10 markiert.
(2) Selbst die "Phasen"-Skripte weichen voneinander ab: _trailing hat TP
aber keinen Time-Stop, _candle_fade Time-Stop aber kein TP, _atrfloor
liefert Punkte statt R.
(3) backtest_trailing.py koppelt den Initial-SL an mult (sl = entry -
d*mult*atr) statt fix 2,0.
KORREKTUR DER STUFE-1-BEGRUENDUNG: die "67 % groesserer Einzelverlust" war
ein Artefakt von (3) - dort war der Worst-Case per Konstruktion gleich dem
Multiplikator. Sauber nachgemessen mit fixem SL (backtest_trailmult.py, NEU,
80k Bars, 2 Halbjahre):
Trail 1,0 H1 -73 · H2 +1346 · Worst -2,00
Trail 1,5 H1 -325 · H2 +1294 · Worst -2,00 (live)
Trail 2,0 H1 -446 · H2 +1195 · Worst -2,00
Trail 2,5 H1 -1174 · H2 +1223 · Worst -2,00
Trail 3,0 H1 -1088 · H2 +1397 · Worst -2,00
Der Worst-Case ist bei JEDEM Multiplikator identisch -2,00. Die Entscheidung
bleibt richtig (1,5 schlaegt 2,0 und 2,5 in beiden Haelften), nur die
Tail-Begruendung war falsch.
NEU UND OFFEN: Trail 1,0 schlaegt 1,5 in BEIDEN Haelften - eigener
Vorschlag, bewusst nicht ungefragt umgesetzt.
Aequivalenz verifiziert (500 synthetische Kursreihen je Fall): _candle_fade
und _atrfloor sind bitgenau identisch zur neuen simulate().
Live verifiziert: "AKTIVIERT ATR=0.5796 (M30) mult=1.5x".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
97617cd81d |
Deployment-Drift: Stufe 1 (Trail-mult) + Stufe 2 (Entscheidungs-Telemetrie)
Behebt die strukturelle Schwachstelle, die heute dreimal zugeschlagen hat:
Komponenten werden unter anderen Bedingungen BETRIEBEN als VALIDIERT.
Track B schuetzt gegen Overfitting, nicht gegen Deployment-Drift.
STUFE 1 (core/trailing.py): _MULT_BY_TF durchgehend 1,5 (vorher M15 2,0 /
M30 2,5 / H1 3,0) und _MULT_BREAKOUT_ADD 0,5 -> 0,0. Die Staffelung war nie
gemessen; backtest_trailing.py validiert nur 1,5 und die breiteren Werte
sind dort messbar schlechter (80k Bars, 2 Halbjahre):
mult 1,5 H1 SigmaR -249 · H2 +1252 · Worst -1,50
mult 2,0 H1 SigmaR -412 · H2 +1187 · Worst -2,00
mult 2,5 H1 SigmaR -1367 · H2 +1450 · Worst -2,50
Auf M30 fuhr der Bot also 5,5x schlechteres H1 und einen 67 % groesseren
Einzelverlust; bei Breakouts waren es 3,0 - nie getestet. Relevant, weil die
TF-Heuristik oft auf M15/M30 landet (31.07.: 19 von 33 Phasen).
STUFE 2a (wave_rec/history/engine): jede Empfehlung loggt einen
maschinenlesbaren block_reason - deadband, dead_hour, eia, htf_counter,
stretch, min_conf, breakout_pending, entry_room, no_data, stale. DB migriert
(Backup angelegt). Ohne den war nicht feststellbar, WELCHES der Gates die
93 % WARTEN erzeugt (Backtest-Erwartung ~43 %).
STUFE 2b (analyze_divergence.py, NEU): haelt vier Dinge gegen die
Backtest-Erwartung - A Signal-Verteilung, B Gate-Anteile inkl.
"im Backtest modelliert?", C TF-Wechsel-Rate, D0 Modell-Kalibrierung,
D Merkmals-Drift gegen _PB_MU/_SD.
LEHRE AUS DEM BAU SELBST: die Merkmals-Drift (D) haette den realen Fehler
NICHT gefangen - mom3 lag nur 0,50 Sigma unter mu, bei Gewicht 1,43 wurden
daraus aber -0,71 im Logit (23 % statt 41 % vorhergesagt). Deshalb ist D0
der schaerfere Test und die D-Schwelle auf 0,5 Sigma gesetzt.
Erster Lauf nach dem Fix bestaetigt das Nachtraining live:
D0 = 27,0 % vorhergesagt vs 28,0 % real (vorher 23 vs 41).
Stufe 3 (geteilter Exit-Kern) bleibt offen, spaeter und einzeln.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
0208101707 |
TF-Churn-Fix: Breakout-Bestaetigung ueberlebt TF-Wechsel + Verweildauer
Auslöser: User-Frage warum der Bot die Rally am 31.07. (82,5 -> 84,4 in 2 h) nicht gehandelt hat. Befund: in dem Fenster 99x WARTEN und 1x SHORT - und dieser SHORT wurde am Tief autonom eroeffnet (AUTOSIG, -26,31 EUR, per adverse15 geschlossen). Den LONG machte der User um 11:56 von Hand. Der WARTEN-Anteil ist strukturell zu hoch: Backtest-Erwartung (backtest_dist.py) ~43 % Live letzte 24 h 93,2 % Live letzte 7 Tage 88,0 % Live gesamt (93.599 Zeilen) 78,6 % MECHANISMUS (im Log belegt): _choose_tf setzt den Score einer TF hart auf 0,0, sobald sie ueberdehnt ist - genau das passiert M5 IM Trend. Real am 31.07.: M5 sprang zwischen 0,00 und 1,93, die TF wechselte 33x am Tag (Median-Abstand 5 min). Die 1,2x-Hysterese ist dagegen wirkungslos. Und set_timeframe() verwarf bei JEDEM Wechsel die laufende Breakout- Bestaetigung und verankerte sie beim aktuellen Kurs neu. Bei k=0,3 und ATR_M30~0,53 braucht sie ~0,16 $, der Kurs lief ~0,08 $ je 5 min -> die Bestaetigung konnte rechnerisch nie fertig werden. Gleicher Fehlertyp wie beim P(break)-Modell am selben Tag: backtest_breakout.py hat k=0,3 auf einer FESTEN Zeitebene validiert; live wandert sie - die Bedingung, unter der die Messung gilt, existiert im Betrieb nicht. FIX 1 (wave_rec.set_timeframe): _pend wird nicht mehr zurueckgesetzt. Der Anker gehoert zum Signal, nicht zur Zeitebene; bei Richtungswechsel verankert _confirm_breakout ohnehin neu. FIX 2 (engine._tf_loop): Mindest-Verweildauer [trading] tf_min_dwell_s=900. Verifiziert mit synthetischen Szenarien: Fix 1 - Bestaetigung ueberlebt M5->M30 und feuert LONG, Richtungswechsel verankert korrekt neu; Fix 2 - an der ECHTEN Score-Folge vom 31.07. nachgespielt: 4 Wechsel -> 2. NICHT backtestbar (Backtests laufen auf fester TF, das Churning existiert dort nicht). Begruendung ist "stellt die Bedingung her, unter der die Messung gilt", nicht "gemessen besser". Erfolgskontrolle = WARTEN-Anteil muss sich Richtung ~43 % bewegen. Bewusst nicht behoben: der 0,0-Einbruch des Scores bei Ueberdehnung selbst - das waere eine Aenderung der TF-Bewertung und damit messpflichtig. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0944b1c13a |
P(break) neu trainiert auf live-spiegelnder Stichprobe (Weg b) - eingebaut
Behebt die am selben Tag gefundene Merkmals-Diskrepanz: das alte Modell war
auf "Anlauf zu einem beim Entry FIXIERTEN Level" trainiert, live waehlt
_draw_levels das Level jede Sekunde neu -> mom3 live 0,15 statt 1,45 ->
Ausgabe immer ~23 % -> Gate seit Inbetriebnahme faktisch nie aktiv.
backtest_pbreak_retrain.py: Stichprobe spiegelt den Live-Pfad (Level
dynamisch mit Hysterese, gesampelt an JEDEM Bar im 0,15xATR-Band, keine
Anlauf-Bedingung). Kontrolle: Merkmalsmittel der Stichprobe (mom6 0,203 /
mom3 0,202) treffen die live rekonstruierten Werte (0,181 / 0,149).
AUC auf dieser Stichprobe (H2, out-of-sample):
ALT-Modell 0,368 (schlechter als Zufall, 19,2 % vs real 39,4 %)
NEU-Modell 0,654 kalibriert
backtest_pbreak_rvalue.py (R-Ertrag, Echtkosten, Baseline = nur Trailing):
NEU schlaegt ALT in BEIDEN Haelften bei JEDER Schwelle. Gegen die Baseline
gewinnt es bei 0,35/0,45/0,55 in beiden (bei 0,60 kippt H1).
Bestwert 0,35: H1 -149 vs -506 (+357), H2 +1308 vs -110 (+1418).
Nebenbefund: das ALTE Modell war in H1 schlechter als gar kein Auto-Close.
EINGEBAUT: neue _PB_MU/_SD/_W (final auf allen 80k gefittet, n=76.542,
Basisrate 37,8 %, nach H1->H2-Validierung; alte Werte als Kommentar) +
sr_close_pbreak 0,55 -> 0,35, Config-Waechter-Anker mitgezogen.
Verifiziert: Chart-Linien zeigen 43 %/36 % statt 8-15 %.
ACHTUNG - invertiert eine alte Projekt-Regel: mom3-Gewicht dreht das
Vorzeichen (+1,4330 -> -0,5420). Alt: "kriecht ans Level -> 26 % Bruch, mit
Schwung -> laufen lassen". Neu: Anlauf-Schub -> 26,5 % (Level absorbiert
ihn und haelt), Schwung weg vom Level -> 51 %. Beides gilt in seiner
Population (fixiertes vs. dynamisches Level); fuer den Live-Pfad gilt die
neue Lesart.
Offen: auch NEU schliesst bei 0,35 noch ~94-97 % der Positionen (waehlt vor
allem den besseren Moment). Touch-Zahl bringt im neuen Modell nichts mehr
(0,652 vs 0,654) - die dynamische Level-Wahl erfasst den Effekt bereits.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|