English Русский 中文 Español 日本語 Português
Integration von MetaTrader 5 und Python: Daten senden und empfangen

Integration von MetaTrader 5 und Python: Daten senden und empfangen

MetaTrader 5Handel |
4 123 106
Maxim Dmitrievsky
Maxim Dmitrievsky

Warum MQL5 und Python integrieren?

Eine umfassende Datenverarbeitung erfordert umfangreiche Werkzeuge und geht oft über den Sandkasten (Sandbox) einer einzigen Anwendung hinaus. Für die Verarbeitung und Analyse von Daten, Statistiken und maschinellem Lernen werden spezielle Programmiersprachen verwendet. Eine der führenden Programmiersprachen für die Datenverarbeitung ist Python. Eine sehr effektive Lösung ist die Nutzung der Leistungsfähigkeit der Sprache und der enthaltenen Bibliotheken für die Entwicklung von Handelssystemen.

Es gibt verschiedene Lösungen, um das Zusammenspiel von zwei oder mehr Programmen zu realisieren. Sockets sind eine der schnellsten und flexibelsten Lösungen.

Ein Netzwerk-Socket ist ein Endpunkt der Prozesskommunikation über ein Computernetzwerk. Die Standardbibliothek von MQL5 enthält eine Gruppe von Socket-Funktionen, die eine Low-Level-Schnittstelle für die Arbeit im Internet bieten. Dies ist eine gemeinsame Schnittstelle verschiedenster Programmiersprachen, da sie Systemaufrufe auf Betriebssystemebene verwendet.

Der Datenaustausch zwischen den Preisen erfolgt über TCP/IP (Transmission Control Protocol/Internet Protocol). So können sich Prozesse innerhalb eines einzelnen Computers und über ein lokales Netzwerk oder das Internet gegenseitig beeinflussen.

Um eine Verbindung herzustellen, ist es notwendig, einen TCP-Server zu erstellen und zu initialisieren, mit dem sich der Client-Prozess verbinden wird. Ist das Zusammenspiel der Prozesse abgeschlossen, muss die Verbindung zwangsweise geschlossen werden. Daten in einem TCP-Austausch sind ein Stream von Bytes.

Wenn wir einen Server erstellen, müssen wir einen Socket einem oder mehreren Hosts (IP-Adressen) und einem ungenutzten Port zuordnen. Wenn die Liste der Hosts nicht gesetzt ist oder als "0.0.0.0" angegeben wird, hört der Socket auf alle Hosts. Wenn Sie "127.0.0.0.1" oder "localhost" angeben, ist die Verbindung nur innerhalb der "internen Schleife", d.h. nur innerhalb eines Computers möglich.

Da in MQL5 nur der Client verfügbar ist, werden wir in Python einen Server erstellen.


Erstellen eines Socket-Servers in Python

Der Zweck des Artikels ist es nicht, die Grundlagen der Python-Programmierung zu vermitteln. Es wird daher davon ausgegangen, dass der Leser mit dieser Sprache vertraut ist. 

Wir werden die Version 3.7.2 und das integrierte Socket-Paket verwenden. Bitte lesen Sie die zugehörige Dokumentation für weitere Details.

Wir werden ein einfaches Programm schreiben, das einen Socket-Server erstellt und die benötigten Informationen vom Client (das MQL5-Programm) übernimmt, sie bearbeitet und das Ergebnis zurückschickt. Dies scheint die effizienteste Interaktionsmethode zu sein. Angenommen, wir müssten eine maschinelle Lernbibliothek verwenden, wie z.B. scikit learn, die die lineare Regression von Preisen berechnet und Koordinaten zurückschickt, mit denen eine Linie im MetaTrader 5 Terminal gezeichnet werden soll. Dies ist ein einfaches Beispiel. Diese Interaktion kann aber auch zum Trainieren eines neuronalen Netzwerks, zum Senden von Daten (Kurse) vom Terminal, zum Lernen und Zurückgeben des Ergebnisses an das Terminal verwendet werden.

Lassen Sie uns das Programm socketserver.py erstellen und die oben beschriebenen Bibliotheken importieren:

import socket, numpy as np
from sklearn.linear_model import LinearRegression

Nun können wir mit dem Erstellen einer Klasse fortfahren, die für den Socket verantwortlich ist:

class socketserver:
    def __init__(self, address = '', port = 9090):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.address = address
        self.port = port
        self.sock.bind((self.address, self.port))
        self.cummdata = ''
        
    def recvmsg(self):
        self.sock.listen(1)
        self.conn, self.addr = self.sock.accept()
        print('connected to', self.addr)
        self.cummdata = ''

        while True:
            data = self.conn.recv(10000)
            self.cummdata+=data.decode("utf-8")
            if not data:
                break    
            self.conn.send(bytes(calcregr(self.cummdata), "utf-8"))
            return self.cummdata
            
    def __del__(self):
        self.sock.close()

Beim Erstellen eines Klassenobjekts erhält der Konstruktor den Hostnamen (IP-Adresse) und die Portnummer. Dann wird das Objekt sock erstellt, das der Adresse und dem Port sock.bind() zugeordnet ist.

Die Methode recvmsg wartet auf die eingehende Verbindung: sock.listen(1). Wenn eine eingehende Client-Verbindung ankommt, akzeptiert der Server diese: self.sock.accept().

Dann wartet der Server in einer Endlosschleife auf eine eingehende Client-Nachricht, die als Byte-Stream ankommt. Da die Nachrichtenlänge nicht im Voraus bekannt ist, erhält der Server diese Nachricht in Teilen, z.B. immer wieder 1 Kbyte, bis die gesamte Nachricht angekommen ist: self.conn.recv(10000). Empfangene Daten werden in eine Zeichenkette data.decode("utf-8") umgewandelt und zum Rest der Zeichenkette summdata hinzugefügt.

Nachdem alle Daten empfangen wurden (if not data:), sendet der Server an den Client eine Zeichenkette, die die äußersten rechten und linken Koordinaten der berechneten Regressionslinie enthält. Die Zeichenkette wird vorübergehend in ein Byte-Array conn.send(bytes(calcregr(self.cummdata), "utf-8")) umgewandelt.

Am Ende gibt die Methode die vom Client empfangene Zeichenkette zurück. Sie kann unter anderem zur Visualisierung von erhaltenen Kursen verwendet werden.

Ein Destruktor schließt den Socket, sobald die Ausführung des Python-Programms abgeschlossen ist.

Bitte beachten Sie, dass dies nicht die einzige mögliche Realisierung der Klasse ist. Alternativ können Sie die Methoden zum Empfangen und Senden von Nachrichten trennen und zu verschiedenen Zeitpunkten unterschiedlich verwenden. Ich habe nur die grundlegende Technologie zum Erstellen einer Verbindung beschrieben. Sie können Ihre eigenen Lösungen implementieren.

Lassen Sie uns die lernende Methode der linearen Regression innerhalb der aktuellen Implementierung genauer betrachten:

def calcregr(msg = ''):
    chartdata = np.fromstring(msg, dtype=float, sep= ' ') 
    Y = np.array(chartdata).reshape(-1,1)
    X = np.array(np.arange(len(chartdata))).reshape(-1,1)
        
    lr = LinearRegression()
    lr.fit(X, Y)
    Y_pred = lr.predict(X)
    type(Y_pred)
    P = Y_pred.astype(str).item(-1) + ' ' + Y_pred.astype(str).item(0)
    print(P)
    return str(P)

Der empfangene Bytestrom wird in einen utf-8-Zeichenkette umgewandelt, die dann von der Methode calcregr(msg = ' '') akzeptiert wird. Da die Zeichenkette eine Folge von Preisen enthält, die durch Leerzeichen getrennt sind (wie im Client implementiert), wird sie in ein NumPy-Array vom Typ float umgewandelt. Danach wird das Preisarray in eine Spalte umgewandelt (das Datenempfangsformat ist sclearn) Y = np.array(chartdata).reshape(-1,1). Der Prädiktor für das Modell ist die lineare Zeit (eine Folge von Werten; ihre Größe entspricht der Länge der Trainingsprobe) X = np.array(np.arange(len(chartdata)))).reshape(-1,1)

Es folgt das Training und die Modellvorhersage, während der erste und letzte Wert der Zeile (die Kanten des Segments) in die Variable "P" geschrieben, in eine Zeichenkette umgewandelt und in Form von Bytes an den Client übergeben werden.

Jetzt müssen wir nur noch das Klassenobjekt erstellen und die Methode recvmsg() in einer Schleife aufrufen:

serv = socketserver('127.0.0.1', 9090)

while True:  
    msg = serv.recvmsg()


Erstellen eines Socket-Clients in MQL5

Lassen Sie uns einen einfachen Expert Advisor erstellen, der sich mit dem Server verbinden kann, die angegebene Anzahl der letzten Schlusskurse übergibt, die Koordinaten der Regressionslinie zurückholt und sie auf das Chart zeichnet. 

Die Funktion socksend() übergibt Daten an den Server:

bool socksend(int sock,string request) 
  {
   char req[];
   int  len=StringToCharArray(request,req)-1;
   if(len<0) return(false);
   return(SocketSend(sock,req,len)==len); 
  }

Sie erhält die Zeichenkette, konvertiert sie in ein Byte-Array und sendet sie an einen Server.

Die Funktion socketreceive() überwacht den Port. Sobald eine Serverantwort empfangen wurde, gibt die Funktion sie als Zeichenkette zurück:

string socketreceive(int sock,int timeout)
  {
   char rsp[];
   string result="";
   uint len;
   uint timeout_check=GetTickCount()+timeout;
   do
     {
      len=SocketIsReadable(sock);
      if(len)
        {
         int rsp_len;
         rsp_len=SocketRead(sock,rsp,len,timeout);
         if(rsp_len>0) 
           {
            result+=CharArrayToString(rsp,0,rsp_len); 
           }
        }
     }
   while((GetTickCount()<timeout_check) && !IsStopped());
   return result;
  }

Die letzte Funktion drawlr() erhält eine Zeichenkette, in die die Koordinaten der linken und rechten Linie geschrieben wurden, wandelt die Zeichenkette dann in ein Zeichenkettenarray um und zeichnet die lineare Regressionslinie auf ein Chart:

void drawlr(string points) 
  {
   string res[];
   StringSplit(points,' ',res);

   if(ArraySize(res)==2) 
     {
      Print(StringToDouble(res[0]));
      Print(StringToDouble(res[1]));
      datetime temp[];
      CopyTime(Symbol(),Period(),TimeCurrent(),lrlenght,temp);
      ObjectCreate(0,"regrline",OBJ_TREND,0,TimeCurrent(),NormalizeDouble(StringToDouble(res[0]),_Digits),temp[0],NormalizeDouble(StringToDouble(res[1]),_Digits)); 
     }
  

Die Funktion wird in der Funktion OnTick() aufgerufen.

void OnTick() {
 socket=SocketCreate();
 if(socket!=INVALID_HANDLE) {
  if(SocketConnect(socket,"localhost",9090,1000)) {
   Print("Connected to "," localhost",":",9090);
         
   double clpr[];
   int copyed = CopyClose(_Symbol,PERIOD_CURRENT,0,lrlenght,clpr);
         
   string tosend;
   for(int i=0;i<ArraySize(clpr);i++) tosend+=(string)clpr[i]+" ";       
   string received = socksend(socket, tosend) ? socketreceive(socket, 10) : ""; 
   drawlr(recieved); }
   
  else Print("Connection ","localhost",":",9090," error ",GetLastError());
  SocketClose(socket); }
 else Print("Socket creation error ",GetLastError()); }

Testen der MQL5-Python Client-Server Anwendung

Um die Anwendung auszuführen, müssen Sie den Python-Interpreter installiert haben. Sie können sie von der offiziellen Website herunterladen.

Führen Sie dann die Serveranwendung socketserver.py aus. Sie erstellt einen Socket und wartet auf neue Verbindungen aus dem MQL5-Programm socketclientEA.mq5.

Nach einer erfolgreichen Verbindung werden der Verbindungsvorgang und die Preise der Regressionslinie im Programmfenster angezeigt. Die Preise werden an den Client zurückgeschickt:



Die Verbindungsaktivität und die Preise der Regressionslinie werden auch im MetaTrader 5 Terminal angezeigt. Die Regressionslinie wird auch auf dem Chart dargestellt und bei jedem neuen Tick erneut aktualisiert:

Wir haben die Implementierung der direkten Interaktion von zwei Programmen über eine Socket-Verbindung besprochen. Gleichzeitig hat MetaQuotes ein Python-Paket entwickelt, mit dem Daten direkt vom Terminal empfangen werden können. Für weitere Details lesen Sie bitte die Forumsdiskussion im Zusammenhang mit der Verwendung von Python in MetaTrader (auf Russisch, verwenden Sie daher die automatische Übersetzungsoption).

Lassen Sie uns ein Skript erstellen, das zeigt, wie man Kurse vom Terminal erhält.

Erhalten und Analysieren von Kursen mit dem MetaTrader 5 Python API

Zuerst müssen Sie das MetaTrader5 Python-Modul installieren (die Zusammenfassung der Pythondiskussionen ist hier verfügbar). 

pip install MetaTrader5

Importieren Sie es in das Programm und initialisieren Sie die Verbindung zum Terminal:

from MetaTrader5 import *
from datetime import date
import pandas as pd 
import matplotlib.pyplot as plt 

# Initialisieren der MT5-Verbindung 
MT5Initialize()
MT5WaitForTerminal()

print(MT5TerminalInfo())
print(MT5Version())

Danach erstellen Sie die Liste der gewünschten Symbole und fordern nacheinander die Schlusskurse für jedes Währungspaar vom Terminal zum Pandas-Datenrahmen an:

# Erstellen einer Beobachtungsliste von Währungen für die die Korrelationsmatrix gezeichnet werden soll
sym = ['EURUSD','GBPUSD','USDJPY','USDCHF','AUDUSD','GBPJPY']

# Kopieren des Datenrahmens
d = pd.DataFrame()
for i in sym:
     rates = MT5CopyRatesFromPos(i, MT5_TIMEFRAME_M1, 0, 1000)
     d[i] = [y.close for y in rates]

Jetzt können wir die Verbindung zum Terminal trennen und dann die Preise der Währungspaare als prozentuale Veränderungen darstellen, indem wir die Korrelationsmatrix berechnen und auf dem Bildschirm anzeigen:

# Deinitialisieren der MT5-Verbindung
MT5Shutdown()

# Berechnen der prozentualen Veränderung
rets = d.pct_change()

# Berechnen der Korrelation
corr = rets.corr()

# Zeichnen der Korrelationsmatrix
plt.figure(figsize=(10, 10))
plt.imshow(corr, cmap='RdYlGn', interpolation='none', aspect='auto')
plt.colorbar()
plt.xticks(range(len(corr)), corr.columns, rotation='vertical')
plt.yticks(range(len(corr)), corr.columns);
plt.suptitle('FOREX Correlations Heat Map', fontsize=15, fontweight='bold')
plt.show()

Wir sehen eine gute Korrelation zwischen GBPUSD und GBPJPY in der obigen Heatmap. Jetzt können wir die Co-Integration testen, indem wir die Bibliothek statmodels importieren:

# Importieren von statmodels für den Test der Kointegration
import statsmodels
from statsmodels.tsa.stattools import coint

x = d['GBPUSD']
y = d['GBPJPY']
x = (x-min(x))/(max(x)-min(x))
y = (y-min(y))/(max(y)-min(y))

score = coint(x, y)
print('t-statistic: ', score[0], ' p-value: ', score[1])

Die Beziehung zwischen zwei Währungspaaren kann als Z-Score angezeigt werden:

# Zeichnen der Transformation Z-Score
diff_series = (x - y)
zscore = (diff_series - diff_series.mean()) / diff_series.std()

plt.plot(zscore)
plt.axhline(2.0, color='red', linestyle='--')
plt.axhline(-2.0, color='green', linestyle='--')

plt.show()



Visualisierung der Marktdaten mittels der Bibliothek Plotly

Es ist oft notwendig, Kurse in einer ansprechenden Form zu visualisieren. Dies kann mit der Bibliothek Plotly realisiert werden, die auch das Speichern von Diagrammen im interaktiven .html-Format ermöglicht.

Lassen Sie uns EURUSD-Kurse herunterladen und in einem Kerzenchart anzeigen:

# -*- kodieren: utf-8 -*-
"""
Created on Thu Mar 14 16:13:03 2019

@author: dmitrievsky
"""
from MetaTrader5 import *
from datetime import datetime
import pandas as pd
# Initialisieren der MT5-Verbindung 
MT5Initialize()
MT5WaitForTerminal()

print(MT5TerminalInfo())
print(MT5Version())

# Kopieren der Daten nach Panda Datenrahmen
stockdata = pd.DataFrame()
rates = MT5CopyRatesFromPos("EURUSD", MT5_TIMEFRAME_M1, 0, 5000)
# Deinitialisieren der MT5-Verbindung
MT5Shutdown()

stockdata['Open'] = [y.open for y in rates]
stockdata['Close'] = [y.close for y in rates]
stockdata['High'] = [y.high for y in rates]
stockdata['Low'] = [y.low for y in rates]
stockdata['Date'] = [y.time for y in rates]

import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

trace = go.Ohlc(x=stockdata['Date'],
                open=stockdata['Open'],
                high=stockdata['High'],
                low=stockdata['Low'],
                close=stockdata['Close'])

data = [trace]
plot(data)

Es ist auch möglich, einen beliebigen Umfang historischer Bid- und Ask-Kurse herunterzuladen und anzuzeigen:

# -*- kodieren: utf-8 -*-
"""
Created on Thu Mar 14 16:13:03 2019

@author: dmitrievsky
"""
from MetaTrader5 import *
from datetime import datetime

# Initialisieren der MT5-Verbindung 
MT5Initialize()
MT5WaitForTerminal()

print(MT5TerminalInfo())
print(MT5Version())

# Kopieren der Daten in die Liste
rates = MT5CopyTicksFrom("EURUSD", datetime(2019,3,14,13), 1000, MT5_COPY_TICKS_ALL)
bid = [x.bid for x in rates]
ask = [x.ask for x in rates]
time = [x.time for x in rates]

# Deinitialisieren der MT5-Verbindung
MT5Shutdown()

import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
data = [go.Scatter(x=time, y=bid), go.Scatter(x=time, y=ask)]

plot(data)


Schlussfolgerung

In diesem Artikel haben wir Möglichkeiten zur Implementierung der Kommunikation zwischen dem Terminal und einem in Python geschriebenen Programm über Sockets und direkt über die Fachbibliothek von MetaQuotes diskutiert. Leider ist die aktuelle Implementierung des Socket-Clients in MetaTrader 5 nicht für den Betrieb im Strategy-Tester geeignet, so dass kein vollständiges Testen und Messen der Leistung dieser Lösung durchgeführt wurde. Lassen Sie uns auf weitere Updates der Socket-Funktionen warten.

Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/5691

Beigefügte Dateien |
Letzte Kommentare | Zur Diskussion im Händlerforum (106)
Too Chee Ng
Too Chee Ng | 18 Dez. 2024 in 11:39

Vielen Dank für diesen Artikel.

Ich frage mich nur, warum wir in OnTick() ständig socket=SocketCreate() und SocketClose() aufrufen müssen?

Es scheint etwas ineffizient zu sein, dies wiederholt zu tun.
Hält es den Socket nicht offen/aktiv? Oder ist es vielmehr möglich, den Socket offen/aktiv zu halten?

Alex Renko
Alex Renko | 14 Feb. 2025 in 10:21
Ernesto Che Daten, um Fibs und Channels zu zeichnen. In Ihrem Beispiel gibt Python zwei Werte zurück, aber ich muss Daten für bis zu 12 verschiedene Strukturen mit jeweils drei Koordinatenpunkten zurückgeben.
Zunächst blieb ich mit der Tatsache hängen, dass mt5 nicht einen langen String zurückgibt, der alle Strukturen auf einmal beschreibt. Ich habe den Austausch durch mehrere kürzere Abfragen vorgenommen. Alles scheint zu funktionieren, aber von Zeit zu Zeit.
Irgendetwas sagt mir, dass es an der Timeout-Einstellung liegt. Könnten Sie mir bitte eine Richtung vorschlagen, um eine Lösung zu finden?
Vielen Dank im Voraus

Hallo! Ich habe auch ein Socket angehoben. Ich habe ein Problem - ich schreibe einen Indikator in Python. Es nimmt Daten von mt5 eine Menge und so viel wie Sie wollen, aber um Daten zu mt5 zurückgeben ist nicht so einfach. Auf dem Socket ist es möglich, nur einen String bis zu 100 kleine Strings zu übertragen, aber ich brauche mehr. Welche Lösungen gibt es außer Socket? Und außer Web/Internet-Anfragen des Datenaustauschs zwischen Python->MT5? Ich möchte keine MySQL-DB dafür aufziehen. Wir sprechen über die Übertragung von Python zu MT5 etwa 40 Währungspaare mit einer Geschichte von 1000 neu berechnete Messwerte und weitere Konstruktion von Indikator-Linien in MT5... Ich möchte weg von Berechnungen in MT5 zu bekommen, wie Python tut es viel schneller. Ich möchte also alle Zeilen des Indikators sehen und nicht nur den letzten Balken, der durch einen String einmal pro Sekunde übertragen wird.
Kann mir jemand einen nützlichen Tipp geben?

TCP/IP Socket - MT5 erhält sowieso nur einen String und der passt nicht auf 30 000 Daten.... Die Begrenzung einer String-Variablen selbst im Jason-Format liegt bei bis zu 100 Strings. Was ist der Nutzen eines solchen Sockets?
Es stellt sich heraus, dass für große Daten ein Ausweg Python-->MySQL-->MT5

Ich hatte auch diese Idee:

Mit multiprocessing.shared_memory in Python und WinAPI in MQL5 kann man Daten direkt aus dem Speicher lesen.
Maxim Kuznetsov
Maxim Kuznetsov | 14 Feb. 2025 in 10:52
Alex Renko #:
außer für Web-/Internet-Anforderer des Datenaustauschs zwischen Python->MT5? Ich möchte keine MySQL-DB einführen.

"SQLite heranziehen" - MT5 hat es eingebaut, Python hat es offensichtlich auch....

Sie können den Socket verwenden, um das, was Sie brauchen, sofort zu melden (Signale, Warnungen usw.), und große Daten in SQLite eingeben. Das heißt, in Python geben Sie alles, was Sie brauchen, in die Datenbank ein und pfeifen auf den Socket "Datenaktualisierung". Und in MQL kann man die Datenbank auf die Trillerpfeife hin wieder auslesen.

Die Datenbank selbst kann auf einer Frame-Disk gespeichert werden

Alex Renko
Alex Renko | 18 Feb. 2025 in 03:19
Maxim Kuznetsov #:

"bring up SQLite" - MT5 hat es eingebaut, python hat es offensichtlich auch.

Sie verwenden den Socket, um das, was Sie brauchen, sofort zu melden (Signale, Warnungen usw.), und stellen große Daten in SQLite. Das heißt, in Python stellen Sie alles, was Sie brauchen, in die Datenbank und pfeifen auf den Socket "Datenaktualisierung". Und in MQL können Sie die Datenbank auf die Trillerpfeife hin wieder auslesen.

Die Datenbank selbst kann auf einer Frame-Disk gespeichert werden

Ich verstehe, was Sie meinen, danke für die Antwort... Ich dachte so
MetaTrader 5 verwendet seine eigene Programmiersprache MQL5, die in einem isolierten Prozess läuft. Dies erlaubt keine direkte Interaktion mit dem gemeinsamen Speicher des Betriebssystems, wie es andere Anwendungen, die Low-Level-APIs verwenden, tun können.

Shell innerhalb einer Shell.... Es ist schon 20 Jahre her, dass sie keine native Version für den Mac machen konnten...

Maxim Kuznetsov
Maxim Kuznetsov | 18 Feb. 2025 in 04:50
Alex Renko #:

Ich verstehe Ihren Standpunkt, danke für die Antwort.... Das dachte ich mir auch
MetaTrader 5 verwendet seine eigene Programmiersprache MQL5, die in einem isolierten Prozess läuft. Dies erlaubt keine direkte Interaktion mit dem gemeinsamen Speicher des Betriebssystems, wie es andere Anwendungen mit Low-Level-APIs tun können.

Shell innerhalb einer Shell.... Es ist schon 20 Jahre her, dass sie keine native Version für den Mac machen konnten...

niemand verbietet die Verwendung von DLL - und dort kann man tun, was man will.

Man kann den Speicher direkt durchsuchen (wahrscheinlich nicht schneller :-) ).

Oder effiziente Zwischenlösungen, a la In-Memory Key-Value-DB.

Nur in den meisten Fällen sind die Bremsen und der Flaschenhals auf der Seite von Python

Optimale Farben für Handelsstrategien Optimale Farben für Handelsstrategien
In diesem Artikel werden wir ein Experiment durchführen: Wir werden die Optimierungsergebnisse einfärben. Die Farbe wird durch drei Parameter bestimmt: die Werte für Rot, Grün und Blau (RGB). Es gibt noch andere Methoden der Farbcodierung, die ebenfalls drei Parameter verwenden. So können drei Prüfparameter in eine Farbe umgewandelt werden, die die Werte visuell darstellt. Lesen Sie diesen Artikel, um herauszufinden, ob eine solche Darstellung nützlich sein kann.
Extrahieren von strukturierten Daten aus HTML-Seiten mit Hilfe von CSS-Selektoren Extrahieren von strukturierten Daten aus HTML-Seiten mit Hilfe von CSS-Selektoren
Der Artikel beschreibt eine universelle Methode zur Analyse und Konvertierung von Daten aus HTML-Dokumenten auf Basis von CSS-Selektoren. Handelsberichte, Testerberichte, Ihren bevorzugten Wirtschaftskalender, öffentliche Signale, Kontoüberwachung und zusätzliche Online-Kursquellen werden direkt mit MQL verfügbar gemacht.
Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil III). Erhebung (Collection) von Marktorders und Positionen Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil III). Erhebung (Collection) von Marktorders und Positionen
Im ersten Teil begannen wir mit der Erstellung einer großen plattformübergreifenden Bibliothek, die die Entwicklung von Programmen für MetaTrader 5 und MetaTrader 4 Plattformen vereinfacht. Danach haben wir die Collection (Sammlung bzw. Liste) von historischen Aufträgen und Deals implementiert. Unser nächster Schritt ist das Erstellen einer Klasse für eine komfortable Auswahl und Sortierung von Aufträgen, Deals und Positionen in Collections. Wir werden das Basis-Bibliotheksobjekt Engine implementieren und der Bibliothek die Collection von Marktorders und Positionen hinzufügen.
Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil II). Erhebung (Collection) historischer Aufträge und Deals Bibliothek für ein leichtes und schnelles Entwickeln vom Programmen für den MetaTrader (Teil II). Erhebung (Collection) historischer Aufträge und Deals
Im ersten Teil begannen wir mit dem Erstellen einer großen plattformübergreifenden Bibliothek, die die Entwicklung von Programmen für MetaTrader 5 und MetaTrader 4 Plattformen vereinfacht. Wir haben das abstrakte Objekt COrder angelegt, das als Basisobjekt für die Speicherung von Daten zu historischen Aufträgen und Deals sowie zu Marktorders und Positionen dient. Jetzt werden wir alle notwendigen Objekte entwickeln, um die Daten der Kontenhistorie in "Collections" (Sammlungen bzw. Listen) zu speichern.