Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Daytrader — Trendfolge-Signal- & Order-Vorschlags-Tool

Scannt ein Universe aus US-Aktien und DAX-Werten auf Pullbacks in intakten Aufwärtstrends (Tageskerzen, Swing-Trading, typische Haltedauer 1–4 Wochen) und liefert konkrete Limit-Order-Vorschläge zum manuellen Ausführen bei Scalable/Gettex.

Die Strategie ist Long-only. Der Scanner erzeugt ausschließlich BUY-Signale, der Backtest hat nie etwas anderes validiert, und seit dem 06.08.2026 platziert auch der IBKR-Paper-Test keine Shorts mehr (→ Long-only).

Zwei Ausführungswege: manuell bei Scalable/Gettex (der eigentliche Zweck) und ein IBKR-Paper-Konto als Betatest, das die Proposals automatisch platziert (notebooks/proposal_trader.ipynb) — nur zum Messen, nicht mit echtem Geld.

Git-Workflow für dieses Repo: README_GIT.md.

Strategie (evidenzbasiert)

Reine Trendfolge auf Basis des Momentum-Effekts (Jegadeesh & Titman 1993, eines der robustesten Ergebnisse der Asset-Pricing-Forschung):

  1. Trendrichtung — Kurs über SMA50 und SMA50 steigt (Slope ≥ 1,5 %/20 Tage)
  2. Trendstärke — Abstand zum SMA50 in ATR-Einheiten (kontinuierlicher Score)
  3. Pullback-Timing — Einstieg nur nach Rücksetzer vom 10-Tage-Hoch, nie am Breakout-Tag ("Kauf am Top"-Schutz)
  4. Marktregime-Filter je Markt — BUY-Signale nur, wenn der passende Referenzindex über seinem SMA200 notiert (US: SPY, DE: DAX; Faber 2007 / Zeitreihen-Momentum). Backtest: Das DAX-Regime für DE-Titel schlägt das SPY-Regime deutlich (2022: −110 % → −72 %, 2023: −50 % → +52 %).

Bewusst kein RSI, Bollinger, MACD oder VWAP — diese Indikatoren haben nach Kosten keine robuste empirische Grundlage.

Backtest-Ergebnisse (Stand Juli 2026)

Getestet auf splitbereinigten Tagesdaten 2020-07 bis 2026-07 (Alpaca für US, yfinance für Xetra; 0,3 % Round-Trip-Kosten, Fill-/Gap-Simulation, konservative Regel "Stop-Loss vor Take-Profit bei Mehrdeutigkeit"). Parametertuning nur In-Sample (bis 2023), Out-of-Sample (ab 2024) validiert:

Kennzahl US (46 Titel) US + DAX (82 Titel)
Trades ~1.200 ~2.030
Ø netto/Trade ~+0,9 % ~+0,6 %
Profit-Faktor ~1,3–1,4 ~1,2
Haltedauer Median 8–9 Handelstage Median 9 Handelstage

Ehrlich: Der historische Edge der DAX-Titel ist deutlich dünner als der der US-Titel (~+0,16 %/Trade netto mit DAX-Regime vs. ~+0,9 % bei US) — Momentum lief 2021–2026 auf deutschen Einzelwerten schwächer. DE-Signale also eher selektiv handeln (höhere Konfidenz verlangen), US bleibt Kern.

Erkenntnisse, die in die Konfiguration eingeflossen sind:

  • TP 3,0×ATR / SL 2,0×ATR schlägt das alte 2,5/1,5 in beiden Zeitfenstern deutlich (Gewinner länger laufen lassen). Noch weitere Ziele wären historisch besser gewesen, verschieben die Haltedauer aber Richtung Positionstrading.
  • SPY>SMA200-Filter reduzierte die Trades im Bärenmarkt 2022 von 89 auf ~25 bei nahezu unverändertem Gesamtertrag.
  • Zeit-Stops schaden (getestet 5/10/15 Tage) — Positionen laufen bis SL/TP.
  • Parabolik-Dämpfung ab 15 % Slope kostete Rendite (bestrafte intakte starke Trends), Schwelle jetzt 25 %.
  • Gewinn ist breit verteilt (18 von 22 Symbolen netto positiv), kein reiner NVDA-Effekt; Strategie bleibt bis ~1 % Round-Trip-Kosten profitabel.
  • Achtung: 2022 bleibt trotz Filter negativ. Trendfolge verliert in Bärenmärkten — der Filter begrenzt nur, wie oft man dann überhaupt drin ist.

Reproduzieren / nach Konfig-Änderungen neu prüfen:

python3 -m daytrader.backtest             # nutzt Cache in backtest_data/
python3 -m daytrader.backtest --refresh   # Kursdaten neu laden
python3 -m daytrader.backtest --cost 0.6  # konservativere Kostenannahme

Long-only (seit 06.08.2026)

Der Kern war immer Long: backtest.py überspringt alles außer BUY, und der Regime-Filter ist ein Long-Filter. Parallel lief ab 14.07.2026 im IBKR-Paper-Konto ein Short-Experiment mit, um zu klären, ob sich ein Live-Weg dafür lohnt (Derivate bei Scalable vs. Brokerwechsel). Die Antwort ist nein. Am 06.08.2026 wurde die Short-Seite abgeschaltet (SIDES = ("BUY",) in Abschnitt 1 des Notebooks).

Stand bei Abschaltung (82 geschlossene Trades, Fenster 14.07.–06.08.2026):

geschlossen TP SL Trefferquote Ø netto/Trade realisiert
Long 50 26 24 52 % −0,48 % −90,28 EUR
Short 32 1 31 3 % ≈ −8,5 % −1.032,59 EUR
gesamt 82 27 55 33 % −3,62 % −1.122,87 EUR

Signifikanz: gesamt t = −4,10, p = 0,000, 95 %-KI [−5,38 %, −1,87 %] — signifikant negativ, und der Treiber ist eindeutig die Short-Seite. Nur Long t = −0,53, p = 0,599 — nach 50 Trades nicht von null zu unterscheiden, also weder bestätigt noch widerlegt. 1 Gewinner aus 32 Short-Trades ist dagegen kein Rauschen mehr.

Dazu der Kapital-Effekt: rund 6.643 EUR (≈ 25 % des gebundenen Kapitals) lagen im Short-Buch, und die realisierten Short-Verluste haben über effective_budget_eur() das Arbeitskapital verkleinert. Der Budget-Guard hat mit diesem Geld keine Long-Trades mehr platziert — der Long-Test lief also mit künstlich verkleinertem Buch.

Beweisstück (Dashboard-Screenshot, Logs, Methodik inkl. des am selben Tag gefixten Exit-Ledger-Bias): daytrader/Test_Demoportfolio/archiv/2026-08-06_shorts_gestoppt/. Die Short-Historie bleibt in trades_log.csv erhalten und wird im Dashboard weiter getrennt ausgewiesen — sie wird nur nicht fortgeschrieben. Offene Shorts liefen gegen ihre GTC-Brackets aus.

Was der Long-only-Nachbau ergibt — und was nicht

analysis/longonly_replay.py spielt dieselben Handelstage aus dem Point-in-Time-Archiv PROPOSALS/proposals_YYYY-MM-DD.npy unter Long-only-Regeln nach, um die Stichprobe zurückzuholen, die der Budget-Guard gekostet hat — statt den Test neu zu starten. Selbsttest zuerst: auf die tatsächlich platzierten Long-Trades eingeschränkt, gegen das echte Ergebnis gehalten.

                              n     TP/SL   Quote   Ø netto       t      netto
Selbsttest (Nachbau)         66   29 / 37    44 %   −0,66 %   −0,91   −213,98 EUR
Selbsttest (echt, 06.08.)    50   26 / 24    52 %   −0,48 %   −0,53    −90,28 EUR
Kontrafaktisch Long-only     90   36 / 54    40 %   −1,27 %   −2,08   −497,05 EUR

Lesart, ehrlich:

  • Der Nachbau trifft Richtung und Größenordnung, ist aber ~0,2 pp/Trade pessimistischer als die Realität (MKT-Fill vs. kalibriertes Limit, Bar-Auflösung statt echtem Fill). Der Kontrafaktische ist damit eher eine Untergrenze als eine Punktschätzung.
  • Trotzdem: Long-only ist über dieses Fenster ebenfalls negativ, mit t = −2,08 sogar signifikant. Das Abschalten der Shorts beendet einen klar kaputten Zweig — es macht den Long-Kern nicht profitabel. Drei Wochen sind kein Urteil über eine Strategie mit 8–9 Tagen Haltedauer, aber sie sind auch keine Bestätigung.
  • Von 450 Long-Proposals (Konfidenz ≥ 0,6) wurden 136 platziert; 314 fielen am Duplikat-Schutz (offene Position im selben Symbol), 0 am Budget-Deckel. Der begrenzende Faktor ist also nicht das Kapital, sondern die Universe-Breite.
  • Die aus dem Live-Test aufgestellte Konfidenz-Hypothese („hohe Konfidenz = besser") hält mit größerem n nicht: Bucket 1,00 liegt bei n = 48 auf −2,30 %/Trade (t = −3,12), Bucket 0,60–0,79 bei −0,46 %. Falls überhaupt, zeigt das Muster in die Gegenrichtung.
.venv/bin/python analysis/longonly_replay.py   # Kursdaten-Cache: analysis/replay_cache/

Warum Limit-Orders die manuelle Latenz lösen

Du tippst die Order erst nach dem Signal ein. Eine Limit-Order füllt aber erst beim Zielpreis — egal wie lange du brauchst. Auf Tageskerzen mit mehrtägiger Ordergültigkeit (GTD) ist Geschwindigkeit ohnehin kein Faktor.

Gettex-Ausführung & Datenquellen

Ausführung auf Gettex. Signale: US via Alpaca (IEX), DAX via yfinance (Xetra-Ticker .DE, EOD/leicht verzögert, kein API-Key nötig). Für die Tageskerzen-Strategie reicht das völlig — gescannt wird einmal täglich nach Börsenschluss, Echtzeit ist bei GTD-Limit-Orders kein Faktor. (Twelve Data blieb als Provider im Code; deren Free-Tier deckt Xetra nicht ab — das war der frühere Verbindungsfehler.) limit_offset_pct: 0.5 fängt den Market-Maker-Spread mit ab.

Setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

export ALPACA_KEY_ID=...             # US-Titel (Free-Tier, IEX)
export ALPACA_SECRET=...
# DAX-Titel laufen über yfinance — kein Key nötig.
export ANTHROPIC_API_KEY=...         # optional, nur für News-Gate

Nutzung

python3 -m daytrader.scan --once               # einmal scannen (nach US-Schluss)
python3 -m daytrader.scan --every 86400        # täglich
python3 -m daytrader.scan --once --min-conf 0.6

Tageskerzen sind nach US-Börsenschluss final — ein Scan pro Tag (z. B. nach 22:15 Uhr deutscher Zeit) reicht.

Aufbau

Kern (daytrader/):

  • providers.py — Alpaca (US, splitbereinigt), yfinance (Xetra, keyless), Twelve Data (optional), austauschbar.
  • signals.py — SMA-Trend, Slope, ATR, Pullback; kontinuierliches Scoring.
  • proposals.py — Signal → Limitpreis + SL/TP (ATR-adaptiv) + Gültigkeit.
  • scan.py — CLI; Universe-Scan inkl. Regime-Filter je Markt (SPY/DAX).
  • backtest.py — Backtest der kompletten Pipeline auf der aktuellen Config. Long-only: überspringt alles außer BUY.
  • llm_gate.py — optional: prüft auf News/Earnings (kein Handelsentscheid).

Betatest (daytrader/Test_Demoportfolio/, IBKR-Paper-Konto):

  • ibkr_proposal_trader.py — platziert Proposals als Market-Entry + GTC-Bracket, Budget-Guard, Duplikat-Schutz, sides-Filter (jetzt ("BUY",)).
  • ibkr_stats.py — Statistik-Dashboard aus trades_log.csv / fills_log.csv / exits_log.csv; weist Long und Short getrennt aus.
  • ibkr_bracket_paper.py — Bracket-Order-Mechanik gegen TWS.
  • *_log.csv — Handelsverlauf des Paper-Kontos (inkl. der nicht fortgeschriebenen Short-Historie).
  • archiv/2026-08-06_shorts_gestoppt/ — Beweisstück zur Short-Abschaltung.

Auswertung (analysis/):

  • longonly_replay.py — Long-only-Nachbau des Betatests aus dem PROPOSALS-Archiv, mit Selbsttest gegen das echte Ergebnis.
  • satellit_kadenz_backtest.py — Kern-Satellit-Kadenz (täglich vs. wöchentlich vs. monatlich).

PROPOSALS/proposals_YYYY-MM-DD.npy ist das Point-in-Time-Archiv jedes Scans — die Grundlage dafür, dass Nachbauten frei von Survivorship-Bias sind.

Universe anpassen

In config/config.yaml unter universe: Titel ergänzen/entfernen — danach python3 -m daytrader.backtest --refresh laufen lassen, um zu sehen, wie die Strategie auf den neuen Titeln historisch abgeschnitten hätte.

Wichtige Hinweise

  • Backtest ≠ Zukunft. Die Parameter sind auf 2020–2026 validiert, einer Phase mit außergewöhnlich starkem US-Tech-Momentum. Erst mit kleinen Positionen / Paper-Trading starten.
  • Der Live-Test bestätigt den Backtest bisher nicht. Drei Wochen Paper-Trading sind zu kurz für ein Urteil, laufen aber gegen die Backtest-Erwartung (siehe Long-only). Der Betatest läuft weiter, um Stichprobe zu sammeln.
  • Ergebnisse sind additiv gleichgewichtet gerechnet, ohne Positionsgrößen- und Portfolioeffekte (bis zu ~10 parallele Signale möglich).
  • Free-Tier-Daten haben Limits/Delays. Für den Tagesscan irrelevant.
  • Keine Anlageberatung. Eigenverantwortliche Prüfung jedes Vorschlags.

About

Trade proposals based on trend analysis (Jegadeesh-Titman-Momentum)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages