C# für algorithmisches Handeln
Was ist C#?
C# ist eine objektorientierte Programmiersprache, die zum Erstellen einer Vielzahl von Diensten und Anwendungen verwendet wird. Ihre klare, strukturierte Syntax macht sie leicht zu erlernen und zu lesen, selbst für Anfänger, und bietet gleichzeitig einen strukturierten Ansatz zum Schreiben von kompaktem und wiederverwendbarem Code.
C#-Algorithmen in einer Minute!
- Selbst wenn Sie noch nie mit C# gearbeitet haben, dauert das Erstellen und Bereitstellen Ihres ersten Bots oder Indikators nur ein paar Minuten.
- Da C# einfach zu verwenden ist, können Sie jeden Code-Schnipsel aus dieser Dokumentation schnell umschreiben, um ihn an Ihre Bedürfnisse anzupassen.
- Bei der Verwendung von C# können Sie auf eine große Anzahl von Bibliotheken zugreifen, die vordefinierte Klassen und Methoden enthalten. Diese Methoden können gängige Aufgaben effizient erledigen und lassen Ihnen die Freiheit, komplexe Handelsprobleme zu lösen.
- In C# können Sie Code schreiben, der bei der Ausführung keine Server-Threads blockiert. Mit anderen Worten, Sie können bestimmte Aufgaben gleichzeitig mit anderen Aufgaben starten.
Was ist .NET?
Damit C#-Programme ausgeführt werden können, muss ihr Quellcode in Intermediate Language (IL) kompiliert werden. Dieser IL-Code folgt der Common Language Infrastructure (CLI)-Spezifikation und wird später zur Laufzeit in native Maschinenanweisungen kompiliert. Das .NET-Framework bietet eine virtuelle Ausführungsumgebung, die auf umfangreichen Klassenbibliotheken und der Common Language Runtime (CLR), Microsofts Implementierung der CLI, aufbaut.
Ohne auf technische Feinheiten einzugehen, erfüllt .NET die folgenden Funktionen:
- Erleichterung der Entwicklung und Ausführung von Anwendungen: Das .NET SDK enthält bereits mehrere integrierte Compiler und Build-Engines, sodass keine benutzerdefinierten Lösungen erstellt werden müssen.
- Bereitstellung von Laufzeitbibliotheken: Wenn Sie Ihrem Code neue Datentypen oder Sammlungen hinzufügen, werden Sie oft feststellen, dass .NET bereits geeignete Klassen und Methoden für die Aufgabe bietet.
Die Grundlagen von C#
Datentypen und Variablendeklarationen
Datentypen sind ein Mittel zur Kategorisierung von Daten, damit C# genau weiß, wie Variablen und Eigenschaften zu behandeln sind. In Variablen-/Eigenschaftsdeklarationen stehen Datentypen immer vor dem Variablen-/Eigenschaftsnamen.
1 | |
Alternativ können Sie das Schlüsselwort var verwenden, um die Angabe eines Datentyps zu vermeiden.
1 | |
Objekte und Klassen
Stellen Sie sich Objekte als Abstraktionen von materiellen oder immateriellen Entitäten vor. Diese Entitäten können bestimmte Eigenschaften (Properties) haben und verschiedene Operationen (Methoden) ausführen. Klassen dienen wiederum als Vorlagen für die Objekterstellung.
Da C# eine objektorientierte Sprache ist, können Klassen auch Eigenschaften und Methoden von anderen Klassen erben. Betrachten Sie das folgende Beispiel, in dem wir eine neue Klasse NewBot deklarieren, die von der Klasse Robot erbt. Wir definieren auch einige neue Klasseneigenschaften.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
Datentypen
Da C# eine stark typisierte Sprache ist, ist es notwendig, Datentypen bei der Deklaration von Variablen und Klasseneigenschaften anzugeben. Kurz gesagt, Datentypen stellen einzigartige Klassen mit unterschiedlichen Verhaltensweisen dar. Betrachten Sie die folgenden Beispiele, in denen verschiedene Datentypen für unterschiedliche Klasseneigenschaften und zugehörige Parameter angegeben werden.
1 2 | |
Im obigen Code stellt der Datentyp DataSeries eine schreibgeschützte Liste von Werten dar und wird daher typischerweise zur Darstellung von Marktpreisen verwendet.
Wenn es notwendig ist, Multi-Option-Parameter zu erstellen, können Sie den integrierten Datentyp enum verwenden, wie unten beschrieben. Sie können sich enum's als spezielle Klassen vorstellen, die verschiedene Konstanten enthalten.
1 2 3 4 5 6 7 8 9 | |
Um auf eine in einem enum enthaltene Konstante zuzugreifen, verwenden Sie die folgende Syntax.
1 | |
Wenn ein Parameter oder eine Eigenschaft eine Zahl sein muss, verwenden Sie meistens die Datentypen int (Ganzzahl) oder double (Dezimalzahl). Während der Typ double weniger Präzision als der Typ decimal hat, ist er auch weniger ressourcenintensiv.
1 2 | |
Schließlich repräsentiert der Typ bool typischerweise eine Ja- oder Nein-Eingabe. Die Werte Ja und Nein entsprechen true bzw. false.
1 2 | |
Namespaces
Namespaces fungieren als festgelegte Sammlungen von Klassen. Sobald Sie eine Klasse einem Namespace zuweisen, kann später über die Notation Namespace.ClassName darauf zugegriffen werden. Wir werden unseren NewBot dem Namespace CoolTradingBots zuweisen.
1 2 3 4 5 6 7 8 | |
Klassenmethoden
Klassenmethoden werden nach der Klassendeklaration definiert. Alle Objekte unserer Klasse NewBot können die Methode CustomTradeOperation() aufrufen. Sie nimmt zwei Argumente entgegen, nämlich ein Symbol-Objekt und ein double-Objekt. Unsere Methode soll ein Symbol entgegennehmen und eine Art Handelsaktion für das angegebene Volumen ausführen
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Klassenbibliotheken
Auf Klassenbibliotheken (und folglich Klassenmethoden) kann über ihren Namespace zugegriffen werden, wie im folgenden Beispiel gezeigt.
1 | |
Alternativ können Sie das Schlüsselwort using am Anfang Ihres Codes eingeben, um bestimmte Namespaces festzulegen und Redundanzen zu vermeiden. Betrachten Sie den folgenden Code-Ausschnitt.
1 2 3 | |
Bedingte Anweisungen
Um bedingte Anweisungen zu verwenden, verwenden Sie ein Schlüsselwort gefolgt von einem Ausdruck in runden Klammern. Das folgende Beispiel verwendet das Schlüsselwort if, um unsere Methode CustomTradingOperation() zu finalisieren. Dazu verwenden wir die Methode EvaluateMarket(), die im Namespace Analytics.Actions definiert ist.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Collections
Collections werden als Container definiert, die ein oder mehrere Objekte einer bestimmten Klasse speichern können.
Collections sind vollständig indizierbar, was bedeutet, dass auf ihre Mitglieder zugegriffen werden kann, indem ein bestimmter integer-Wert in eckigen Klammern übergeben wird. Betrachten Sie das folgende Beispiel, in dem die Methode Calculate() die Eigenschaften eines Balkens ausgibt, auf den über seinen Index zugegriffen wird.
1 2 3 4 5 | |
cTrader-Erweiterungen erstellen
Im folgenden Ausschnitt erstellen wir einen grundlegenden Handelsroboter, indem wir nur das in den obigen Abschnitten behandelte Wissen verwenden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
Synchrone und asynchrone Operationen
Wie zuvor erwähnt, unterstützt C# asynchrone Operationen vollständig. Das folgende Diagramm definiert ein grundlegendes Beispiel dafür, wie Handelsaktivitäten bei synchroner Ausführung durchgeführt werden.
graph TD
A(Technisches Signal<br>erkennen) ==> B(Market-Order<br>ausführen)
B ==> C(Take Profit/<br>Stop Loss<br>erreicht)
C ==> D(Position schließen)
D ==> A Die synchrone Ausführung hat einen wichtigen Nachteil. Im obigen Beispiel belegt die Aktion der Ausführung einer Market-Order alle Server-Threads vollständig, was bedeutet, dass Ihr Handelsroboter nichts anderes tun kann, bevor diese Operation abgeschlossen ist.
Dies ist weniger als ideal, wenn Sie schnell auf Marktereignisse und Volatilität reagieren möchten. Idealerweise sollte Ihr Bot in der Lage sein, verschiedene Aktionen zu speichern oder bestimmte Aufgaben zurückzustellen, um sich anderen, dringenderen Aktivitäten zu widmen. Wir werden unser Beispiel erweitern, um besser widerzuspiegeln, wie asynchrone Operationen durchgeführt werden.
graph TD
A([Technisches Signal<br>erkennen]) ==> B(['Buy'-Order<br>platzieren]) & C(['Sell'-Order zur<br>Absicherung<br>platzieren]) ==> D([Eine Order<br>erreicht<br>Take Profit/<br>Stop Loss])
D ==> E([Position schließen])
E ==> A Im obigen Beispiel hat unser Handelsroboter gleichzeitig Orders in beide Richtungen platziert, um seine Positionen abzusichern. Im Gegensatz zu synchronen Operationen ist es nicht erforderlich, auf den Abschluss einer Operation zu warten, bevor mit einer anderen fortgefahren wird. Dies erweitert die Möglichkeiten der Entwickler zur Erstellung effizienter und zuverlässiger Handelsroboter erheblich.
Beachten Sie, dass asynchrone Ausführung sich von Multi-Threading unterscheidet:
- Bei asynchroner Ausführung werden alle Aufgaben im selben Thread gestartet. Wenn sie gespeichert oder zurückgestellt werden, geben sie diesen Thread frei, und wenn ihre Ausführung später fortgesetzt wird, erfolgt dies in einem anderen Thread, der aus dem Thread-Pool ausgewählt wird.
- Beim Multi-Threading starten alle Aufgaben in verschiedenen Threads und setzen ihre Ausführung in ihren ursprünglichen Threads fort. Es gibt kein Thread-Shuffling.
cTrader ruft Ihre Methoden niemals parallel auf, sodass Sie sich keine Gedanken über Multi-Threading-Probleme machen müssen.
