English Русский 日本語
preview
Einführung in MQL5 (Teil 37): Beherrschung von API und WebRequest in MQL5 (XI)

Einführung in MQL5 (Teil 37): Beherrschung von API und WebRequest in MQL5 (XI)

MetaTrader 5Integration |
19 0
ALGOYIN LTD
Israel Pelumi Abioye

Einführung

Willkommen zurück zu Teil 37 der Serie Einführung in MQL5! Im vorigen Artikel haben wir die Grundlagen von API-Signaturen vorgestellt und untersucht, wie abgesicherte Anfragen in MQL5 mithilfe von Hashing und HMAC-basierten Techniken erstellt werden. Wir haben uns darauf konzentriert, warum Signaturen notwendig sind, wie sie sensible Anfragen schützen und wie MQL5 die Signaturerstellung auf konzeptioneller Ebene handhabt.

Dieser Artikel baut auf dieser Grundlage auf und macht den nächsten nützlichen Schritt. Hier werden wir ein MQL5-Skript schreiben, das Kontoinformationen für jeden Vermögenswert abruft, der durch Senden von authentifizierten API-Abfragen an Binance zugänglich ist. Hier werden alle zuvor besprochenen Themen zusammengefasst, wie z. B. die Verwendung von WebRequest, der Umgang mit Zeitstempeln, das Erstellen von Signaturen und die Interaktion mit privaten API-Endpunkten. Am Ende dieses Artikels werden Sie wissen, wie Sie sicher mit Binance interagieren und aktuelle Kontoinformationen direkt von MQL5 abrufen können.

 

Abrufen des Binance-Server-Zeitstempels für signierte Anfragen

Eine Nachricht und ein geheimer Schlüssel sind die beiden wesentlichen Komponenten, die benötigt werden, um eine sichere Signatur für Binance zu erstellen, wie wir im letzten Beitrag beschrieben haben. Die Nachricht ist in diesem Fall der Zeitstempel, der die aktuelle Zeit auf dem Binance-Server widerspiegeln muss und nicht die Zeit auf Ihrem lokalen Computer. Um Ihre Anfragen zu sichern, ist der Zeitstempel unerlässlich. Replay-Attacken werden verhindert, indem sichergestellt wird, dass jede signierte Anfrage eindeutig ist und nicht von einer anderen Partei verwendet werden kann. Der Zeitstempel erfasst den genauen Zeitpunkt der Anfrage, da er sich ständig ändert. Binance ermöglicht eine genaue Überprüfung durch die Angabe des Zeitstempels in Millisekunden. Beim Zugriff auf private Endpunkte, z. B. bei der Überprüfung des Kontostands oder beim Ausführen von Trades, wird durch die Verwendung der richtigen Serverzeit sichergestellt, dass Ihre Signatur gültig ist.

Wir müssen eine API-Anfrage an Binance senden, um diese Serverzeit zu erhalten. Der Zeitstempel des Servers ist die offizielle Referenz, die Binance für alle authentifizierten Anfragen verwendet, im Gegensatz zur lokalen Zeit, die je nach der Uhr Ihres Computers oder Ihrer Zeitzone variieren kann. Das bedeutet, dass unsere MQL5-Software vor der Erstellung der Signatur Binance kontaktieren muss, um die Serverzeit zu erhalten. Jede Signatur ohne diesen Schritt würde abgelehnt werden, da der Zeitstempel nicht den Erwartungen von Binance entsprechen würde. Um die aktuelle Serverzeit zu erhalten, muss eine GET-Anfrage an einen bestimmten Binance-Endpunkt gesendet werden. Wir können frei auf diesen Endpunkt zugreifen, da er keine Authentifizierung erfordert. Die aktuelle Serverzeit in Millisekunden ist in einem JSON-Objekt enthalten, das Binance als Antwort auf unsere Anfrage bereitstellt. Danach wird unser Skript diesen Wert aus der Antwort extrahieren und ihn als Nachricht verwenden, während die Signatur erstellt wird.

Wenn wir die Anfrage korrekt aufbauen, die Antwort sauber verarbeiten und den Zeitstempel richtig auslesen, sind alle folgenden API-Aufrufe mit der Binance-Serverzeit synchronisiert. Obwohl dieser Schritt unbedeutend erscheinen mag, ist er doch von entscheidender Bedeutung, da ohne einen genauen Zeitstempel weder eine private Anfrage noch eine Signatur erfolgreich wäre. Wir müssen zunächst lernen, die Serverzeit zuverlässig zu erfassen, bevor wir diesen Zeitstempel mit dem geheimen Schlüssel kombinieren können, um später in diesem Artikel eine ordnungsgemäß signierte Anfrage zu erstellen. Ich habe das zwar schon einmal gesagt, aber ich denke, es lohnt sich, es noch einmal zu sagen. Sie müssen WebRequest zu Binance in den Plattformeinstellungen aktivieren, bevor Ihr MQL5-Skript dies tun kann. Fügen Sie https://api.binance.com zur Liste der zulässigen URLs im Bereich Expert Advisors hinzu, nachdem Sie Strg+O gedrückt haben, um die Optionen aufzurufen. Dies ist eine Voraussetzung, bevor wir signierte API-Anfragen senden, da dies sicherstellt, dass Ihr Skript mit den Binance-Servern kommunizieren kann, ohne blockiert zu werden.

Beispiel:
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

   string url_t = "https://api.binance.com/api/v3/time";
   string headers_t = "";
   char result_t[];
   string response_headers_t;
   char data_t[];

   int status_t = WebRequest("GET", url_t, headers_t, 5000, data_t, result_t, response_headers_t);
   string time = CharArrayToString(result_t);

   Print(time);
  }

Ausgabe:

Abbildung 1. Zeitstempel

Erläuterung:

Das Skript beginnt mit der Definition der URL des Binance-Endpunkts, der die aktuelle Serverzeit angibt. Unsere MQL5-Software wird eine Anfrage an diese URL senden, um den offiziellen Binance-Zeitstempel abzurufen. Die Verwendung der Serverzeit ist von entscheidender Bedeutung, da sie garantiert, dass alle signierten Anfragen, die wir anschließend übermitteln, mit der Binance-Uhr synchronisiert sind, wodurch Fehler oder Ablehnungen durch inkonsistente Zeitstempel vermieden werden. Das Skript erstellt dann eine leere Zeichenkette für Header. Die Header können leer bleiben, da keine Authentifizierung erforderlich ist, da diese Anfrage an eine öffentliche API gerichtet ist. Andererseits werden für private Abfragen Header mit Ihrem API-Schlüssel oder anderen Anmeldeinformationen benötigt. Es ist jedoch zulässig, die Header leer zu lassen, wenn der Server-Zeitstempel abgerufen wird.

Zusätzlich werden vom Skript Arrays deklariert, um den Inhalt der Anfrage und die Antwort zu speichern. Da eine GET-Anfrage keine Daten enthält, bleibt das Array für den Anfragekörper leer, während das Array für die Antwort die vom Server zurückgegebenen Rohdaten enthält. Alle Header, die der Server zurückgibt, werden in einer anderen Variablen gespeichert. Obwohl dies optional ist, kann es für die Fehlersuche oder Überprüfung weiterer Daten, die Binance zurückgegeben hat, nützlich sein. Die GET-Anfrage wird dann über die WebRequest-Funktion an Binance gesendet. Zu den Parametern, die diese Funktion akzeptiert, gehören der Anfragetyp, die URL, die Header, die Timeout-Zeit in Millisekunden, der Inhalt der Anfrage, das Array für die Speicherung der Antwort und die Variable für die Rückgabe der Header. Die Funktion gibt einen Statuscode zurück, der angibt, ob die Anfrage erfolgreich war. In der Regel wird bei einer erfolgreichen Anfrage ein Statuscode von 200 ausgegeben.

Das rohe Byte-Array wird in eine lesbare Zeichenkette umgewandelt, sobald die Antwort des Servers eingegangen ist. Diese Konvertierung ermöglicht es uns, die Daten so zu extrahieren, dass sie von Menschen genutzt werden können. Der Zeitstempel wird vom Binance-Server als eine Reihe von Bytes im JSON-Format gesendet. Um zu überprüfen, ob die Anfrage erfolgreich war und ob wir die aktuelle Binance-Serverzeit in Millisekunden haben, gibt das Skript abschließend den Zeitstempel aus.

Analogie:

Angenommen, Sie möchten wissen, wie spät es in der Stadt eines Freundes ist, bevor Sie einen Anruf tätigen. Um sicherzustellen, dass Ihr Schreiben den Empfänger erreicht, müssen Sie zunächst dessen Adresse angeben. Dies ist vergleichbar mit der Angabe der Binance-Endpunkt-URL im Skript, die dem Programm den genauen Ort für die Übermittlung der Anfrage angibt. Es weist Ihr MQL5-Programm an, wo genau es die Anfrage stellen muss, um die offizielle Serverzeit zu erhalten. Es ist wichtig, diese Serverzeit zu verwenden, da sie garantiert, dass Ihr Timing mit der Uhr von Binance übereinstimmt, wenn Sie später Aktionen planen. Ihre Pläne können sich ändern, und Binance kann Ihre Anfrage ablehnen, wenn Sie stattdessen Ihre eigene lokale Uhr verwenden. 

Ziehen Sie dann die Möglichkeit in Betracht, dass Ihr Umschlag weitere Anweisungen oder Notizen enthalten könnte. Die Header der WebRequest sind ähnlich wie diese. Für diese spezielle Anfrage, die sich auf die Serverzeit bezieht, benötigen Sie keine weiteren Hinweise, da Binance bereits weiß, worum Sie bitten. Ähnlich wie bei der Aufnahme eines API-Schlüssels in die Header müssen Sie bei anderen Arten von Anfragen, z. B. bei der Übertragung sensibler Daten, möglicherweise einen Geheimcode oder eine Identität angeben.

Stellen Sie sich die Antwort als ein Paket vor, das Binance zurückschickt. Das Antwort-Array im Skript dient als Ort, an dem das Paket aufgefangen und gespeichert wird. Der Anfragekörper ist leer, da Sie lediglich eine Abfrage stellen und keine weiteren Informationen angeben. Wenn Sie weitere Informationen darüber wünschen, wie die Antwort gesendet wurde, können Sie die zurückgegebenen Header einsehen, die im Wesentlichen zusätzliche Hinweise zum Paket enthalten. Die Verwendung der WebRequest-Funktion ist vergleichbar mit dem Versand eines Briefes. Sie geben an, wo der zurückgesendete Brief hinterlegt werden soll, die Art der Sendung, den Bestimmungsort und wie lange die Post versuchen soll, bevor sie aufgibt. Der Statuscode fungiert bei der Rücksendung des Briefes als Zustellungsbeleg, der angibt, ob die Anfrage erfolgreich bearbeitet wurde. Ein 200er Code bestätigt, dass alles erfolgreich abgeschlossen wurde.

Die Informationen befinden sich schließlich im Inneren der Verpackung, wenn Sie diese öffnen; allerdings können sie zunächst in einem Code geschrieben sein, den Sie nicht entziffern können. Die Übersetzung dieser geheimen Kommunikation in die normale Sprache ist vergleichbar mit der Umwandlung des Byte-Arrays in einen lesbaren Text. Das Ausdrucken des Zeitstempels, der die genaue Serverzeit in Millisekunden anzeigt, ist ähnlich wie das Lesen der Mitteilung von Binance. Wenn Sie wissen, dass Ihre Zeit mit der Uhr von Binance übereinstimmt, können Sie Ihre nächsten Schritte sicher planen. Anhand der WebRequest-Ausgabe können wir sehen, dass die Serverantwort im JSON-Format vorliegt. Die Antwort enthält neben den Rohdaten auch strukturierte Schlüssel und Werte. Das JSON-Objekt für diesen speziellen Endpunkt hat einen einzigen Schlüssel namens serverTime, dessen Wert den aktuellen Zeitstempel des Servers in Millisekunden angibt. Das Extrahieren des Zeitstempels ist aufgrund des Antwortformats einfach.

Bei der Erstellung unserer API-Signatur verwenden wir den mit serverTime verknüpften Wert als Nachricht, das ist alles, was wir brauchen. Wir können sicherstellen, dass unsere nachfolgenden signierten Anfragen mit der Serverzeit von Binance übereinstimmen und somit von den privaten Endpunkten genehmigt werden, indem wir diesen numerischen Wert isolieren.

Beispiel:
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

   string url_t = "https://api.binance.com/api/v3/time";
   string headers_t = "";
   char result_t[];
   string response_headers_t;
   char data_t[];

   int status_t = WebRequest("GET", url_t, headers_t, 5000, data_t, result_t, response_headers_t);
   string time = CharArrayToString(result_t);

   string pattern = "{\"serverTime\":";
   int pattern_lenght = StringFind(time,pattern);
   pattern_lenght += StringLen(pattern);
   int end = StringFind(time,"}",pattern_lenght + 1);

   string server_time = StringSubstr(time,pattern_lenght,end - pattern_lenght);
   Print(server_time);

  }

Erläuterung:

Die erste Zeile definiert eine Zeichenkette namens „pattern“, die „serverTime“ enthält. Das JSON-Objekt, das der Binance-Server zurückgab, hatte genau diesen Anfang. Wenn wir dieses Muster erkennen, können wir den Beginn des echten Zeitstempelwerts innerhalb der gesamten JSON-Antwort ermitteln.

Der nächste Schritt besteht darin, dieses Muster in der Reihe der Antworten zu finden. Die Funktion gibt den Anfangsindex des Musters in der Antwort zurück. Wir hängen die Länge des Musters an diese Stelle an, da wir an dem Wert interessiert sind, der auf das Muster folgt. Dies liefert den Zeitstempel des Servers für den Beginn der Zeichenkette.

Analogie:

Stellen Sie sich vor, Sie erhalten eine kleine Schachtel mit einer Notiz von einem Freund. Die Notiz beginnt mit einem Header, der „serverTime:“ lautet, gefolgt von einer langen Zahl. Die Überschrift und das weitere Material sind für Sie nicht relevant, nur die Nummer ist relevant. Die Suche nach dem Header in der JSON-Antwort ist der erste Schritt, ähnlich wie die Suche nach der Serverzeit. Sobald Sie die Nummer gefunden haben, ignorieren Sie den Header und konzentrieren sich auf die Nummer selbst, die die notwendigen Informationen enthält. Die schließende Klammer im JSON-Objekt zeigt das Ende der Ganzzahl an, nach der Sie dann suchen. Dies ist vergleichbar mit dem Auffinden des Endes des Zettels im Paket. Da Sie nun genau wissen, wo die Zahl beginnt und wo sie endet, können Sie vorsichtig nur die Zahl entfernen und die Überschrift und alle anderen Zeichen weglassen.

Zum Schluss notieren Sie sich die Zahl oder lesen sie sich laut vor. Dies bedeutet, dass die Teilzeichenkette im Code extrahiert wird, die allein die numerische Serverzeit enthält. Das Ausdrucken ist vergleichbar mit dem Notieren der Nummer auf Papier, damit Sie sie für Ihre nächste Aufgabe verwenden können. Genauso wie Sie die genaue Uhrzeit, die Ihr Freund auf den Zettel geschrieben hat, für die Planung einer Aktivität nutzen würden, können Sie die Zahl auf diese Weise isolieren und sie direkt als Nachricht verwenden, wenn Sie Ihre API-Signatur erstellen.

 

Generierung Ihres Binance API-Schlüssels und geheimen Schlüssels

Ein API-Schlüssel und ein geheimer Schlüssel sind erforderlich, um mit Binance über MQL5 zu kommunizieren und authentifizierte API-Anfragen zu stellen. Dank dieser beiden Schlüssel, die als Benutzername und Passwort fungieren, kann sich Ihr Programm sicher mit Binance verbinden und Aufgaben auf Ihrem Konto ausführen, wie z. B. die Überprüfung des Kontostands oder das Tätigen von Geschäften. Während der geheime Schlüssel dazu dient, sichere Signaturen zu erstellen, um nachzuweisen, dass die Anfragen tatsächlich von Ihnen stammen, identifiziert der API-Schlüssel Ihr Konto. Der geheime Schlüssel ist genau das, was unsere MQL5-Skripte zur Erstellung der Signatur verwenden werden.

Sie müssen sich zunächst in Ihr Binance-Konto einloggen, um diese Schlüssel zu generieren. Gehen Sie nach der Anmeldung zu Ihrem Profil und wählen Sie dann API-Verwaltung. Hier wird die Option zum Generieren eines neuen API-Schlüssels angezeigt. Binance wird Sie auffordern, einen Namen oder eine Bezeichnung anzugeben. Wählen Sie einen beschreibenden Namen, z. B. „MQL5 Trading Bot“, damit Sie ihn in Zukunft schnell wiedererkennen können, insbesondere wenn Sie mehrere API-Schlüssel generieren. Binance wird den geheimen Schlüssel und den API-Schlüssel nach der Benennung des Schlüssels erstellen. Der geheime Schlüssel wird nur einmal angezeigt; der API-Schlüssel wird jedoch sofort sichtbar.

Es ist wichtig, den geheimen Schlüssel sicher aufzubewahren, da Binance ihn nicht mehr anzeigen wird. Es kann in einem sicheren Passwort-Manager oder in einer gesicherten Datei aufbewahrt werden. Geben Sie Ihren privaten Schlüssel niemals an Außenstehende weiter oder fügen Sie ihn in Skripte ein, die andere Personen sehen könnten. Wenn die Schlüssel generiert werden, müssen Sie auch die Berechtigungen für den API-Schlüssel einrichten. Normalerweise müssen Sie die Option „Read Info“ aktivieren, um Kontostände abzurufen und Abfragen von MQL5 zu senden. Wenn Ihr Bot Handel treiben soll, müssen Sie auch den Handel aktivieren. Um zu verhindern, dass Geld von Ihrem Konto abgehoben wird, sollten Sie Abhebungen nur dann zulassen, wenn sie unbedingt notwendig sind.

Ihr MQL5-Programm kann Signaturen erstellen und abgesicherte Anfragen an Binance senden, nachdem Sie sowohl den geheimen Schlüssel als auch den API-Schlüssel haben. Da er zusammen mit der Nachricht und dem Zeitstempel zur Erstellung einer eindeutigen Signatur verwendet wird, ist der geheime Schlüssel sehr wichtig. Dies schützt Ihre Anfragen vor Eingriffen und stellt sicher, dass nur Ihre Software auf Ihr Konto zugreifen kann.

 

Erstellen von Binance-API-Signaturen in MQL5

Der nächste Schritt besteht darin, eine Signatur zu erstellen, da wir nun wissen, wie wir eine API-GET-Anfrage verwenden können, um die Binance-Serverzeit zu erhalten, und wir haben erfolgreich einen API-Schlüssel und einen geheimen Schlüssel erstellt. Eine Signatur ist ein sicheres Verfahren, um nachzuweisen, dass die an Binance gestellten Anfragen echt und unverändert sind, wie wir im letzten Beitrag beschrieben haben. Der Unterschied besteht darin, dass wir die Signatur diesmal mit den genauen Parametern erstellen, die für die private API von Binance erforderlich sind. Wir erstellen eine eindeutige Signatur, indem wir den geheimen Schlüssel mit dem aktuellen Server-Zeitstempel in Millisekunden kombinieren. Durch Hinzufügen dieser Signatur zur API-Anfrage kann Binance die Legitimität der Anfrage und die Integrität der Daten überprüfen.

Da Binance alle Anfragen an private Endpunkte zurückweist, die unsigniert oder nicht ordnungsgemäß signiert sind, ist die Erstellung der Signatur ein wesentlicher Schritt. Sie können sicher sein, dass Ihr MQL5-Skript effektiv und sicher mit Binance kommunizieren kann, indem Sie die Anweisungen sorgfältig befolgen und den Server-Zeitstempel zusätzlich zu Ihrem geheimen Schlüssel verwenden. Die Deklaration von zwei String-Variablen wird der erste Schritt in unserem MQL5-Programm sein. Die Binance-Serverzeit, die wir zuvor über die API-Anfrage erhalten haben, wird in einer dieser Variablen gespeichert. Wenn wir die Signatur erstellen, wird die Nachricht diese Serverzeit, ausgedrückt in Millisekunden, enthalten. Der private Schlüssel, der auf dem Binance-Dashboard erstellt wurde, wird in der zweiten String-Variable gespeichert. Da er das entscheidende Element ist, mit dem nachgewiesen wird, dass die Anfrage tatsächlich von Ihnen stammt, ist dieser geheime Schlüssel privat und muss sicher aufbewahrt werden.

Der nächste Schritt besteht darin, beide Werte in Byte-Arrays umzuwandeln, nachdem sie als Zeichenketten gespeichert worden sind. Bevor wir eine Signatur erstellen können, ist diese Übersetzung erforderlich, da die kryptografischen Algorithmen von MQL5 auf Byte-Ebene und nicht direkt mit Zeichenketten arbeiten. Bei dieser Konvertierung verwenden wir die UTF-8-Kodierung, um Konsistenz zu gewährleisten und Kodierungsprobleme zu vermeiden. Durch die Verwendung von UTF-8 können Sie sicher sein, dass die Nachricht und der geheime Schlüssel in einer Standardform dargestellt werden, die der Binance-Server und Ihr MQL5-Programm auf die gleiche Weise verstehen würden. Wir bereiten sowohl die Serverzeit als auch den geheimen Schlüssel für das Hashing und die Signierung vor, indem wir sie mit der UTF-8-Kodierung von Zeichenketten in Byte-Arrays umwandeln.

Beispiel:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

   string url_t = "https://api.binance.com/api/v3/time";
   string headers_t = "";
   char result_t[];
   string response_headers_t;
   char data_t[];

   int status_t = WebRequest("GET", url_t, headers_t, 5000, data_t, result_t, response_headers_t);
   string time = CharArrayToString(result_t);

   string pattern = "{\"serverTime\":";
   int pattern_lenght = StringFind(time,pattern);
   pattern_lenght += StringLen(pattern);
   int end = StringFind(time,"}",pattern_lenght + 1);

   string server_time = StringSubstr(time,pattern_lenght,end - pattern_lenght);

   string message = "timestamp=" + server_time;
   string secrete_key = "ABCDER2y8VAzqopxzLVEhVYABCDEV2AxIYLueComud3aSEez8Z8fvgHPZTXABCDE";

   uchar uMsg[], uSKey[];
   StringToCharArray(message, uMsg, 0, StringLen(message), CP_UTF8);
   StringToCharArray(secrete_key, uSKey, 0, StringLen(secrete_key), CP_UTF8);

  }

Erläuterung:

An diesem Punkt beginnen wir mit der Angabe der zu signierenden Nachricht. Der Serverzeitwert, den wir zuvor aus der Binance-API-Antwort extrahiert haben, wird mit der Zeichenkette timestamp= kombiniert, um die Nachricht zu bilden. Da Binance verlangt, dass signierte Anfragen eine strenge Parametersyntax einhalten, ist das Hinzufügen dieses Präfixes erforderlich. Der Server signiert keine Rohwerte. Schlüssel-Wert-Paare werden von ihm signiert. Die erzeugte Signatur wird nicht mit dem übereinstimmen, was Binance auf seiner Seite berechnet, und die Anfrage wird abgelehnt, wenn wir versuchen, nur den Serverzeitwert zu verwenden, ohne timestamp= anzugeben. Aus diesem Grund muss die Nachricht genau so formuliert werden, wie es die Binance-API-Spezifikation vorschreibt.

Der geheime Schlüssel wird dann in einer String-Variablen gespeichert, die wir angeben. Dieser Wert, der der vom Binance-Dashboard erzeugte private Schlüssel ist, muss jederzeit sicher aufbewahrt werden. Binance erhält niemals den privaten Schlüssel als Teil der Anfrage. Vielmehr wird die Signatur direkt in der MQL5-Anwendung erstellt. Da Binance bereits eine Kopie dieses Schlüssels besitzt, kann es dieselbe Signatur auf seiner Seite erzeugen, um die Anfrage zu validieren. Wir deklarieren zwei Zeichen-Arrays, nachdem wir die Nachricht und den geheimen Schlüssel als Zeichenketten angegeben haben. Der geheime Schlüssel und die Byte-Darstellung der Nachricht werden in diesen Feldern gespeichert. Dieser Konvertierungsschritt ist vor der Erstellung der Signatur erforderlich, da die kryptografischen Verfahren von MQL5 mit Bytes und nicht mit einfachen Zeichenketten arbeiten.

Anschließend wird die UTF-8-Kodierung verwendet, um die Nachrichten-Zeichenkette in ein Byte-Array umzuwandeln. Dies garantiert ein einheitliches und vorhersehbares Format für jedes Zeichen in der Nachricht. Der geheime Schlüssel wird demselben Umwandlungsverfahren unterzogen. Die Verwendung der UTF-8-Kodierung ist von entscheidender Bedeutung, da sie sicherstellt, dass die in MQL5 verwendete Byte-Darstellung mit der von Binance verwendeten übereinstimmt, wenn die gleiche Signaturberechnung ausgeführt wird.

Analogie:

Nehmen wir an, Sie möchten einen Einschreibebrief an eine Sicherheitsdienststelle senden, die nur Briefe in einem bestimmten Format annimmt. Sie beginnen damit, den Inhalt des Briefes zu schreiben. Die Zeit ist in diesem Fall der Inhalt. Eine einfache, auf Papier gedruckte Nummer wird vom Amt jedoch nicht akzeptiert. Sie geht davon aus, dass die Uhrzeit deutlich angegeben wird, z. B. durch die Angabe „Zeitstempel entspricht dieser Uhrzeit“. Das Amt wird den Brief zurückweisen, da er nicht dem erforderlichen Format entspricht, wenn Sie nur die Nummer ohne Aufkleber schicken. Aus diesem Grund ist es notwendig, timestamp= vor die Serverzeit zu setzen. Ohne sie wird der Vorschlag niemals genehmigt werden.

Als Nächstes stellen Sie sich den geheimen Schlüssel als einen persönlichen Stempel vor, den nur Sie besitzen. Diese Marke wurde nie in den Umschlag gelegt. Vielmehr nutzen Sie es an Ihrem Arbeitsplatz, um den Brief vor dem Versand mit Anmerkungen zu versehen. Anhand dieses Stempels kann das Amt nachprüfen, ob die Sendung tatsächlich von Ihnen stammt. Das Amt weiß sofort, dass Ihr Brief gefälscht ist, wenn jemand anders versucht, ihn ohne den Stempel zu vervielfältigen. Stellen Sie sich einmal vor, dass handgeschriebene Briefe von der Behörde nicht gelesen werden. Nur Text, der mit einem bestimmten Tastaturlayout geschrieben wurde, wird von ihm verstanden. Folglich müssen Sie beim Umschreiben der Nachricht und der geheimen Stempelinformationen dasselbe Format verwenden. Um sicherzustellen, dass es beim Lesen des Briefes nicht zu Verwechslungen kommt, werden die Nachricht und der geheime Schlüssel mit UTF-8 in Byte-Arrays umgewandelt, als würde man alles auf einer standardisierten Tastatur eingeben.

Beispiel:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

   string url_t = "https://api.binance.com/api/v3/time";
   string headers_t = "";
   char result_t[];
   string response_headers_t;
   char data_t[];

   int status_t = WebRequest("GET", url_t, headers_t, 5000, data_t, result_t, response_headers_t);
   string time = CharArrayToString(result_t);

   string pattern = "{\"serverTime\":";
   int pattern_lenght = StringFind(time,pattern);
   pattern_lenght += StringLen(pattern);
   int end = StringFind(time,"}",pattern_lenght + 1);

   string server_time = StringSubstr(time,pattern_lenght,end - pattern_lenght);

   string message = "timestamp=" + server_time;
   string secrete_key = "ABCDER2y8VAzqopxzLVEhVYABCDEV2AxIYLueComud3aSEez8Z8fvgHPZTXABCDE";

   uchar uMsg[], uSKey[];
   StringToCharArray(message, uMsg, 0, StringLen(message), CP_UTF8);
   StringToCharArray(secrete_key, uSKey, 0, StringLen(secrete_key), CP_UTF8);

   int blockSize = 64;
   uchar ipad[], opad[];
   ArrayResize(ipad, blockSize);
   ArrayResize(opad, blockSize);

   for(int i = 0; i < blockSize; i++)
     {
      ipad[i] = uSKey [i] ^ 0x36;
      opad[i] = uSKey [i] ^ 0x5C;
     }

   uchar innerData[], innerHash[];
   ArrayCopy(innerData, ipad);
   ArrayCopy(innerData, uMsg, blockSize);
   CryptEncode(CRYPT_HASH_SHA256, innerData, uSKey, innerHash);

   uchar outerData[], finalHash[];
   ArrayCopy(outerData, opad);
   ArrayCopy(outerData, innerHash, blockSize);
   CryptEncode(CRYPT_HASH_SHA256, outerData, uSKey, finalHash);

   string signature = "";
   for(int i = 0; i < ArraySize(finalHash); i++)
      signature += StringFormat("%02x", finalHash[i]);

   Print(signature);
  }

Erläuterung:

Zunächst wird die Blockgröße auf 64 Byte festgelegt. Die Anforderungen des Hashing-Algorithmus bestimmen diesen Wert. Die Verwendung der richtigen Blockgröße stellt sicher, dass die von uns bereitgestellten Daten den Erwartungen des Algorithmus entsprechen, da der Algorithmus mit Datenstücken fester Größe arbeitet. Dann werden zwei Byte-Arrays deklariert. Das innere Polster wird durch das eine, das äußere Pad durch das andere dargestellt. Um die Blockgröße anzupassen, werden beide Felder verkleinert. Diese Arrays sind derzeit leere Container mit einer Kapazität von jeweils genau 64 Byte. Diese Pads sind für die Aufteilung der inneren und äußeren Hashing-Prozesse unerlässlich und werden bald mit Werten gefüllt, die aus dem geheimen Schlüssel gewonnen werden.

Die Pads werden in der anschließenden Schleife vorbereitet. Vom ersten Byte bis zum vierundsechzigsten Byte wird die Schleife ausgeführt. Mit einer exklusiven ODER-Verknüpfung wird ein Byte des geheimen Schlüssels mit einer festen Konstante für jede Stelle kombiniert. Das innere Pad verwendet eine Konstante, während das äußere Pad eine andere Konstante verwendet. Bei diesem Verfahren wird der geheime Schlüssel auf einheitliche und geregelte Weise geändert. Das Ergebnis sind zwei verschiedene Schlüsselversionen, eine für den äußeren Hashing-Schritt und eine für den inneren Hashing-Schritt. Diese Aufteilung ist entscheidend für die Sicherheit und trägt zur Manipulationssicherheit der Signatur bei.

Wenn die Pads fertig sind, werden die Daten für die innere Hashing-Phase vorbereitet. Das innere Pad wird in ein neues Byte-Array kopiert, das zur Speicherung der kombinierten Daten erstellt wird. Die Nachrichtenbytes werden dann, beginnend an der Position der Blockgröße, eingefügt. Dies ergibt ein einzelnes kontinuierliches Byte-Array mit der Nachricht nach dem inneren Pad. Der kryptografische Hash-Algorithmus empfängt dann diese kombinierten Daten und erzeugt einen Hash-Wert. Die ursprüngliche Umwandlung der Nachricht unter Verwendung des geheimen Schlüssels wird durch dieses Ergebnis dargestellt, das als innerer Hash bezeichnet wird.

Das Verfahren geht nach der Erstellung des inneren Hashes zur äußeren Hash-Phase über. Das äußere Pad wird in ein neues Byte-Array kopiert. Dieses Array wird dann dem inneren Hash hinzugefügt. Das äußere Pad und das Ergebnis des ersten Hashes werden zu einer neuen Folge von Bytes kombiniert. Der endgültige Hash wird erstellt, indem die Daten ein weiteres Mal durch den Hashing-Prozess laufen. Auf Byte-Ebene stellt dieser endgültige Hash die tatsächliche Signaturausgabe dar.

Die Signatur liegt zu diesem Zeitpunkt noch in Form von Rohbytes vor; sie kann daher nicht direkt in einem API-Aufruf verwendet werden. Eine leere Zeichenkette wird gebildet, um sie nutzbar zu machen. Die Bytes des resultierenden Hashes werden dann in einer Schleife durchlaufen. Das Byte wird an die Signaturkette angehängt, nachdem es in jedem Zyklus in eine zweistellige Hexadezimaldarstellung umgewandelt wurde. Dieser Vorgang wird wiederholt, bis alle Bytes verarbeitet wurden.

Die endgültige Signatur wird durch eine einzige hexadezimale Zeichenkette dargestellt, nachdem die Schleife beendet ist. Wir können diesen Wert direkt in einer API-Anfrage verwenden und die Ausgabe durch Drucken bestätigen. Diese Zeichenkette wird Binance als Beweis dafür übergeben, dass die Anfrage legitim ist, richtig geformt und mit dem richtigen geheimen Schlüssel erstellt wurde.

Analogie:

Nehmen wir an, Sie wollen ein starkes Wachssiegel für ein wichtiges Dokument herstellen. Dieses Siegel muss zwei Dinge zeigen. Erstens, dass Sie das Dokument tatsächlich geschrieben haben. Zweitens, dass während der Zustellung keine Änderungen an dem Dokument vorgenommen wurden. Die Herstellung einer Form mit fester Größe für die Dichtung ist der erste Schritt in diesem Prozess. Egal wie lang Ihre Botschaft oder Ihr Geheimsatz ist, diese Form hat immer die gleiche Größe. Da die Versiegelungstechnik für diese Größe entwickelt wurde, ist die Formgröße festgelegt. Die Blockgröße zeigt dies an. Sie legt den Bereich fest, in dem das Versiegelungsverfahren stattfindet.

Sie erhalten dann zwei einzelne Wachsplatten. Ihr Geheimwort wird verwendet, um beide zu erstellen, aber sie werden unterschiedlich behandelt. Eine erste Standardkomponente wird mit dem einen Blatt kombiniert, während ein zweiter Standardbestandteil mit dem anderen Blatt kombiniert wird. Die geheime Phrase wird durch diese Mischphase auf zwei verschiedene Arten leicht verändert. Das Endprodukt sind zwei verschiedene Wachsplatten, die unterschiedliche Funktionen im Versiegelungsprozess haben, aber demselben Geheimnis entstammen. Das sind die inneren und äußeren Pads.

Sobald die Wachsplatten vorbereitet sind, können Sie mit dem ersten Versiegelungsschritt fortfahren. Nachdem Sie das erste Wachsblatt in die Form gelegt haben, legen Sie Ihr Papier darauf. Sie werden zu einem einzigen zusammengefassten Stapel zusammengefasst. Durch Verpressen dieses Stapels mit einer Stanzmaschine wird ein Zwischensiegel erstellt. Das letzte Siegel ist nicht dieses. Es handelt sich lediglich um ein vorläufiges Ergebnis, das in der nächsten Phase genutzt wird. Dann beginnt die zweite Versiegelungsphase. Sie legen die zweite Wachsplatte in die Form. Darauf wird dann die Zwischenversiegelung aufgebracht. Mit der gleichen Stanzmaschine wird dieser neue Stapel noch einmal gepresst. Das endgültige Wachssiegel ist das Ergebnis dieser zweiten Presse. Sowohl Ihr Dokument als auch Ihre geheime Phrase werden durch dieses Siegel eindeutig repräsentiert, und selbst eine geringfügige Änderung an einem der beiden Siegel würde zu einem völlig anderen Siegel führen.

Das Siegel befindet sich nun in einem unbearbeiteten physischen Zustand, der es schwierig macht, es zu versenden oder digital an ein Dokument anzuhängen. Sie übersetzen das Siegel akribisch in einen schriftlichen Code mit zwei Zeichen für jede Komponente, um es nutzbar zu machen. Bis das gesamte Siegel als eine einzige lesbare Zeichenkette dargestellt ist, gehen Sie das gesamte Siegel Stück für Stück durch und schreiben seine kodierte Form auf. Zum Schluss prüfen und bestätigen Sie den fertigen Code. Sie hängen diesen Code an Ihr Dokument an, wenn Sie es per E-Mail versenden. Der Empfänger verwendet seine Kopie Ihrer geheimen Phrase, um nach Erhalt des Dokuments den gleichen Versiegelungsvorgang zu wiederholen. Sie können sicher sein, dass das Dokument echt und unverfälscht ist, wenn ihr Siegel genau mit dem Ihren übereinstimmt. 

 

Senden von authentifizierten Anfragen an die Binance-API

Das Senden einer authentifizierten Anfrage an die Binance-API ist der nächste Schritt, nachdem Sie gelernt haben, wie man API-Signaturen in MQL5 erstellt. Während kontobezogene Endpunkte, wie die Abfrage des Kontostands, eine Authentifizierung erfordern, können öffentliche Endpunkte ohne zusätzliche Authentifizierung aufgerufen werden. Hier kommen die Serverzeit, die von Ihnen erstellte Signatur und der API-Schlüssel zusammen. Eine signierte Anfrage muss an einen privaten Endpunkt gesendet werden, um Ihr verfügbares Kontoguthaben für jedes Asset auf Binance abzurufen. Die Header der Anfrage enthalten Ihren API-Schlüssel, während die Parameter den Zeitstempel und die Signatur enthalten. Um sicherzustellen, dass die Anfrage authentisch ist und die Daten nicht verändert wurden, überprüft Binance diese Details.

Der Server antwortet mit einem JSON-Objekt, das Informationen zu jedem Vermögenswert auf Ihrem Konto enthält, einschließlich des verfügbaren und des gesperrten Kontoguthabens, nachdem die Anfrage ordnungsgemäß gesendet wurde. Sie können dann die erforderlichen Kontoinformationen aus dieser Antwort innerhalb Ihrer MQL5-Software extrahieren und bearbeiten. An dieser Stelle beginnt Ihr Code, tatsächlich mit Ihrem Binance-Konto zu interagieren.

Beispiel:
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---

   string url_t = "https://api.binance.com/api/v3/time";
   string headers_t = "";
   char result_t[];
   string response_headers_t;
   char data_t[];

   int status_t = WebRequest("GET", url_t, headers_t, 5000, data_t, result_t, response_headers_t);
   string time = CharArrayToString(result_t);

   string pattern = "{\"serverTime\":";
   int pattern_lenght = StringFind(time,pattern);
   pattern_lenght += StringLen(pattern);
   int end = StringFind(time,"}",pattern_lenght + 1);

   string server_time = StringSubstr(time,pattern_lenght,end - pattern_lenght);

   string message = "timestamp=" + server_time;
   string secrete_key = "ABCDER2y8VAzqopxzLVEhVYABCDEV2AxIYLueComud3aSEez8Z8fvgHPZTXABCDE";

   uchar uMsg[], uSKey[];
   StringToCharArray(message, uMsg, 0, StringLen(message), CP_UTF8);
   StringToCharArray(secrete_key, uSKey, 0, StringLen(secrete_key), CP_UTF8);

   int blockSize = 64;

   uchar ipad[], opad[];
   ArrayResize(ipad, blockSize);
   ArrayResize(opad, blockSize);

   for(int i = 0; i < blockSize; i++)
     {
      ipad[i] = uSKey [i] ^ 0x36;
      opad[i] = uSKey [i] ^ 0x5C;
     }

   uchar innerData[], innerHash[];
   ArrayCopy(innerData, ipad);
   ArrayCopy(innerData, uMsg, blockSize);
   CryptEncode(CRYPT_HASH_SHA256, innerData, uSKey, innerHash);

   uchar outerData[], finalHash[];
   ArrayCopy(outerData, opad);
   ArrayCopy(outerData, innerHash, blockSize);
   CryptEncode(CRYPT_HASH_SHA256, outerData, uSKey, finalHash);

   string signature = "";
   for(int i = 0; i < ArraySize(finalHash); i++)
      signature += StringFormat("%02x", finalHash[i]);

   Print(signature);

   string query_string = "";
   query_string += "&signature=" + signature;

   string time_stamp = "timestamp=" + server_time;
   string url = "https://api.binance.com/api/v3/account?"+ time_stamp + query_string;

   string API_KEY = "ABcdeviQHg3LD9ncT0mabcdepfz2a3qkNvrI0abcdeIZYU5umZgeowabcdeMbq8A";
   string headers = "X-MBX-APIKEY: " + API_KEY + "\r\n";

   char   result[];
   string response_headers;
   char   datas[];

   int status = WebRequest("GET", url, headers, 5000, datas, result, response_headers);
   string server_result = CharArrayToString(result);

   Print(server_result);

  }

Erläuterung:

Im ersten Schritt werden die für Binance erforderlichen Anfrageparameter vorbereitet. Die Signatur wird an eine leere Zeichenkette angehängt, die zum Speichern zusätzlicher Abfragewerte konstruiert wird. Die Signatur darf niemals innerhalb des Headers oder des Textkörpers angegeben werden, sondern muss Teil der URL-Abfrage sein. Unabhängig davon wird die Serverzeit, die Sie zuvor von Binance erhalten haben, verwendet, um den Zeitstempel in das richtige Format zu bringen. Dieser Zeitstempel hilft Binance bei der Abwehr von Replay-Attacken und zeigt, dass die Anfrage vor kurzem gestellt wurde. Die endgültige Anfrage-URL, die an Binance gesendet wird, wird dann durch Kombination des Datums und der Signatur mit der Basis-Endpunkt-URL erstellt.

Danach ist der API-Schlüssel fertig. Der API-Schlüssel wird nicht an die URL angehängt, wie es bei der Signatur der Fall ist. Vielmehr wird er unter Verwendung des eindeutigen Headernamens eingefügt, den Binance in den Headern der Anfrage vorschreibt. Die Signatur verifiziert, dass die Anfrage mit dem korrekten geheimen Schlüssel genehmigt wurde, und dieser Header zeigt Binance an, von wessen Konto die Anfrage eingereicht wurde. WebRequest verlangt, dass die Header die korrekte HTTP-Syntax einhalten, daher ist der Zeilenumbruch am Ende der Header-Zeichenkette von entscheidender Bedeutung.

Anschließend werden Variablen deklariert, um die Antwort des Servers zu empfangen. Diese bestehen aus einem zusätzlichen Byte-Array, das intern von der WebRequest-Funktion verwendet wird, einer Zeichenkette zur Aufzeichnung der vom Server gelieferten Antwort-Header und einem Byte-Array zur Speicherung des Antwortinhalts. Nach der Verarbeitung der Anfrage verwendet MetaTrader diese Variablen als Container, um alles zu speichern, was Binance zurückliefert. Da für die Anfrage des Kontostandes keine Daten im Anfragetext gesendet werden müssen, wird die Funktion WebRequest mit der Methode GET aufgerufen. Die Funktion erhält die endgültige URL, einen Timeout-Wert und Header mit dem API-Schlüssel. Binance prüft die Anfrage, bestätigt die Signatur und den Zeitstempel und gibt Ihre Kontoinformationen zurück, wenn alles korrekt ist.

Um das Lesen und Verarbeiten innerhalb von MQL5 zu erleichtern, wird die rohe Antwort, die als Zeichenfeld empfangen wurde, schließlich in eine Zeichenkette umgewandelt. Sie können die vollständige JSON-Antwort von Binance, die Details zum verfügbaren Kontoguthaben für jedes Asset auf Ihrem Konto enthält, anzeigen, indem Sie dieses Ergebnis ausdrucken. Aus dieser Ausgabe können Sie anschließend bestimmte Daten extrahieren, z. B. das freie Kontoguthaben, das gesperrte Kontoguthaben oder die Angaben zu den einzelnen Anlagen.

Analogie:

Angenommen, Sie möchten alle Ihre Kontostände überprüfen, indem Sie einen sicheren Brief an eine Bank senden. Die Bank verlangt, dass jede Anfrage authentisch und unverändert ist, Sie können also nicht einfach hingehen und fragen. Sie beginnen damit, eine persönliche Notiz zu schreiben, die Sie Ihrem Brief beifügen. Ein Zeitstempel und eine Signatur sind zwei wichtige Informationen in dieser Notiz. Der Zeitstempel, der die genaue Zeit angibt, zu der Sie den Brief verfasst haben, funktioniert ähnlich wie ein Poststempel. Damit ist gewährleistet, dass die Bank weiß, dass das Schreiben aktuell ist und nicht veraltet und jemand versucht, es erneut zu verwenden.

Die Signatur dient als Beweis dafür, dass Sie die einzige Person sind, die berechtigt ist, diese Nachricht zu übermitteln, ähnlich wie ein persönliches Wachssiegel. Wenn Ihre Anfrage bei der Bank eingeht, werden beide zusammengelegt und zur Überprüfung auf den Umschlag geklebt. Sie bereiten dann eine ID-Karte vor, die als Darstellung Ihres API-Schlüssels für die Bank dient. Damit die Bank weiß, für welches Konto die Anfrage bestimmt ist, wird dieser in einem sichtbaren Schlitz in den Umschlag gelegt. Die Bank kann Ihren Ausweis sehen, aber da sie Ihren Geheimstempel nicht kennt, kann sie Ihre Signatur nicht fälschen.

Sie übergeben den Umschlag nun einem zuverlässigen Kurier. Die WebRequest-Funktion in MQL5 wird durch diesen Kurier dargestellt. Nachdem der Kurier Ihre Post bei der Bank abgegeben hat, wartet er auf eine Antwort. Nach der Überprüfung Ihrer Identität und der Kontrolle des Zeitstempels und des Wachssiegels schreibt die Bank eine Antwort, die den Saldo aller Assets auf Ihrem Konto enthält. Sie öffnen den Umschlag, wenn der Kurier zurückkommt. Wie eine Nachricht, die in einem geheimen Buchformat (JSON) aufgezeichnet wird, ist die Antwort kodiert. Um die Salden leicht erkennen zu können, müssen Sie sie in eine lesbare Sprache umwandeln. Das Ausdrucken aus dem Programm ist vergleichbar mit dem Aufstellen des Hauptbuchs auf Ihrem Schreibtisch, damit Sie jeden Eintrag überprüfen können. 

Die Daten müssen dann in einer Datei gespeichert werden, wenn die Anfrage abgeschickt wurde und der Server geantwortet hat. Sie können das Ergebnis debuggen, eine dauerhafte Aufzeichnung Ihres Kontostandes aufbewahren oder die Antwort später verarbeiten, ohne wiederholte Anfragen an Binance zu stellen, indem Sie die Antwort speichern. Die Standard-Dateifunktionen in MQL5 können verwendet werden, um die Serverantwort in eine Datei zu schreiben.

Beispiel:

string filename = "Binace_Balance.txt";
int handle = FileOpen(filename, FILE_WRITE|FILE_TXT|FILE_SHARE_READ|FILE_ANSI);

if(handle != INVALID_HANDLE)
  {

   FileWrite(handle, server_result);
   FileClose(handle);
   Print("EA successfully wrote the data to " + filename);
  }
else
  {
   Print("Error opening file for writing. Error code: ", + GetLastError());
  }

Erläuterung:

Stellen Sie sich vor, Sie erhalten von Ihrer Bank ein offizielles Schreiben, in dem alle Ihre Kontoguthaben aufgelistet sind. Sie beschließen, es für später aufzubewahren, nehmen ein Notizbuch und beschriften den Einband deutlich. Wenn Sie es wieder brauchen, können Sie es dank dieses Etiketts schnell identifizieren. Die Wahl eines beschreibenden Dateinamens für die Serverantwort ist damit vergleichbar. Danach schlagen Sie das Notizbuch auf einer leeren Seite auf und vergewissern sich, dass sie lesbar und zum Schreiben vorbereitet ist. Ebenso öffnet Ihr Programm eine Datei mit den entsprechenden Einstellungen, damit der lesbare Text korrekt gespeichert werden kann.

Sie kopieren den Inhalt des Briefes auf die Seite, während das Notizbuch geöffnet ist. Nachdem Sie alles notiert haben, schließen Sie das Notizbuch, um den Inhalt zu bewahren. Wenn Sie es schließen, können Sie sicher sein, dass Ihre Notizen sicher sind. Das Schließen der Datei in Ihrer Software bewirkt dasselbe, indem es garantiert, dass die Antwort genau erhalten bleibt. Wenn Sie das Notizbuch nicht öffnen können, schreiben Sie den Grund auf, damit das Problem behoben werden kann. In ähnlicher Weise wird ein Fehlercode zurückgegeben, der Ihnen hilft, einen Fehler beim Öffnen einer Datei zu verstehen und zu beheben.

 

Schlussfolgerung

In diesem Artikel haben wir den nächsten großen Schritt bei der Arbeit mit der Binance-API in MQL5 gemacht. Wir haben gelernt, wie man mithilfe des API-Schlüssels, des geheimen Schlüssels, der Serverzeit und der von uns erstellten Signatur authentifizierte Anfragen sendet, um die Kontosalden für alle Assets abzurufen. Wir haben auch besprochen, wie man die Serverantwort behandelt und sie sicher in einer Datei zur späteren Verwendung oder Weiterverarbeitung speichert.

Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/20978

Beigefügte Dateien |
Die Übertragung der Trading-Signale in einem universalen Expert Advisor. Die Übertragung der Trading-Signale in einem universalen Expert Advisor.
In diesem Artikel wurden die verschiedenen Möglichkeiten beschrieben, um die Trading-Signale von einem Signalmodul des universalen EAs zum Steuermodul der Positionen und Orders zu übertragen. Es wurden die seriellen und parallelen Interfaces betrachtet.
Entwicklung des Price Action Analysis Toolkit (Teil 57): Ein Modul zur Klassifizierung von Marktzuständen in MQL5 Entwicklung des Price Action Analysis Toolkit (Teil 57): Ein Modul zur Klassifizierung von Marktzuständen in MQL5
In diesem Artikel wird ein Modul zur Klassifizierung von Marktzuständen für MQL5 entwickelt, das das Preisverhalten anhand abgeschlossener Preisdaten interpretiert. Durch die Analyse von Volatilitätskontraktion, -expansion und struktureller Konsistenz klassifiziert das Tool die Marktbedingungen als Kompression, Transition, Expansion oder Trend und bietet so einen klaren kontextuellen Rahmen für die Price-Action-Analyse.
Eine alternative Log-datei mit der Verwendung der HTML und CSS Eine alternative Log-datei mit der Verwendung der HTML und CSS
In diesem Artikel werden wir eine sehr einfache, aber leistungsfähige Bibliothek zur Erstellung der HTML-Dateien schreiben, dabei lernen wir auch, wie man eine ihre Darstellung einstellen kann (nach seinem Geschmack) und sehen wir, wie man es leicht in seinem Expert Advisor oder Skript hinzufügen oder verwenden kann.
MQL5-Handelswerkzeuge (Teil 15): Unschärfeeffekte im Canvas, Schatten-Rendering und flüssiges Scrollen mit dem Mausrad MQL5-Handelswerkzeuge (Teil 15): Unschärfeeffekte im Canvas, Schatten-Rendering und flüssiges Scrollen mit dem Mausrad
In diesem Artikel wird das MQL5-Canvas-Dashboard mit fortschrittlichen visuellen Effekten erweitert, einschließlich Unschärfegradienten für Nebelüberlagerungen, Schattenrendering für den Header und Antialiasing für glattere Linien und Kurven. Wir fügen dem Textfeld ein sanftes Mausrad-Scrolling hinzu, das die Zoom-Skalierung des Charts nicht beeinträchtigt – eine klare technische Verbesserung.