
Die ATAS-Plattform hat neben all ihren nützlichen Indikatoren und Footprint-Charts eine tolle Möglichkeit, Ihre eigenen Algorithmen über die API zu verbinden. Der Reiz liegt darin, dass es unbegrenzte Möglichkeiten zur Nutzung von ATAS-Kapazitäten eröffnet. Zum Beispiel für:
Am Ende des Artikels erhalten Sie eine Datei für Visual Studio mit dem im Text verwendeten Quellcode. Wenn Sie Fragen haben, fragen Sie in den Kommentaren.
Los gehts!
Wie soll man anfangen
Man soll mit der Installation von Microsoft Visual Studio beginnen – dies ist eine Umgebung, in der verschiedene Programme in C# entwickelt werden, einschließlich DLLs. Im Format von DLL-Bibliotheken können Sie Ihre Algorithmen mit ATAS verbinden.
Sie können das Distributions-Kit des Visual Studio Community-Programms (kostenlose Version, es reicht) unter visualstudio.microsoft.com//downloads/ herunterladen.
Installieren Sie Visual Studio auf Ihrem Computer wie jedes andere Programm. Es ist empfehlenswert, die englische Version zu wählen. Wir verwenden Englisch in den Screenshots.
Starten wir. Wählen Sie Create Class Library (.NET Standard).

Beachten Sie, dass das Lernen in den meisten C#-Kursen mit der Erstellung einer Console App beginnt. Wir haben uns entschieden, Class Library zu erstellen, da sie für die Verbindung mit ATAS benötigt wird.
Was ist Class Library? Es ist eine separate Komponente eines größeren Programms. In unserem Fall erstellen wir eine DLL-Datei mit unseren eigenen Klassen, damit sie später als Komponente an die ATAS-Plattform angebunden wird.
Sie werden bald sehen, wie dies geschieht.

Auswählen eines Namens für das Projekt Lesson1. Klicken Sie auf Create.
Visual Studio wird gestartet und erstellt eine leere Class Library Vorlage für uns (im Screenshot unten).

Kurz zur Schnittstelle. Auf der rechten Seite (1) befindet sich ein Fenster namens Solution Explorer. Es zeigt die Struktur unseres Projekts und seiner Elemente (wenn es für Sie nicht angezeigt wird, können Sie es über das Menü View öffnen. Sie können dort auch andere Fenster öffnen / schließen).
Auf der linken Seite befindet sich ein großer Bereich, in dem der Programmcode bearbeitet wird, in diesem Fall der Klasseneditor Class1.cs.
Was ist in unserem Code nach dem Erstellen der Vorlage:
- using ist ein Schlüsselwort, es bedeutet, dass wir zusätzliche Quellen (namespace) verbinden. Using System (2) wird standardmäßig vorgeschlagen, da es die Grundlagen enthält, die wir wahrscheinlich verwenden werden.
- namespace Lesson1 ist unser Namespace. Es zieht eine Art Grenze zwischen verschiedenen Teilen des Codes, damit sie nicht aufgrund der gleichen Namen in Konflikt geraten.
- public class Class1 ist ein Stub für unsere Klasse. C # ist eine objektorientierte Programmiersprache (OOP) und eine Klasse ist ein Muss.
Die ersten Schritte
Stellen wir eine Verbindung zu ATAS her.
Fügen Sie dazu in unserem Projekt einen Link zur Bibliothek ATAS.Indicators.dll hinzu, die sich im Ordner mit der installierten ATAS-Plattform befindet.
Wählen Sie im Menü Project die Option Add References (oder klicken Sie mit der rechten Maustaste im Explorer-Fenster auf die Registerkarte Dependencies).

Im Explorerfenster erscheinen ATAS.Indicators (1).

Bearbeiten Sie als Nächstes den Code wie im Screenshot (2) gezeigt:
Wir schreiben namespace ATAS.Indicators.Technical – weil wir unseren eigenen Algorithmus im Raum anderer technischer ATAS-Indikatoren erstellen werden.
Fügen wir using ATAS.Indicators hinzu – Wenn Sie Algorithmen für ATAS erstellen, verwenden Sie immer diese Referenz (z. B. einen Absatz später).
Bearbeiten wir public class Example1_1: Indicator. In dieser Zeile bedeutet Example1_1, dass wir das erste Beispiel aus dem ersten Lesson machen (Sie können einen anderen Namen eingeben, er wird dann in der Liste der ATAS-Indikatoren angezeigt).
Aber der Doppelpunkt und das Wort Indicator haben eine wichtige Bedeutung. Somit weisen wir darauf hin, dass die Indicator-Klasse (sie ist in ATAS.Indicators.dll enthalten) die „übergeordnete“ Klasse ist. Und unsere Klasse Example1_1 erbt alles, was in der übergeordneten gibt. Dies bedeutet, dass wir Zugriff auf alle Funktionen erhalten, die den Erben der Indicator Klasse erlaubt sind – d. h. Operationen mit Preisen, Clustern, Werten anderer Indikatoren usw.
Als nächstes schreiben wir protected override void OnCalculate (int bar, decimal value) und zwei geschweifte Klammern. Dieser Teil des Codes wird als OnCalculate-Methode bezeichnet.
Eine Methode ist einfach ausgedrückt ein Satz von Befehlen, die ein Computer ausführen soll. Innerhalb der übergeordneten Klasse wird die OnCalculate-Methode als erforderlich deklariert. Wenn Sie Ihren Indikator zum Chart hinzufügen, führt die Plattform die Befehle aus, die Sie in die geschweiften Klammern schreiben. Und wenn Sie die OnCalculate-Methode nicht haben, lässt Visual Studio Sie den Code nicht in eine DLL-Datei kompilieren, da seine Anwesenheit erforderlich ist. Andernfalls wird ATAS nicht verstehen, was es tun muss.
Wenn Sie alles richtig gemacht haben, wird unten die Aufschrift No issues found (3) angezeigt. Wenn dort Fehler angezeigt werden, versuchen Sie deren Ursache zu verstehen. Was kann schon schief gehen:
- C# ist eine Sprache, bei der die Groß-/Kleinschreibung beachtet wird. Das bedeutet, dass Groß- und Kleinbuchstaben im Code unterschiedlich sind.
- Geschweifte Klammern, Semikolons, Anführungszeichen und andere Symbole sind wichtig. Wenn Sie etwas vergessen oder verloren haben, werden Sie von Visual Studio aufgefordert.
Nachdem Sie nun einen fehlerfreien Code haben, kompilieren wir ihn. Wählen Sie dazu im Menü Build die Option Build Lesson1(oder drücken Sie Strg + B), und im output Fenster sollte eine Meldung erscheinen, dass die Kompilierung des Codes in eine Datei erfolgreich war.

Wie Sie sehen, wurde unser Projekt in Lesson1.dll kompiliert. Wir gehen in den angegebenen Ordner, nehmen die Datei und kopieren sie nach C:UsersUserDocumentsATASIndicators (in Ihrem Fall kann der Pfad zum Ordner Documents abweichen). Fügen Sie dort Lesson1.dll ein.
Starten Sie ATAS, öffnen Sie einen Chart, laden Sie Daten in ein Instrument und rufen Sie das Fenster des Indikatormanagers auf. Und was ist da?

Unser eigener Indikator Example1_1 ist in der Liste der technischen Indikatoren erschienen! (Falls nicht, versuchen Sie es mit dem Search Formular).
Beachten Sie. Obwohl wir praktisch keinen Code geschrieben haben, enthält unser Indikator:
- die Möglichkeit, eine Quelle Source auszuwählen;
- Auswahl eines Panels zur Anzeige;
- Einstellungen für die Anzeige (Farbe, Linientyp und andere).
Unser Indikator hat all diese Einstellungen von der „übergeordneten“ Klasse Indicator geerbt. Wir können sie ändern, aber wir werden sie vorerst so lassen, wie sie sind.
Wenn wir dem Chart Example1_1 hinzufügen, wird der Indikator in der Liste der hinzugefügten angezeigt, aber tatsächlich ändert sich nichts, da in der OnCalculate-Methode kein Code vorhanden ist. Es sind keine Befehle auszuführen.
Und wenn Sie das Panel ändern, um den Indikator anzuzeigen, und New Panel anstelle von Chart angeben, dann sehen Sie Folgendes:

Im unteren Bereich wird eine rote horizontale Linie angezeigt. Was ist die Linie und warum gibt es Nullen?
Denn wenn Sie Ihre Example1_1-Klasse erstellen und sie von der „übergeordneten“ Indicator-Klasse erben, wird Ihrer Klasse automatisch ein Daten-Array hinzugefügt. Es heißt Dataseria. Dieses Array enthält die Werte Ihres Indikators für jede Kerze.
Stellen Sie sich vor, wir fügen dem Chart den Indikator Example1_1 hinzu, der aus 458 Kerzen besteht.

Im Speicher wird eine Tabelle erstellt, in der der Computer die früheste Kerze (links im Chart) die Nummer 0, dem nächsten die Nummer 1 usw. zuweist. Die letzte (rechte) Kerze wird mit 457 nummeriert.
Und die Zeile Example1_1 speichert die Indikatorwerte. Da wir aber keinen Code geschrieben haben, um sie zu berechnen, sind dort die Standardwerte hinterlegt – und das sind Nullen.
Wenn Sie aufgepasst haben, hat die OnCalculate-Methode Parameter (int bar, decimal value) im Code. Also:
- bar ist eine ganzzahlige Variable vom Typ integer. Hier wird die Seriennummer der Bar gespeichert;
- value ist eine Variable vom Typ decimal (Dezimalzahl). Der diesem Balken entsprechende Indikatorwert wird hier gespeichert.
Das klingt für einen Anfänger bisher wahrscheinlich alles schwierig. Daher werden wir ein anderes Mal auf die Berechnung der Indikatorwerte zurückkommen, aber vorerst werden wir etwas sehr Einfaches tun.
Schreiben der einfachsten Algorithmen
Erstes Programm
Als erstes Programm zeigen diejenigen, die mit dem Erlernen der Programmiersprache C# beginnen, normalerweise die Meldung “Hello, world!” auf dem Bildschirm an.
Da es sich aber um eine Bibliothek für ATAS handelt, werden wir diese Meldung im Log-Fenster anzeigen. So ziemlich dasselbe.
Um die Idee umzusetzen, fügen Sie dem Projekt die Referenz Utils.Common.dll aus dem Ordner, in dem ATAS installiert ist hinzu. Genau wie wir ATAS.Indicators.dll hinzugefügt haben.

Wenn Sie alles richtig gemacht haben, sehen Sie im Solution Explorer-Fenster Utils.Common (wie durch die Nummer 1 im Screenshot unten gezeigt).

Als nächstes bearbeiten wir den Code.
using Utils.Common.Logging; hinzuzufügen- dies ist notwendig, damit der Indikator Meldungen im Log-Fenster der ATAS-Plattform anzeigen kann.
this.LogInfo ($“Hello World 1″); in den Textkörper der OnCalculate-Methode hinzuzufügen. Dies ist der Befehl zur Ausgabe der Textphrase „Hello World 1“ im Log-Fenster.
Wir erstellen auch eine weitere protected override void OnInitialize() Methode – Sie werden bald sehen, warum. In den Textkörper der Methode schreiben wir this.LogInfo ($ „Hello World 2“);
Als nächstes kompilieren wir.

Kopieren Sie unsere aktualisierte Lesson1.dll aus dem Projektordner und fügen Sie sie (überschreiben) in den Ordner Documents ATAS Indicators ein
Und wenn ATAS ausgeführt wird, wird eine Benachrichtigung angezeigt:
Einige Bibliotheken wurden geändert. In der Statusleiste des Hauptfensters können Sie Strategien neu laden.
Keine Angst, das ist großartige Nachrich! Wenn Sie Ihre DLL im Ordner Indicators aktualisieren, müssen Sie die Plattform nicht neu starten.

Es genügt, auf dieses Symbol zu klicken, und ATAS aktualisiert die Bibliotheken ohne Neustart. Dies spart viele Minuten, wenn Sie häufig kleine Änderungen vornehmen.
Öffnen Sie als Nächstes das Tages-Chart (z.B. #ES) und stellen Sie im Einstellungsfenster von Timeframe die Anzahl der Tage = 5 ein, sodass nur 5 Kerzen auf dem Chart vorhanden sind. Fügen Sie dem Chart den Indikator Example1_1 hinzu und sehen Sie sich das Log-fenster an:

„Hello World 1“ wurde 5 Mal angezeigt und „Hello World 2“ wurde 1 Mal angezeigt.
Es bedeutet, dass:
- die Befehle innerhalb der OnCalculate-Methode werden für jeden Balken ausgeführt, und dann wird die Methode bei jedem neuen Tick weiter ausgeführt, um die Indikatorwerte in Echtzeit zu berechnen.
- Und die Methode OnInitialize wird nur einmal ausgeführt, wenn der Indikator initialisiert wird. Dies geschieht vor der Ausführung von Befehlen der OnCalculate-Methode.
Hurra, unser erstes „Hello World“-Programm funktioniert! Verkomplizieren wir die Aufgabe jetzt ein wenig.
Zweites Programm
Lassen Sie uns einen Indikator schreiben, der Informationen über die letzte Kerze im Protokollfenster anzeigt – ist er bullisch (Close> Open) oder bärisch (Close <Open)?
Wählen Sie im Menü Projeсt die Option Add Class aus, und lassen Sie den Namen Class2.cs. Nach dem Hinzufügen erscheint ein neues Class(1) in Ihrem Explorer Fenster. Ein Doppelklick darauf öffnet den Code-Editor dafür.

Kopieren Sie im Editor den Code aus Example1_1 und fügen Sie ihn hier ein. Sie sollten aufgrund eines Namenskonflikts einen Fehler erhalten. Ändern Sie den Namen (2) der Klasse in Example1_2, belassen Sie alle using-Zeilen, entfernen Sie den Code aus der OnCalculate-Methode und schreiben Sie in der OnInitialize-Methode Befehle, um unser Problem zu lösen.
var candle = GetCandle (CurrentBar-1);
Was bedeutet diese Zeile? Lesen wir es von rechts nach links.
- CurrentBar ist eine Variable, die der Anzahl der Kerzen im Chart entspricht. Da die Nummerierung jedoch bei Null beginnt, hat die letzte Kerze in der Tabelle die Nummer CurrentBar-1.
- GetCandle ist eine Methode (Befehl) der übergeordneten Indicator-Klasse. Beim Ausführen dieses Befehls liest der Computer alle verfügbaren Informationen über die Kerze auf dem Chart unter der in Klammern angegebenen Zahl.
- var Candle – so deklarieren wir ein neues Objekt zur Verwendung im Programm. Wenn wir ein neues Objekt deklarieren, ist es besser, ihm sofort einen Wert zuzuweisen. Dies geschieht mit dem Gleichheitszeichen
Und zusammen deklarieren wir eine Variable candle und geben Informationen über die letzte Kerze auf dem Chart ein. Jetzt können wir mit diesen Informationen arbeiten. In unserem Fall – eine bedingte if-else-Konstruktion zu erstellen (eine Vergleichsoperation durchführen).
Wenn der Schlusskurs in unserer Kerze höher (höher) als der Eröffnungskurs ist, schreiben Sie “Last bar is Bullish” in das Log. Andernfalls (wenn kleiner oder gleich) – schreiben Sie “Last bar is Bearish” in das Log.
Kompilieren Sie die dll-Datei über das Menü Build, fügen Sie die Datei Lesson1.dll in das Verzeichnis mit den Indikatoren ein. Klicken Sie in ATAS auf das Symbol für die Plattform, um die Bibliotheken zu aktualisieren. Öffnen Sie den Chart:

Was bedeutet das?
Wir haben zwei Variablen q_Green und q_Red hinzugefügt. Beide sind int (integer) und beide sind null. Wir werden sie zum Zählen verwenden.
Dann kommt der for-Zyklus. Dieser Zyklus ist geeignet, wenn eine Operation eine bekannte Anzahl von Malen durchgeführt werden muss. In unserem Fall entspricht die Anzahl der Iterationen der Anzahl der Kerzen im Chart, die in CurrentBar gespeichert sind. Die Variable i ist ein Zähler, am Anfang ist sie gleich Null. Er erhöht sich jedoch mit jeder Zyklusausführung (Iteration) um 1. Der Zyklus wird solange ausgeführt, wie die Bedingung i <СurrentBar wahr ist.
Wenn der Zyklus zum ersten Mal ausgeführt wird, gibt unser Indikator den Befehl GetCandle (0), empfängt Daten über die erste (linke) Kerze auf dem Chart und legt sie in das candle Objekt ab. Dann vergleicht es Candle.Close und Candle.High und erhöht je nach Vergleich q_Green oder q_Red.
Und so weiter für jede Kerze. Wenn der Zyklus endet, schreibt der Befehl LogInfo den Text und die Werte der Variablen q_Green oder q_Red in das Log-Fenster.
Lassen Sie uns unsere Indikatoren-Bibliothek kompilieren, sie in denselben Ordner einfügen und ersetzen, auf das Symbol klicken, um die Bibliotheken in ATAS zu aktualisieren, und den Indikator zum Chart hinzufügen:

Im Log-Fenster schrieb der Indikator Example1_2, dass der letzte Balken bullisch ist. Und Beispiel1_3 schrieb, dass es insgesamt 11 bullische Balken und 12 bärische Balken gibt.
Lassen Sie uns für diesen Artikel zum letzten Mal komplizierter werden.
Viertes Programm
Lassen Sie uns einen Code schreiben, der eine Abfolge von bullischen und bärischen Kerzen basierend auf der Dauer und Häufigkeit des Auftretens auswertet. Mit anderen Worten, wir wollen zum Beispiel wissen, wie wahrscheinlich es ist, dass auf den ersten bullischen Balken ein weiterer bullischer Balken folgt.
Aber bevor wir den Indikator schreiben, machen wir ein Experiment. Nehmen wir einen Code, der ein zufälliges Array von 20.000 Elementen generiert, die mit Nullen und Einsen gefüllt sind. Wir erhalten also eine Folge von Ketten, deren Mindestlänge = 1 Glied ist. Einige Ketten haben 2, 3, 5 Glieder oder mehr.
Die Frage ist – was wird die durchschnittliche Kettenlänge sein?

Als Ergebnis des Experiments erhalten wir, dass der Durchschnittswert der Kette für ein zufällig generiertes Array von 20.000 Nullen und Einsen etwa 1,96 Glieder beträgt.
Das heißt, wenn wir annehmen, dass 0 eine bärische Kerze und 1 eine bullische Kerze ist, dann beträgt in einem absolut chaotischen Markt die durchschnittliche Länge einer Kette von bullischen / bärischen Balken = 1,96.
Wir brauchen diese Zahl als „Standard der Zufälligkeit“.
Wechseln Sie zu Lesson1 und schreiben Sie den Code für die neue Klasse Example1_4. Lassen Sie uns zunächst die Statistiken für die bullischen Candlesticks berechnen.

Der erste Zyklus (1) wird über das gesamte Array von Kerzen auf dem Chart iterieren. Finden wir den Anfang der bullishen Kette (Zeile 21), dann starten wir den zweiten Zyklus (2), der die Länge jeder Kette in der bullishLine zählt. Die Variable bullishFirst akkumuliert die Anzahl der gefundenen bullishen Ketten, die Variable bullishSum summiert deren Gesamtlänge.
Die Zeilen 24 und 31 werden benötigt, um Fälle zu vermeiden, in denen der Algorithmus über das Array von Kerzen hinausgeht.
Wenn die Zyklen abgeschlossen sind, zeigen wir (3) im Log-Fenster Informationen über die Anzahl der gefundenen Sequenzen von bullischen Kerzen, deren Gesamtlänge und berechnen den Durchschnittswert durch Division.
Wir schreiben einen ähnlichen Algorithmus zur Berechnung von Statistiken zu bärischen Balken. Den elegantesten und professionellsten Code werden wir sicher nicht bekommen. Aber dies ist ein Artikel von einem Laien für Anfänger, also „Hauptsache ist, dass es funktioniert“.
Wir kompilieren den Code, übertragen ihn in einen Ordner und starten ihn auf dem Chart, zum Beispiel eine Gazprom-Aktie (GAZP) mit einer täglichen Periode für mehrere Wochen. Im Log-Fenster sehen wir, dass unser Indikator Folgendes gefunden hat:
- 6 bärische Sequenzen mit insgesamt 10 Kerzen;
- 6 bullische Sequenzen mit insgesamt 11 Kerzen.

Dies ist das richtige Ergebnis, da die erste bärische Kerze nicht als vollständige Sequenz betrachtet wird, da wir ihren Anfang nicht sehen.
Durchschnittliche Länge der Sequenzen:
- 1,66 für bärische Kerzen
- 1,83 für bullishe
Wenn wir Daten für eine deutlich größere Anzahl von Kalendertagen in den Chart laden, stellen wir Folgendes fest:

Durchschnittliche Länge der Sequenzen für den Zeitraum Sommer 2017 bis Frühjahr 2021:
- 1,86 für bärische Kerzen
- 1,93 für bullishe
Dies kommt dem „Standard des Chaos“ sehr nahe. Mit anderen Worten, wenn der Handel mit GAZP-Aktien heute mit Wachstum schließt, dann ist die Wahrscheinlichkeit, dass auch morgen bullisch ist – relativ gesehen 50/50. Und wenn Sie sich die einfachste Strategie im Stil von „Kaufe morgen bei der Eröffnung, wenn es heute Wachstum gab“ Gedanken gemacht haben, dann können Sie mit Hilfe von ATAS und Visual Studio schnell eine Antwort darauf finden, wie stichhaltig diese Strategie ist.
Was, wenn:
- einen anderen Markt/Zeitraum wählen?
- den Charttyp ändern – auf Delta, Range, Range XV, Reversal?
- Trailing-Stop hinzufügen?
- eine automatisierte Strategie erstellen?
Ideen tauchen nacheinander auf. Dies ist pure Kreativität, die Sie auf den Finanzmärkten mit der ATAS-Plattform und der Umgebung für die Entwicklung Ihrer eigenen Algorithmen Visual Studio tun können.
Sie können jetzt loslegen, hier ist das Quellcode-Archiv von Lesson1.
Um es in Visual Studio zu öffnen, doppelklicken Sie auf die Datei Lesson1.sln.
Und im Ordner Lesson1binDebugnetstandard2.0 befindet sich eine vorgefertigte Lesson1.dll, die Sie sofort in Ihren Ordner C:UsersUserDocumentsATASIndicators einfügen können
Bonus
Hier noch ein toller Link. Damit können Sie ein Archiv mit einer Reihe von Algorithmen zur Berechnung beliebter technischer Indikatoren herunterladen, die in Visual Studio geöffnet werden können.
Um das Set in Visual Studio zu öffnen, doppelklicken Sie auf die Datei CustomIndicatorSet.sln
Schlussfolgerungen
Zu wissen, wie man Programme schreibt, ist ein wichtiger Vorteil. Mit einer Beherrschung von C# können Sie auch auf nicht professionellem Niveau:
- den Handel automatisieren;
- Strategieeinstellungen optimieren;
- die Aussichten von Ideen schätzen.
Sollte sich die Erstellung von Algorithmen in C# für ATAS dennoch als zu zeit- und arbeitsaufwendig herausstellen, lassen Sie deren Entwicklung von professionellen Developern in Auftrag geben.
Wenn Ihnen dieser Artikel gefallen hat, lassen Sie es mich in den Kommentaren wissen. Schreiben Sie auch, was Sie im nächsten Artikel zu diesem Thema gerne sehen würden.
Die Informationen in diesem Artikel sind nicht als Aufforderung zur Investition oder zum Kauf/Verkauf von Vermögenswerten an der Börse zu verstehen. Alle Situationen, die in diesem Artikel besprochen werden, dienen ausschließlich dem Zweck, sich mit der Funktionalität und den Vorteilen von ATAS vertraut zu machen.