Was ist Pyne?
Du lernst Pyne code kennen, seine Verbindung zu Python und die Rolle der PyneIDE.
Pyne ist ein System zum Erstellen von Programmen, die mit Marktdaten arbeiten. Mit diesen Programmen kannst du Werte aus Kursen berechnen und darstellen oder die Regeln einer Handelsstrategie festlegen. In diesem Buch durchlaufen wir die gesamte Arbeit vom Schreiben des Programms bis zur Prüfung seiner Ergebnisse.
Was nennen wir Pyne code?
Wir schreiben die Programme in Pyne code. Das ist eine eigenständige Programmiersprache zur Verarbeitung von Marktdaten. Der Code beschreibt, was das System berechnen und anzeigen soll und unter welchen Bedingungen eine Aktion ausgeführt wird.
edge erlaubt einen festgelegten Teil der Möglichkeiten von Python. Wir lernen deshalb nicht die gesamte, universell einsetzbare Sprache Python.Ein Indikator kann beispielsweise den Durchschnittskurs der letzten zehn Kerzen berechnen und als Linie im Kurschart darstellen. Ein Kurschart zeigt, wie sich Preise im Laufe der Zeit verändern. Eine Strategie legt außerdem Ein- und Ausstiegsregeln fest: Sie eröffnet beispielsweise eine Kaufposition, sobald eine Bedingung erfüllt ist. Lässt du sie auf historischen Daten laufen, kannst du untersuchen, welche Trades diese Regeln unter den angegebenen Ausführungsbedingungen ausgelöst hätten. Das nennt man einen Backtest.
Zuerst erstellen wir einfache Indikatoren. An ihnen lernst du die Daten und die Sprache kennen, bevor du Handelsregeln schreibst.
Was hat Pyne mit Python zu tun?
Pyne code verwendet die Schreibregeln von Python. Diese Regeln heißen Syntax: Sie bestimmen beispielsweise, wo Klammern stehen und wie zusammengehörige Zeilen gekennzeichnet werden. Du brauchst vorher kein Python zu lernen; die nötigen Regeln lernst du an den Beispielen dieses Buchs.
Die Dateien haben deshalb die in Python übliche Endung .py. Mit installiertem PyneCore lässt sich Pyne code auch in einer Python-Laufzeit ausführen. Python stellt die Laufzeitumgebung bereit, PyneCore die besondere Funktionsweise und die Funktionsbibliothek von Pyne.
Wie verarbeitet das Programm die Daten?
In den Beispielen erhalten wir Marktdaten als Folge von Kerzen. Eine Kerze fasst die Daten eines Zeitraums zusammen, darunter Eröffnungs- und Schlusskurs. Bei Tagesdaten steht eine Kerze für einen Tag.
PyneCore führt die Berechnungen des Programms nacheinander auf diesen Kerzen aus. So kann es für jede Kerze einen Durchschnitt aus den bis dahin verfügbaren Kursen neu berechnen. Dabei verwaltet es auch frühere Berechnungsergebnisse und Daten, die zwischen den Kerzen erhalten bleiben sollen.
Das unterscheidet sich vom Ablauf eines gewöhnlichen Python-Programms. Die Kennzeichnung @pyne am Dateianfang weist PyneCore an, den Code entsprechend vorzubereiten und auszuführen. Im Kapitel zur Erklärung des Codes sehen wir uns die genaue Schreibweise und das in den Buchbeispielen ergänzte edge an.
Was unterscheidet das von vektorisierter Verarbeitung?
Unter den Python-basierten Handelsframeworks gibt es sowohl Lösungen, die Kerze für Kerze arbeiten, als auch vektorisierte Ansätze. Bei vektorisierter Verarbeitung führst du Operationen auf ganzen Zahlenreihen aus: Du berechnest etwa die Mittelwerte und Kaufsignale für alle Kerzen auf einmal. Häufig verwaltest du die Daten dabei in Tabellen oder Arrays.
In PyneCore beschreibst du die Arbeit für die aktuelle Kerze. Das System führt sie aus und geht anschließend zur nächsten Kerze. Frühere Berechnungsergebnisse und der zu speichernde Zustand werden nach den Sprachregeln von Pyne verwaltet.
Du schreibst die Schritte in eine einfache Funktion
In mehreren Frameworks, die ebenfalls Kerze für Kerze arbeiten, musst du für deine Strategie eine Klasse anlegen. Eine Klasse fasst zugehörige Daten und Operationen zusammen; ihre Funktionen heißen Methoden. Einstellungen und Handelsregeln schreibst du dort in die vom Framework vorgesehenen Methoden. Auf Kurse oder Positionen greifst du über die Daten der Klasse zu.
In den Pyne-code-Beispielen schreibst du in eine Funktion main(), was du berechnen und unter welchen Bedingungen du handeln möchtest. Ihre Zeilen werden für jede verarbeitete Kerze nacheinander ausgeführt: Zuerst berechnest du einen Wert, dann prüfst du eine Bedingung und schließlich zeichnest du ein Signal oder erteilst eine Order. Das Durchlaufen der Kerzen übernimmt PyneCore.
Für den Einstieg musst du daher weder Klassen und Vererbung lernen noch dein Programm auf die Methoden eines Frameworks verteilen. Für die einfachen Beispiele reichen Variablen, Funktionsaufrufe und Bedingungen. Diese lernst du in den nächsten Kapiteln.
Du kannst die Regel in zeitlicher Reihenfolge verfolgen
Das ähnelt dem Durchdenken einer Handelsentscheidung: „Ich sehe mir den aktuellen Kurs und seinen bisherigen Verlauf an. Wenn meine Bedingung erfüllt ist, steige ich ein. Solange ich eine Position habe, prüfe ich die Ausstiegsbedingung.“ Im Code kannst du die Ereignisse in derselben Reihenfolge verfolgen und mit dem Debugger die Variablen an einer bestimmten Kerze untersuchen.
Versehentlich mit zukünftigen Daten zu rechnen wird schwieriger
Bei vektorisierter Verarbeitung kann die gesamte Datenreihe verfügbar sein. Eine Verschiebung in die falsche Richtung oder ein falsch gewählter Durchschnitt kann dadurch einen Kurs in die Berechnung einbeziehen, der zum Entscheidungszeitpunkt noch unbekannt war. Der Durchschnittskurs eines ganzen Jahres würde beispielsweise bei Entscheidungen im Januar auch Kurse aus späteren Monaten verwenden. Das Programm kann trotzdem laufen und überzeugende Ergebnisse zeigen; der Fehler ist unter Umständen schwer zu erkennen. Das nennt man Look-ahead-Bias, also eine Verzerrung durch die Verwendung zukünftiger Informationen.
Die Zeitreihen von Pyne stellen die Werte der aktuellen und der bereits verarbeiteten Kerzen bereit. Über den Zugriff auf historische Werte kannst du den Kurs der nächsten Kerze nicht auslesen. Das senkt das Risiko, versehentlich zukünftige Daten zu verwenden, und macht nachvollziehbarer, worauf eine Entscheidung beruhte.
Auf die Vorbereitung der Daten musst du weiterhin achten. Enthalten externe Daten bereits eine Information, die erst später bekannt wurde, erkennt die kerzenweise Ausführung das allein nicht.
Bei der Geschwindigkeit kann es einen Kompromiss geben
Die Ausführung Kerze für Kerze kann bei manchen Programmen langsamer sein als eine gut geschriebene vektorisierte Berechnung. Das kann besonders dann zählen, wenn du auf großen Datenmengen viele Strategie- oder Parametervarianten ausprobierst. Vektorisierte Systeme beschleunigen solche Berechnungen häufig mit optimierten Rechenbibliotheken. Wie groß der Unterschied tatsächlich ist, hängt vom Programm und von der Datenmenge ab.
In diesem Buch lernst du die kerzenweise Arbeitsweise: Regeln in zeitlicher Reihenfolge zu formulieren und die Vorgeschichte einzelner Entscheidungen zu überprüfen.
Andere Ansätze zum Nachlesen: vektorisierte Verarbeitung in VectorBT und kerzenweise Strategien in Backtrader (auf Englisch).
Wozu dienen PyneIDE und PyneCore?
Die PyneIDE ist eine Erweiterung für den Editor Visual Studio Code. Dort schreibst du das Programm, wählst die Daten aus und startest die Ausführung. Dort betrachtest du auch das Ergebnis im Chart und suchst nach Fehlern.
PyneCore ist das ausführende System. Es lädt das Programm, bereitet es vor, verarbeitet damit die Kerzen und erzeugt die Ergebnisse der Berechnungen und Trades. Die PyneIDE verwendet es im Hintergrund und zeigt die Ergebnisse an.
Im nächsten Kapitel richtest du die PyneIDE ein und erstellst dein erstes Projekt. Zum Lernen verwenden wir Beispieldaten. So kannst du dasselbe Programm erneut ausführen und die Ergebnisse deiner Änderungen vergleichen.