Python-Grundlagen für algorithmisches Handeln
Händler verwenden Python, um Handelsbots, technische Indikatoren, Plugins und andere Tools zu erstellen, die den algorithmischen Handel oder manuelle Operationen unterstützen, und dieser Artikel erklärt die Grundlagen der Programmierung in Python.
Python ist eine beliebte, hochrangige, universelle Programmiersprache, die für Webentwicklung, Datenwissenschaft, Automatisierung und neuerdings für algorithmisches Handeln in cTrader verwendet wird. Egal, ob Sie einfache signalbasierte Handelsbots oder komplexe Multi-Indikator-Strategien erstellen, Python macht den Prozess schneller, effizienter und einfacher zu verwalten.
Python-Algorithmen in einer Minute!
- Erleben Sie integrierte Python-Unterstützung und nahtlosen Zugriff auf die cTrader Algo API, wobei cTrader die einzige große Plattform ist, die native Integration sofort einsatzbereit bietet. Keine Plugins, Adapter oder komplexe Setups erforderlich.
- Konzentrieren Sie sich mehr darauf, was Ihre Strategie erreichen soll, da die Logik einfacher zusammenzustellen ist. Genießen Sie schnelle Iteration, wiederverwendbare Komponenten und skalierbare Performance.
- Entwickeln Sie schnell, debuggen Sie intelligenter und arbeiten Sie ohne Barrieren zusammen. Ihr Code wird immer anpassungsfähig, zuverlässig und wartbar sein.
- Greifen Sie auf Tausende von kostenlosen/Open-Source-Bibliotheken zu und profitieren Sie davon, sowie von ausführlichen Tutorials, Codebeispielen und starker Community-Unterstützung weltweit.
Variablen und Datentypen
In Python sind Variablen dynamisch typisiert, was bedeutet, dass Sie ihre Datentypen nicht explizit deklarieren müssen. Der Interpreter bestimmt den Typ zur Laufzeit basierend auf dem zugewiesenen Wert.
Sie erstellen Variablen, indem Sie ihnen einfach einen Wert zuweisen:
1 2 3 4 | |
Gängige Datentypen
| Typ | Beschreibung | Beispiel |
|---|---|---|
int | Ganze Zahlen | 5, 100, api.StepPips |
float | Dezimalzahlen | 1.1234, 100.5, api.Symbol.Ask |
bool | Boolesche Werte | True, False |
str | Zeichenketten | "EURUSD", api.Label |
list | Sammlung von Elementen | [1, 2, 3], [p for p in api.Positions] |
In cTrader-Algorithmen speichern Variablen wichtige Daten im Zusammenhang mit Marktinformationen, Handelsentscheidungen und cBot-Konfiguration. Diese Variablen repräsentieren oft berechnete Handelsvolumina, Indikatorwerte, boolesche Flags, Symbolnamen, Labels und mehr.
Hier ist ein Beispiel:
1 2 3 4 | |
In diesem Fall ist self.volumeInUnits ein float, der zum Platzieren von Orders verwendet wird, während self.enoughMoney ein bool ist, der steuert, ob weiterhin Positionen in einer Grid-Strategie eröffnet werden sollen.
Klassen und Objekte
Python ist eine objektorientierte Programmiersprache (OOP), die Tools zur Organisation von Code durch Klassen und Objekte bereitstellt, die reale Entitäten und Verhaltensweisen modellieren. Eine Klasse definiert einen Bauplan für die Erstellung von Objekten, die Instanzen dieser Klasse mit ihren eigenen eindeutigen Daten und Verhaltensweisen sind. Die Schlüsselkonzepte sind nachfolgend aufgeführt:
- Eine Klasse wird mit dem Schlüsselwort
classdefiniert. - Die Methode
__init__(Konstruktor) wird häufig verwendet, um den Objektzustand zu initialisieren. - Instanzmethoden definieren Verhalten.
- Attribute enthalten Daten, die für jedes Objekt spezifisch sind.
Sie können beispielsweise eine Klasse Car erstellen:
1 2 3 4 5 6 7 | |
Dann können Sie Objekte der Klasse Car erstellen und mit ihnen interagieren:
1 2 3 | |
Im cTrader-Kontext
In cTrader werden cBots, Indikatoren und Plugins als Klassen implementiert, die ihre gesamte Logik kapseln. Algos interagieren mit der cTrader-Plattform über ein spezielles api-Objekt, das Zugriff auf Symbole, Charts, Orders, Indikatoren und mehr bietet.
Sie können eine Klasse SimplecBot in cTrader auf diese Weise erstellen:
1 2 3 | |
Die Klasse SimplecBot enthält eine einzelne Methode (on_start(self)), die einmal ausgeführt wird, wenn der Handelsbot startet. Die Funktion api.Print schreibt eine Nachricht in das Protokoll und demonstriert, wie Objektmethoden Handelsverhalten kapseln.
Jede Instanz einer Klasse repräsentiert effektiv einen eigenständigen Handelsalgorithmus, der seinen eigenen Lebenszyklus und Handelsentscheidungen mithilfe von OOP-Prinzipien verwaltet. In einem Standard-cTrader-cBot könnte eine Klasse interne Zustandsdaten wie Volumen, Indikatorergebnisse usw. speichern und mehrere Methoden verwenden, um die Handelslogik zu verwalten.
Betrachten Sie dieses MACD-Crossover-Beispiel, das den MACD-Indikator beim Start initialisiert und eine Kauforder platziert, wenn ein MACD-Crossover-Signal auftritt:
1 2 3 4 5 6 7 | |
Das Schlüsselwort self
Innerhalb einer Klasse bezieht sich self auf die Instanz der Klasse und bietet Zugriff auf ihre Variablen und Methoden. self wird verwendet, um:
- Daten wie Indikatorergebnisse, Positionsvolumina und Konfigurationswerte zu speichern.
- Internen Zustand über verschiedene Methodenaufrufe wie
on_start(),on_tick()oderon_bar_closed()hinweg zu verfolgen.
Dieses Beispiel zeigt, wie self verwendet wird:
1 2 3 4 | |
In diesem Fall speichert self.volume das berechnete Volumen, das für Transaktionen verwendet werden soll, während self.macd das MACD-Indikatorobjekt speichert, was den Zugriff auf seine Werte während des gesamten Lebenszyklus des cBots ermöglicht. Ohne self wären diese Variablen lokal für on_start() und in on_bar_closed() nicht zugänglich, wo Handelsentscheidungen getroffen werden können.
Methoden und Funktionen
Funktionen sind Blöcke wiederverwendbaren Codes, die verwendet werden, um eine bestimmte Aufgabe auszuführen. Wenn Funktionen innerhalb einer Klasse definiert werden, werden sie Methoden genannt, und sie arbeiten mit dem internen Zustand der Klasse über den Parameter self. Im Kontext des algorithmischen Handelns mit cTrader definieren Methoden, wie sich Ihr Handelsalgorithmus unter verschiedenen Bedingungen verhält, wie z. B. Markt-Ticks, Balkenabschlüssen oder Initialisierung.
Die Plattform ruft automatisch spezielle Methoden (bekannt als Event-Handler) zu geeigneten Zeitpunkten auf, wie z. B.:
on_start(self) – wird einmal aufgerufen, wenn der Bot initialisiert wird.
1 2 | |
on_tick(self) – wird bei jedem eingehenden Markt-Tick aufgerufen.
1 2 | |
on_bar_closed(self) – wird aufgerufen, wenn eine neue Kerze/ein neuer Balken schließt (ideal für zeitbasierte Strategien).
1 2 3 4 | |
Benutzerdefinierte oder Hilfsmethoden
Um das Umschreiben und Duplizieren von Code zu vermeiden, können Sie Ihre eigenen Methoden definieren. Solche benutzerdefinierten Methoden sollten gängige Logik kapseln, die Ihr Handelsroboter wiederverwenden kann.
Die folgende Methode gibt alle offenen Positionen zurück, die mit dem Label des aktuellen cBots verknüpft sind, was es einfach macht, Positionen konsistent zu verfolgen oder zu schließen.
1 2 | |
Betrachten Sie eine weitere Methode, die den Abstand in Pips zwischen dem aktuellen Kurs und dem Einstieg der Position berechnet, was für Entscheidungen in Grid-basierten Strategien entscheidend ist.
1 2 | |
Sobald eine Methode definiert wurde, können Sie sie innerhalb derselben Klasse mit dem Schlüsselwort self aufrufen. Dieser Ansatz ermöglicht es Ihnen, die Logik überall in Ihrem Bot wiederzuverwenden, ohne Code zu duplizieren.
Nachdem Sie beispielsweise get_bot_positions() definiert haben, können Sie es innerhalb einer anderen Methode aufrufen, um alle Positionen zu schließen:
1 2 3 4 | |
Hier ruft self.get_bot_positions() die Hilfsmethode auf und gibt nur die Positionen zurück, die mit dem aktuellen Bot-Label verknüpft sind.
Ebenso kann die Methode get_distance_in_pips() wiederverwendet werden, um Handelsentscheidungen zu treffen. In einer Grid-Strategie möchten Sie beispielsweise möglicherweise nur dann eine neue Order eröffnen, wenn sich der Markt weit genug von der letzten Position entfernt hat:
1 2 3 4 5 6 7 | |
Weitere Konzepte
Namespaces und Importe
Namespaces in Python helfen dabei, Code zu organisieren und Namenskonflikte zu vermeiden, indem verwandte Bezeichner (Variablen, Funktionen, Klassen) gruppiert werden. Importe ermöglichen es Ihnen, externe Module, Bibliotheken oder Pakete einzubinden, um die Funktionalität über die Standardfunktionen von Python hinaus zu erweitern.
In Python können Sie Standardmodule oder benutzerdefinierte Pakete importieren:
1 2 | |
Sie können auch bestimmte Funktionen oder Klassen importieren:
1 2 | |
Beim Schreiben von Algorithmen für cTrader in Python funktionieren Importe etwas anders, da cTrader in die .NET-basierte cTrader Algo API integriert ist. Dieses Setup umfasst eine Brücke, die es Python-Code ermöglicht, mit .NET-Assemblys zu interagieren, und dies erklärt, warum ein typischer cBot mit Folgendem beginnt:
1 2 3 4 5 6 7 8 9 | |
Dabei gilt:
import clrlädt die Common Language Runtime (CLR) und ermöglicht Python die Interoperabilität mit .NET-Bibliotheken.clr.AddReference("cAlgo.API")verweist auf die cAlgo API-Assembly, die alle handelsbezogenen Klassen, Methoden und Objekte enthält.from cAlgo.API import *importiert alle Typen aus der API (z. B.TradeType,Color,Position).from robot_wrapper import *lädt Hilfsfunktionen und Wrapper, die gängige Handelsoperationen vereinfachen.
Das Namespace-System stellt sicher, dass:
- Pythons integrierte Namen (wie
print) Konflikte mit cTraders Namen (wieapi.Print) vermeiden. - Alle handelsspezifischen Objekte (
api.Symbol,api.Indicators,api.ExecuteMarketOrder) aus dem cTrader Algo API-Namespace stammen und organisiert und eindeutig bleiben. - Sie können die Funktionalität erweitern, indem Sie Ihre eigenen benutzerdefinierten Pakete importieren, um zusammen mit den integrierten Typen von cTrader zu arbeiten.
Schleifen
Schleifen ermöglichen es Ihnen, Operationen über eine Sequenz von Werten zu wiederholen oder bis eine Bedingung erfüllt ist. Im algorithmischen Handel werden Schleifen häufig verwendet, um Positionen zu verarbeiten (z. B. schließen, filtern oder aktualisieren), Bedingungen über mehrere Assets oder Indikatoren zu prüfen, Grid- oder Martingale-Strategien zu implementieren, bei denen wiederholte Ordererteilung erforderlich ist, und mehr.
In Python ist die Iteration unkompliziert und unterstützt sowohl for-Schleifen (zum Durchlaufen von Sammlungen) als auch while-Schleifen (zum Wiederholen, bis sich eine Bedingung ändert).
Sie können eine Schleife schreiben, um Positionen zu schließen:
1 2 3 4 | |
In diesem Fall:
self.get_bot_positions()gibt alle Positionen zurück, die zum aktuellen cBot gehören.- Die
for-Schleife durchläuft jede Position. - Übereinstimmende Positionen werden mit
api.ClosePositiongeschlossen.
Betrachten Sie eine andere Schleife, die über alle offenen Grid-Positionen iteriert, sie nacheinander schließt und rekursiv prüft, ob noch Positionen vorhanden sind (Sicherheit bei teilweisen Schließungen).
1 2 3 4 5 6 | |
Bedingte Anweisungen
Bedingte Anweisungen steuern den Ausführungsfluss in Python, indem sie Ihrem Algorithmus ermöglichen, Entscheidungen auf der Grundlage logischer Ausdrücke zu treffen. Bedingungen sind das Rückgrat der Strategielogik und bestimmen, wann Positionen eröffnet, geschlossen oder verwaltet werden.
Python unterstützt drei hauptsächliche bedingte Konstrukte:
if– führt Code aus, wenn die Bedingung wahr ist.elif(else if) – prüft eine andere Bedingung, wenn die erste falsch war.else– bietet eine Rückfalloption, wenn keine Bedingungen erfüllt sind.
Betrachten Sie die MACD-Crossover-Bedingungen, die in diesem Code ausgedrückt werden:
1 2 3 4 | |
Diese Struktur:
- Erteilt eine Kauforder, wenn die MACD-Linie über der Signallinie liegt.
- Erteilt eine Verkaufsorder, wenn die MACD-Linie unter der Signallinie liegt.
- Überspringt den Handel, wenn kein klares Signal vorliegt.
Listen
Python bietet leistungsstarke und prägnante Tools für die Arbeit mit Datensammlungen wie Transaktionen, Preisen oder Indikatoren. Zwei der häufigsten sind List Comprehensions und integrierte Aggregationsfunktionen wie sum().
Sie können beispielsweise einen Code schreiben, der über numbers iteriert und nur gerade Zahlen auf diese Weise behält:
1 2 | |
Sie können eine List Comprehension verwenden, um nur Positionen für das aktuelle Symbol auszuwählen und eine gefilterte Liste zu erstellen, die in Multi-Symbol-Umgebungen nützlich ist.
1 | |
Die Aggregation von Gewinn oder Volumen mit sum() ist ein Standardansatz in Grid-Trading-Strategien, um zu bestimmen, wann der Gesamtgewinn das Ziel erreicht.
1 | |
Sie können Filterung und Aggregation auf diese Weise kombinieren:
1 2 | |
Synchrone und asynchrone Operationen
Python folgt standardmäßig einem synchronen Ausführungsmodell. Die Lebenszyklusmethoden Ihres Algorithmus, wie on_start, on_tick und on_bar_closed, werden nacheinander von der Ereignisschleife der Plattform ausgelöst.
Hier ist eine grundlegende Darstellung eines synchronen Handelsablaufs:
graph TD
A(Signal erkennen) ==> B(Order ausführen)
B ==> C(Position erreicht<br>TP/SL)
C ==> D(Position schließen)
D ==> A In synchronen Abläufen kann jede langwierige Operation den Thread blockieren und möglicherweise das nächste Ereignis verzögern. In realen Strategien initiieren Algorithmen jedoch typischerweise nicht blockierende Aktionen, wie das Übermitteln einer Order oder das Setzen von Stop-Loss und Take-Profit, und warten dann auf zukünftige Ereignisse (wie einen neuen Tick oder Bar), um Ergebnisse zu verarbeiten. Dieses Setup führt zu einer asynchronen Orchestrierung, obwohl Pythons async/await-Konstrukte nicht verwendet werden.
Hinweis
Für die meisten Handelsalgorithmen ist explizite asynchrone Programmierung nicht erforderlich.
cTrader verwaltet die Nebenläufigkeit, indem es Ihre ereignisbasierten Callbacks serialisiert. Jede Methode wird unabhängig und niemals parallel aufgerufen, wodurch die Notwendigkeit von Multithreading-Schutzmaßnahmen entfällt. Dieses Design ermöglicht es Strategien, auf mehrere Handelsbedingungen gleichzeitig zu reagieren, im logischen Sinne, ohne zu blockieren.
Im folgenden Beispiel bewertet die Strategie Kauf- und Verkaufssignale unabhängig und reagiert entsprechend, ohne dass sich die Ausführungskontexte überschneiden.
graph TD
A([Signal erkennen]) ==> B([Kauforder<br>eröffnen]) & C([Verkaufsorder zur<br>Absicherung<br>eröffnen]) ==> D([Eine Order<br>erreicht<br>Take Profit oder<br>Stop Loss])
D ==> E([Position schließen])
E ==> A Obwohl Entscheidungen parallel zu sein scheinen, werden sie sequenziell vom internen Warteschlangensystem von cTrader verarbeitet. Die Plattformarchitektur zielt darauf ab, Nebenläufigkeitsprobleme zu verhindern und gleichzeitig Handelsroboter reaktionsfähig auf Marktveränderungen zu halten.
