Zum Inhalt springen

Drei Fehler, drei bestandene Tests, keiner entdeckt

ETHUSDT-Perpetual-Chart im 4-Stunden-Takt mit zwei nebeneinander eingezeichneten Rückblickfenstern, eines über 23 Balken und eines über 22 Balken, also die Länge, die der Pine-Quellcode berechnet, und die Länge, die der Python-Nachbau aus derselben Formel berechnet hat.
Derselbe Rückblick, zweimal berechnet. Pine rundet 22,5 von der Null weg und erhält 23. Python 3 rundet auf die gerade Zahl und erhält 22. In keiner der beiden Sprachen warnt Sie irgendetwas davor, dass sich die Konvention geändert hat.

Wenn Sie jemals einen Indikator nach Python portiert haben, um ihn zu backtesten, oder einem Skript vertraut haben, weil es mit einer Verifizierung geliefert wurde, dann geht es hier um die Lücke, die diese beiden Dinge offen lassen.

Wir haben drei unserer eigenen Indikatoren nachgebaut, damit ein Backtest über sie laufen konnte. Alle drei Nachbauten enthielten eine falsche Konstante. Alle drei bestanden ihre Validierung. Kein einziger wurde von einem Test erwischt.

Warum einen Indikator überhaupt nachbauen

Ein Pine-Skript läuft auf Ihrem Chart. Es läuft nicht in einer Schleife über sechs Jahre Historie, und es beantwortet nicht, ob ein Signal sich tatsächlich auszahlt. Um das zu fragen, bauen Sie es in etwas nach, das Sie tausendfach laufen lassen können.

Genau bei diesem Nachbau hört ein Indikator klammheimlich auf, derselbe Indikator zu sein.

Der Fehler, der am meisten gekostet hat, und es ist ein Balken

Eine der Längen in Volume Oracle wird aus dem Zeitrahmen abgeleitet:

target bars   = 36 hours × 60 / 240 minutes = 9
regime length = round(9 × 2.5) = round(22.5)

Pines math.round bricht Gleichstände von der Null weg auf. Es ergibt 23. Das round() von Python 3 verwendet kaufmännisch-gerades Runden, das Gleichstände zur geraden Zahl hin auflöst. Es ergibt 22.

Beide sind korrekte Implementierungen des Rundens. Es sind schlicht unterschiedliche Konventionen, und nichts warnt Sie davor, dass Sie von der einen in die andere gewechselt sind.

Jeder aus dieser Zahl abgeleitete Rückblick verschob sich mit ihr. Das Ergebnis in der am besten belegten Zeile eines Durchlaufs über 36 Signale:

Version48-Stunden-VorteilTrefferquoten
nachgebaut, Länge 22+0,423 %511216
korrekt, Länge 23+0,260 %501223

Ein Abschlag von 38 % durch eine Rundungskonvention.

Dann haben wir die Lehre daraus falsch festgehalten

In unserer Notiz stand, es trete nur bei 4H auf. Sie war aus dem einen Zeitrahmen heraus geschrieben, der gerade auf dem Prüfstand stand, und blieb zwei Monate lang so stehen.

Dieselbe Rechnung über jeden Zeitrahmen laufen lassen:

ZeitrahmenRegimelängeFlusslängeErgebnis
5m45 vs. 4523 vs. 22weicht ab
2H45 vs. 4523 vs. 22weicht ab
4H23 vs. 2212 vs. 11weicht ab
8H53 vs. 5227 vs. 26weicht ab
1D18 vs. 189 vs. 9Gleichstand, stimmt überein
3D, 1W15 vs. 158 vs. 8Gleichstand, stimmt überein

Vier von sechzehn, nicht einer.

Aus dieser Tabelle fallen zwei Dinge heraus, die durch bloßes Nachdenken nicht zu holen waren.

Ein Gleichstand genügt nicht. 1D, 3D und 1W landen alle genau auf ,5 und stimmen überein. Kaufmännisch-gerades Runden verschiebt nur einen Gleichstand, dessen kaufmännisch aufgerundete Antwort ungerade ist, also ist round(17.5) so oder so 18. Rund die Hälfte aller Gleichstände ist harmlos, und genau deshalb beweist die Stichprobe an einem einzigen gar nichts.

Die Abweichung kann einen Schritt zu spät eintreffen. Bei 5m und 2H stimmt die erste Länge bei 45 überein. Die nächste Zeile, round(45 × 0.5), ergibt erneut 22,5, und dieser Wert spaltet sich auf. Wenn Sie die erste Konstante prüfen und weitergehen, geben Sie beide Zeitrahmen fälschlich frei.

Die anderen beiden, kurz

Harmonic normalisiert einen Oszillator, indem er ihn auf ein rollierendes Band beschneidet. In der Quelle wird jeder Balken von seinem eigenen Band beschnitten. Der Nachbau beschnitt ein ganzes Fenster von 200 Balken mit dem Band des aktuellen Balkens, was eine andere Funktion ist. Gemessener Unterschied über 11.497 Balken: im Mittel 0,47 Punkte. Ein echter Übertragungsfehler ohne materielle Wirkung.

Diesen einen haben wir zudem aufgeblasen, bevor wir ihn gemessen haben. Er wurde beim bloßen Lesen des Codes als ziemlich sicher die Abweichung von 9 % angekündigt. Die Zahl war 0,47. Ein echter Fehler und ein materieller Fehler sind zwei verschiedene Behauptungen, und die Größenordnung wird gemessen, bevor die Wirkung benannt wird.

Plutus Flow mittelt das Volumen über 50 Balken, um Ausschläge zu erkennen. Der Nachbau nahm 20, weil das die Zahl war, die wir zu kennen glaubten. Wirkung: unter einem Zehntel Prozentpunkt, keine Vorzeichenwechsel. Am Urteil änderte sich nichts, aber die Zahl war falsch und ist jetzt richtig, und das ist der einzige Maßstab, der zählt.

Der Teil, der die eigentliche Lehre ist

Das hat die Validierung jedes Nachbaus damals gemeldet.

Nachbauseine eigene Prüfungwas das bedeutete
Volume Oracle3 von 3 davor, 3 von 3 danachkonnte sie nicht auseinanderhalten
Harmonic6 von 8 davor, 5 von 8 danachbewertete die fehlerhafte Version höher
Plutus Flownie ausgeführt

Bei der mittleren Zeile lohnt es sich zu verweilen. Die Validierung zog den falschen Code vor. Hätten wir die Prüfung entscheiden lassen, hätte sie uns in den Fehler zurückargumentiert.

Eine Validierung, die einen einzelnen Ausgabewert vergleicht, kann eine falsche Eingabekonstante nicht erkennen. Die Ausgabe ist ein zu grobes Sieb. Viele verschiedene falsche Parametersätze erzeugen heute dieselbe Regimebezeichnung, denselben Kreuzungszustand, dieselbe Farbe im Chart. Sie unterscheiden sich auf Balken, die Sie gerade nicht ansehen, und genau dort lebt ein Backtest.

Was stattdessen zu tun ist

Geben Sie jeden abgeleiteten Parameter aus. Jede Länge, jede Schwelle, jeden Multiplikator. Vergleichen Sie sie Zeile für Zeile mit der Quelle, bevor Sie irgendetwas bewerten.

Behalten Sie die Ausgabeprüfung. Sie fängt eine andere Fehlerklasse ab und ist notwendig. Sie ist nur bei Weitem nicht hinreichend, und alle drei sind glatt an ihr vorbeispaziert.

Der ehrliche Geltungsbereich

Der Pine-Code war in allen drei Fällen korrekt. Falsch war der Apparat, der gebaut wurde, um ihn zu prüfen, und das ist die unangenehmere Fassung des Problems: Das Messgerät driftete, und die Selbstprüfung des Messgeräts sagte, es habe das nicht getan.

Die Zahl von 38 % ist eine Zeile, ein Durchlauf, ein Zeitrahmen, innerhalb der Stichprobe, und sie ist aus unserer eigenen Aufzeichnung zitiert statt neu berechnet. Das Rundungsergebnis ist mit einem einzigen Befehl reproduzierbar, und beim Korrigieren kam heraus, dass unsere eigene Notiz dazu zwei Monate lang falsch gewesen war.


Vergangene Messung unseres eigenen Werkzeugs, im Nachhinein beschrieben. Nichts davon ist eine Empfehlung oder ein Hinweis auf künftige Ergebnisse.