Diskussion zum Artikel "Die eigene, multi-threaded, asynchrone Web-Anfrage in MQL5"

 

Neuer Artikel Die eigene, multi-threaded, asynchrone Web-Anfrage in MQL5 :

Der Artikel beschreibt die Bibliothek, mit der Sie die Effizienz von HTTP-Anfragen mit WebRequest in MQL5 erhöhen können. Die Ausführung von WebRequest im nicht-blockierenden Modus verwendet in zusätzliche Threads, die Hilfscharts und Expert Advisors verwendet, um nutzerdefinierte Ereignisse austauschen und gemeinsame Ressourcen lesen. Die Quellcodes sind ebenfalls besprochen und beigefügt.

Die Umsetzung von Handelsalgorithmen erfordert oft die Analyse von Daten aus verschiedenen externen Quellen, einschließlich des Internets. MQL5 stellt die Funktion WebRequest zum Senden von HTTP-Anfragen an die "Außenwelt" zur Verfügung, die hat aber leider einen spürbaren Nachteil. Die Funktion ist synchron, d.h. sie blockiert den EA-Vorgang für die gesamte Dauer einer Auftragsausführung. MetaTrader 5 weist jedem EA einen einzelnen Thread zu, der sequentiell die vorhandenen API-Funktionsaufrufe im Code ausführt, sowie eingehende Event-Handler (wie Ticks, Tiefe der Marktveränderungen in BookEvent, Timer, Handelsoperationen, Chart-Events, etc.). Es wird jeweils nur ein Codefragment ausgeführt, während alle verbleibenden "Tasks" in Warteschlangen warten, bis sie 'drankommen' und bis das aktuelle Fragment die Kontrolle an den Kernel zurückgibt.

Wenn ein EA beispielsweise neue Ticks in Echtzeit verarbeitet und regelmäßig Wirtschaftsnachrichten auf einer oder mehreren Websites überprüft, ist es unmöglich, beide Anforderungen zu erfüllen, ohne dass sie sich gegenseitig stören. Sobald WebRequest im Code ausgeführt wird, bleibt die EA auf der Funktionsaufrufzeichenkette "eingefroren", während neue Tick-Ereignisse übersprungen werden. Selbst mit der Möglichkeit, übersprungene Ticks mit der CopyTicks-Funktion zu lesen, kann der Moment für eine Handelsentscheidung verpasst werden. So zeigt sich diese Situation, veranschaulicht durch ein UML-Ablaufdiagramm:

Ablaufdiagramm der Ereignisbehandlung mit der Blockierung bei nur einem Thread

Abb. 1. Ablaufdiagramm der Ereignisbehandlung mit der Blockierung bei nur einem Thread

Autor: Stanislav Korotky

 

Wie immer, stark! Wenn die Bibliothek verallgemeinert werden könnte, könnte man ein fertiges Toolkit erstellen, um auf einfache Weise Asynchronität für beliebige Funktionen zu erzeugen. Zugleich plattformübergreifend.

Diese Methode könnte verwendet werden, um OrderSendAsync für MT4, zum Beispiel zu erstellen.

Vielen Dank für den Artikel!

 
fxsaber:

Wie immer, stark! Wenn die Bibliothek verallgemeinert werden könnte, könnte man ein fertiges Toolkit erstellen, um auf einfache Weise Asynchronität für beliebige Funktionen zu erzeugen. Zugleich plattformübergreifend.

Mit dieser Methode könnten Sie OrderSendAsync für MT4, zum Beispiel erstellen.

Ja, ich habe vor langer Zeit einmal begonnen, ein Gruppen-Order-Management-System für MT4 mit Plugin-Befehlen für Nachrichten zu erstellen, aber es wurde nicht fertig. Ich habe nicht überprüft, wie die Ressourcen in MT4 funktionieren, obwohl es nach der Dokumentation zu urteilen wie in MT5 sein sollte.

 
Stanislav Korotky:

Ich habe nicht überprüft, wie die Ressourcen in MT4 funktionieren, obwohl es laut der Dokumentation wie in MT5 sein sollte.

Ja, alles ist wie in MT5. Nur in der aktuellen MT4-Version gibt es einen Fehler, der den Austausch unmöglich macht.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

Bugs, Bugs, Fragen

fxsaber, 2018.09.17 18:38

ResourceReadImage in MT4 mit einem solchen Fehler, dass es unmöglich ist, die Ressource zu lesen
#property strict

class RESOURCE
{
public:
  const string Name;

  RESOURCE( const string sName = __FILE__ ) : Name("::" + sName )
  {
  }

  ~RESOURCE( void)
  {
    ::ResourceFree(this.Name);
  }

  virtual bool Set( const uint &Data[], const uint Width = 1, const ENUM_COLOR_FORMAT ColorFormat = COLOR_FORMAT_XRGB_NOALPHA ) const
  {
    return(::ResourceCreate(this.Name, Data, Width, (Width == 0) ? ::ArraySize(Data) : ::ArraySize(Data) / Width, 0, 0, Width, ColorFormat));
  }

  int Get( uint &Data[] ) const
  {
    uint Width;
    uint Height;

    return(::ResourceReadImage(this.Name, Data, Width, Height) ? ::ArraySize(Data) : 0);
  }
};

void OnStart()
{
  RESOURCE Resource;
  
  uint DataIn[] = {0};  
  Resource.Set(DataIn);
   
  uint DataOut[];
  Resource.Get(DataOut);
  
  Print(DataOut[0]); // MT5x64 (Build 1881) - 0, MT4 (Build 1126) - 4278190100 (Zufallswerte)
}


ResourceSave schreibt korrekt, aber ResourceReadImage ist ein großer Fehler. Ist es möglich, es zu beheben? Ich habe es in MT5x32.... nicht überprüft.


Vielleicht hilft diese Methode, um das Lesen von Ressourcen in MT4 korrekt zu machen. Ich habe es nicht getestet.

 

Übrigens können Sie auf vollwertige Diagramme - OBJ_CHART - verzichten. Skripte werden auf sie geladen. Und WebRequest und OrderSend funktionieren dort.

Ich habe ein Beispiel dafür gegeben, wie man einen Indikator ohne zusätzliche Charts handeln kann.

So können Sie iCustom-indicator als Manager verwenden, und es wird WebRequest in seinem Skript für jede WebRequestAsync starten.

Das Design sollte einfacher und zuverlässiger sein, weil es keine zusätzlichen Fenster geben wird.

 
fxsaber:

Übrigens können Sie auf vollwertige Diagramme - OBJ_CHART - verzichten. Skripte werden auf sie geladen. Und WebRequest und OrderSend funktionieren dort.

Ich habe ein Beispiel dafür gegeben, wie man einen Indikatorhandel ohne zusätzliche Charts durchführen kann.

So können Sie iCustom-indicator als Manager verwenden, und es wird WebRequestAsync in seinem Skript für jede WebRequestAsync laufen.

Das Design sollte einfacher und zuverlässiger sein, da es keine zusätzlichen Fenster geben wird.

Können Sie einen Link zu diesem Beispiel angeben?

 
Maxim Kuznetsov:

Kann ich einen Link zu diesem Beispiel haben?

Hier und hier.


ZY Der Benutzer wird wahrscheinlich überrascht sein, wenn der Marktindikator den Handel beginnt....

 
fxsaber:

Hier und hier.


ZY Wahrscheinlich wird der Benutzer überrascht sein, wenn der Markt-Indikator zu handeln beginnt...

Mensch, ich dachte, es ist nur eine Übertragung von Ereignissen.... :-)

 
Maxim Kuznetsov:

Scheiße, es ist nur ein Event.... dachte ich :-)

Es gibt keine Veranstaltung.

 
fxsaber:

Es gibt kein Ereignis.

Es ist das Skript, das die Aufträge ausführt.

und wie es die Aufträge bekommt, ist eine andere Sache.

 
Maxim Kuznetsov:

führt das Skript die Aufträge aus.

und wie es Aufträge erhält, ist eine andere Sache.

Das Skript empfängt keine Aufträge, es wird durch den Indikator in beliebiger Menge ausgelöst.