In diesem Artikel
Nach diesem Artikel kannst du …
- Kennungen vor einer Umwandlung zu Arrays prüfen.
- Veröffentlichungszeit und abgeschlossene Bars kausal zuordnen.
- Signal, Ausführung und Wiedereinstiegszustand separat definieren.
- Kosten aus tatsächlichen Quote-Seiten ohne Doppelzählung abrechnen.
Begriffe direkt erklärt
Backtesting Spread Ausführungsabweichung (Slippage) ErwartungswertPython ist eine Möglichkeit, Daten und eigene Forschungsregeln zu organisieren. MT5 unterstützt im Strategietester ebenfalls Tests, Optimierung und Mehrwährungs-EAs. Wähle die Umgebung anhand des Daten-, Kontrakt- und Ausführungsmodells. Um Implementierungen zu vergleichen, frierst du denselben Datensatz und dieselben Regeln ein. Ein glatter Chart ersetzt weder zeitlich verfügbare Signale noch tatsächlich modellierbare Ausführungen.
Die Forschungsfrage vor der Bibliothek
Definiere Instrument, Zeiteinheit, Einstieg, Ausstieg, Größe und erlaubte Positionszustände. Erst danach wählst du die kleinste passende Werkzeugkombination. pandas und NumPy unterstützen Datenrechnung; Backtrader arbeitet ereignisorientiert. vectorbt bietet Order-, Signal- und eigene Order-Function-Modi und verändert dabei Cash- und Assetzustände. Vektorisierte Eingaben machen Ausführungen nicht automatisch voneinander unabhängig.
Prüfe Versionen, Lizenz, Datenrechte und Umgebung. Ein Bibliotheksname garantiert weder realistische Ausführung noch eine feste Laufzeit. Daten und späterer Betrieb können zusätzliche Kosten haben. Ein Offline-Lernmodell benötigt weder Live-Zugangsdaten noch einen echten Auftrag.
Originaldaten samt Bedeutung sichern
Speichere Produkt, Anbieter, Quote-Seite, Zeitzone, Intervall und Downloadbereich. Prüfe Kennungen, Duplikate, Reihenfolge und Lücken. Eine Handelspause ist nicht automatisch ein Dateifehler; das Auffüllen kann erfundene Beobachtungen erzeugen. Bewahre die unveränderte Datei und dokumentiere jeden Verarbeitungsschritt.
MetaTrader5s copy_rates_range liefert Zeit, OHLC, Tickvolumen, Spread und reales Volumen. Zeitargumente und Rückgaben verwenden UTC. Die verfügbare Historie hängt vom Terminal und seinen Einstellungen ab; ein angefragter Zeitraum ist kein Vollständigkeitsnachweis. Eine vollständige historische Provisions- oder Finanzierungstabelle liefert diese Barabfrage nicht. Konvertiere UTC ausdrücklich nach Europe/Berlin, bevor du lokale Sessionregeln anwendest.
Unser Kennungstest verwendet abgeschlossene fiktive Preisdatensätze A = 100, B = 102, C = 104. Eine separate Flag-Series steht in der Reihenfolge C, A, B mit Werten 1, 0, 0. pandas multipliziert nach Labels: A: 0, B: 0, C: 104. Werden beide Reihen ohne Kennungen zu Arrays, entsteht positionsweise 100, 0, 0. Wieder A, B, C zugeordnet, ist plötzlich A statt C der Kandidat. Gleiche Arraylängen verhindern diesen Fehler nicht. Die Flagmarkierung ist weder Auftrag noch Ausführung.
Vor to_numpy() Kennungen prüfen; gleiche Längen reichen nicht.
- Mit Series-Labels
- A:0 / B:0 / C:104 – Flag 1 gehört zu C
- Ohne Kennungen
- 100 / 0 / 0 – Erste Arrayposition ist Preis A
- Weitere Prüfung
- Verfügbarkeitszeit – Auch korrektes Label bestätigt noch keine kausale Information
Verfügbarkeit statt bloßer Zeitbeschriftung
Eine H1-Bar mit Eröffnungszeit 10:00 Uhr ist zu diesem Zeitpunkt noch nicht vollständig beobachtet. Ihr vollständiges OHLC steht erst nach Periodenende fest. Bei Resampling bestimmt closed die Intervallzugehörigkeit, label die angezeigte Kante. Eine andere Beschriftung macht das Aggregat nicht früher verfügbar.
Makrodaten verknüpfst du nach dem Veröffentlichungszeitpunkt der damals verfügbaren Datenversion, nicht nur nach ihrem Berichtsmonat. merge_asof verlangt sortierte Schlüssel. backward sucht früher oder gleich, nearest kann später auswählen. Keiner dieser Modi erkennt automatisch spätere Revisionen. Definiere Toleranz und Reihenfolge zeitgleicher Ereignisse.
Die Entscheidung fällt hypothetisch um 10:04 UTC. Gespeichert sind Veröffentlichungen um 10:00 mit Wert 50 und 10:05 mit Wert 60. Ohne Toleranzbegrenzung wählt backward den vier Minuten alten Wert 50. Nearest wählt den nur eine Minute entfernten, aber zukünftigen Wert 60. Eine inklusive backward-Toleranz von zwei Minuten liefert keinen Treffer. Diesen fehlenden Wert darfst du nicht durch Zukunftsinformation ersetzen.
Ein eigener Barvergleich nimmt für die ersten zwanzig Bars Highs von 100 bis 119 an, jeweils Open = High − 0,5, Low = High − 2 und Close = High − 1. Bar 21 hat O120/H121/L118/C120,5; Bar 22 O120,6/H122/L119/C121. Das sind beliebige Beispielpreise, keine FX-Marktdaten.
previous_high = bars["high"].shift(1).rolling(20).max()
signal = bars["close"] > previous_high
next_bar_signal = signal.shift(1, fill_value=False)Auf Bar 21 ist das vorherige Zwanzig-Bar-Hoch 119, daher ist 120,5 > 119 wahr. Mit dem aktuellen High 121 wäre die Bedingung falsch. Die letzte Zeile ordnet das beobachtete Signal Bar 22 zu. Sie legt keinen Fillpreis, keine Annahme des Auftrags und keinen Ausstieg fest. Verwende nur abgeschlossene Eingangs-Bars und definiere die übrigen Ereignisse separat.
Ausführung, Kosten und Zustand modellieren
Im dokumentierten Backtrader-Standardmodell wird ein nach Verarbeitung der aktuellen Bar platzierter Market-Auftrag zum Open der nächsten verfügbaren Bar ausgeführt. Andere Einstellungen können das ändern. Liegen Stop und Ziel innerhalb derselben OHLC-Bar, verraten deren vier Preise nicht, welches Ereignis zuerst eintrat.
Bei mehreren Instrumenten brauchen gemeinsame Mittel, verfügbare Margin und gleichzeitig angefragte Aufträge eine Reihenfolge. Die Addition unabhängiger Equity-Kurven kann Trades enthalten, die ein gemeinsames Konto nicht finanzieren könnte. Definiere außerdem Finanzierung, Kontraktgröße, Umrechnung, Ablehnungen und bei zufälliger Slippage die Verteilung, Seed und Version.
Unser Wiedereinstiegsmodell hat auf fünf Bars Bedingungen wahr, wahr, wahr, falsch, wahr. Beide Varianten steigen auf Bar 1 ein. Auf Bar 2 schließt ein Stop die Position vor der Einstiegsprüfung; weitere Ausstiege gibt es nicht. Wer bei flacher Position und wahr sofort einsteigt, eröffnet auf Bar 2 erneut. Wer erst ein neues falsch zur Freigabe verlangt, wartet, wird auf Bar 4 freigegeben und eröffnet auf Bar 5. Beide zählen zwei Einstiege mit unterschiedlichen Kennungen. Das ist unsere definierte Zustandsmaschine, keine Behauptung über Bibliotheksdefaults.
Ein vollständiges EUR/USD-Rechenmodell
Du kaufst hypothetisch 10.000 EUR zu Ask 1,1002 USD je EUR; gleichzeitig ist Bid 1,1000. Später verkaufst du alle Einheiten zu Bid 1,1012 bei Ask 1,1014. Ein Pip entspricht 0,0001 USD je EUR. Der Abstand der tatsächlichen Fills beträgt zehn Pips und damit 10 USD. Je 1 USD Provision auf beiden Seiten lassen 8 USD netto. Finanzierung und zusätzliche Slippage sind hier null.
Weitere zwei Pips Einstiegsspread abzuziehen ergäbe fälschlich 6 USD: Die Quote-Seiten sind schon in den Fillpreisen enthalten. Für einen EUR-Bericht benötigt auch das Nettoresultat eine definierte Umrechnung. Bei einem separat angenommenen Umrechnungskurs von 1,1000 USD je EUR entsprechen 8 USD rund 7,27 EUR, ohne Umrechnungsgebühr. Das ist keine aktuelle Kursangabe.
Eine separate gleich große R-Stichprobe hat vierzig Gewinne zu +2R und sechzig Verluste zu −1R. Gewinne 80R minus Verluste 60R ergeben 20R, Mittel +0,2R und Profit Factor rund 1,33. Kosten von 0,1R je Trade verändern die Ergebnisse auf +1,9R und −1,1R: Gewinne 76R, Verluste 66R, netto 10R, Mittel +0,1R, Profit Factor rund 1,15. Es handelt sich um Arithmetik, keinen ausgeführten Backtest.
Ledger und Auswahlverfahren nachvollziehbar machen
Bewahre offene Equity und geschlossene Trades getrennt. Beginne die Drawdownreihe mit dem Anfangskapital und entferne Zahlungsströme aus der Strategierendite. Eine Kennzahl muss aus der datierten Reihe rekonstruierbar sein. Fixiere chronologische Trainings- und Testfenster vor der Auswahl und speichere sämtliche getesteten Instrumente, Filter, Parameter und verworfenen Versionen. Wenige Parameter bedeuten nicht wenige Auswahlversuche; die Forschung zu Backtest-Overfitting untersucht genau diese Wiederholung.
Auch 75 % Trefferquote diagnostizieren keinen Bias: 75 hypothetische Gewinne à +0,2R und 25 Verluste à −1R liefern 15R minus 25R, also −10R vor Kosten und Profit Factor 0,6. Prüfe Kausalität, Kosten und Auswahl unmittelbar statt mit universellen Schwellen.
Mit wenigen vollständig definierten Datensätzen beginnen
Protokolliere zunächst von Hand Kennungen, Verfügbarkeitszeiten, erlaubte Ausführungen und jeden Zustandswechsel. Rechne danach die Fills und Kosten ab und leite Ergebnisse aus dem Ledger ab. Vergleiche alternative, benannte Ausführungsannahmen auf denselben eingefrorenen Regeln. Bewahre Versuchsliste und unberührte Fenster; ein fester Performanceabfall verrät seine Ursache nicht automatisch.
- Protokolliere wenige Datensätze von Hand mit Kennung, Verfügbarkeitszeit und jedem Zustandswechsel. Prüfe bei zeitbasierten Verknüpfungen die tatsächlich vorher verfügbare Zeile; vier Minuten alter Input und eine Minute zukünftiger Input sind verschiedene Fälle, auch wenn der zukünftige Abstand kleiner erscheint.
- Rechne tatsächliche Modellfills und getrennte Gebühren ab und leite den Erfolg aus dem Ledger ab. Dokumentiere zehn USD brutto, acht USD netto und die ausdrücklich angenommene EUR-Umrechnung; ein Midpreis oder bereits enthaltener Spread darf die ausführbaren Kursseiten und Buchungen nicht doppelt ersetzen.
- Vergleiche alternative benannte Ausführungsannahmen unter denselben eingefrorenen Regeln und bewahre Versuchsliste sowie unberührte Fenster. Prüfe einzelne Entscheidungen, Intrabargrenzen und Kosten statt nur Endkurven; ein bestimmter Performanceabfall erklärt seine Ursache nicht und selbst 75 Prozent Gewinner können im zugewiesenen Auszahlungsmodell verlieren.
Prüfe dein Verständnis
Etwa 2 Minuten Übung.
Antwort und Erklärung anzeigen
Richtig: Der vergangene Wert ist zu alt, der spätere noch nicht verfügbar.
Weitere Fragen
Welche Pythonkenntnisse brauche ich für den Einstieg?
Du solltest Daten lesen und prüfen, Funktionen verwenden sowie Labels von Arraypositionen unterscheiden können. Reproduziere zuerst ein kleines vollständig festgelegtes Modell. Korrekte Zuordnung allein ersetzt weder Timing noch Positionszustand oder Ausführung. Sichere Versionen und prüfe Zwischendatensätze; eine feste Lernzeit oder Zeilenzahl beweist keine Einsatzreife.
Ist Backtrader oder vectorbt realistischer?
Vergleiche das dokumentierte Simulationsmodell mit deinen Anforderungen. Backtrader arbeitet ereignisorientiert; sein Standard-Marketmodell verwendet das nächste verfügbare Open. vectorbt unterstützt mehrere Modi und aktualisiert Cash sowie Assetzustände. In beiden musst du Defaults, Kosten und Ereignisreihenfolge prüfen. Ein Bibliotheksname garantiert weder Geschwindigkeit für jeden Datensatz noch realistische Ergebnisse.
Woher bekomme ich geeignete historische Daten?
Identifiziere Produkt, Anbieter, Quote-Seite, Zeitbasis und verfügbare Historie. MetaTrader5-Barabfragen verwenden UTC und die vorhandene Terminalhistorie; sie liefern keine vollständigen historischen Gebühren. yfinance nutzt Yahoo-Daten, CCXT Daten von Kryptobörsen. Prüfe die konkrete Reihe und Nutzungsrechte, bewahre die Originaldatei und dokumentiere Lücken oder Änderungen, statt Werkzeugnamen als Qualitätsrang zu verwenden.
Wie prüfe ich ungewöhnlich gute Backtestergebnisse?
Rekonstruiere zuerst die damals verfügbaren Signale, bestätige das Fillmodell und rechne Kosten in korrekten Einheiten nach. Bewahre sämtliche Auswahlversuche und vorher definierte Testfenster. Trefferquote und Profit Factor allein identifizieren keinen Fehler. Ungewöhnliche Werte begründen eine Untersuchung der Kausalität und Auswahl; sie beweisen weder einen Vorteil noch automatisch Overfitting.
Quellen und Nachvollziehbarkeit
- pandas: Series und Label Alignment
Series-Rechenoperationen richten sich an Labels aus; unindexierte Arrays rechnen positionsweise.
- pandas: merge_asof
Sortierte Schlüssel, backward/nearest und Toleranz; Verfügbarkeitszeit und Datenrevision separat modellieren.
- pandas: DataFrame.resample
closed definiert Intervallzugehörigkeit, label die Beschriftung; kein Ersatz für Verfügbarkeitszeit.
- Backtrader: Orders — Creation/Execution
Dokumentiertes Standardmodell für Market-Aufträge nach Verarbeitung einer Bar; andere Konfigurationen gesondert prüfen.
- vectorbt: Portfolio
Orders-, Signals- und Order-Function-Modi mit Zustandsänderungen für Cash und Assets.
- MetaQuotes: Python copy_rates_range
UTC, Rückgabefelder und verfügbare Terminalhistorie; keine vollständige historische Gebührentabelle.
- Bailey et al. — Pseudo-Mathematics and Financial Charlatanism (2014)
Originalarbeit zu vielen getesteten Varianten und Backtest-Überanpassung.
Rechenfälle sind ausdrücklich angenommene Beispiele. Sie ersetzen weder aktuelle Marktdaten noch die Spezifikation deines Anbieters.
