Diskussion zum Artikel "Die Umsetzung des Mehrwährungsmodus in MetaTrader 5" - Seite 5

 
Lazarev:

sagen Sie mir,

1. wenn ich nur Bid und Ask von anderen Währungen benötige, ist es dann fair, "Spione" zu verwenden?

2. es ist nur eine Idee, gibt es keine Möglichkeit in der onChartEvent-Funktion, Ereignisse von anderen Währungen zu überprüfen und nicht nur von der aktuellen Währung?

3. Ist es möglich, den Timerwert im onTimer-Event kleiner als eins zu setzen, so dass der Kurswert viel öfter heruntergeladen wird und dementsprechend um die Mindestzeit hinter dem Zeitpunkt des letzten Ticks zurückbleibt?

4. oder ist es möglich, "CHARTEVENT_CUSTOM+n" zu verwenden, um in meinem Fall die Kreuzung von Maischen in anderen Graphen zu überprüfen?

1. Verwenden.

2. Es gibt eine Option. Das Ereignis von einer anderen Währung sollte an den Chart gesendet werden, wo der EA mit OnChartEvent() gesetzt ist.

3. nein. eins ist das Minimum.

4. Kann.

 

Ich habe einen einfachen "Spion-Indikator" SendEvent.mq5 erstellt, der ein Ereignis sendet, wenn ein neues Angebot eintrifft:

#property indicator_chart_window
#property indicator_plots 0
int OnInit()
  {
   return(0);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   EventChartCustom(0,1,0,0,_Symbol);
   return(rates_total);
  }

Ich habe einen einfachen Expert Advisor erstellt, der Ereignisse von diesem Indikator empfängt und versucht, eine Handelsoperation durchzuführen (hier ein Ausschnitt, der vollständige Text befindet sich in der angehängten Datei):

void OnChartEvent(const int id, // ChartEvent-Ereignishandler
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)            // sparam enthält den Namen des Instruments
  {
      // Abfrage von Digit,Point,Ask,Bid für das Instrument, für das das Ereignis eingetreten ist
      if(!SymbolInfoInteger(sparam,SYMBOL_DIGITS,dig)) Print("SymbolInfoInteger(SYMBOL_DIGITS) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_POINT,p)) Print("SymbolInfoDouble(SYMBOL_POINT) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_BID,Bid)) Print("SymbolInfoDouble(SYMBOL_BID) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_ASK,Ask)) Print("SymbolInfoDouble(SYMBOL_ASK) ERROR!");
      d=(int)dig;
      if(1>0) // wir kaufen immer
        {
         q.action=TRADE_ACTION_DEAL; // Füllen Sie die Struktur MqlTradeRequest und versuchen Sie, eine Handelsoperation durchzuführen.
         q.symbol=sparam; // sparam enthält den Namen des Werkzeugs
         q.volume=Lot;
         q.price=NormalizeDouble(Ask,d);
         q.sl=NormalizeDouble(Ask-p*StopLoss,d);
         q.tp=NormalizeDouble(Ask+p*TakeProfit,d);
         q.deviation=0;
         q.type=ORDER_TYPE_BUY;
         q.type_filling=ORDER_FILLING_FOK;
         // Überprüfung der aktuellen Werkzeugeigenschaften
         Print("Bid=",DoubleToString(Bid,8),", Ask=",DoubleToString(Ask,8),", Digits=",d,", Points=",DoubleToString(p,8));
         // Überprüfen Sie die Struktur der Handelsanfrage, die wir senden werden
         Print("q.action=",q.action,", q.symbol=",q.symbol,", q.volume=",q.volume,", q.price=",DoubleToString(q.price,d),", q.sl=",DoubleToString(q.sl,d),", q.tp=",DoubleToString(q.tp,d),", q.deviation=",q.deviation,", q.type=",q.type,", q.type_filling=",q.type_filling);
         Print(OrderCheck(q,ch));                                  // Prüfung, ob eine Handelsoperation durchgeführt werden kann
         Print("ch.retcode=",ch.retcode,", ch.comment=",ch.comment); // Ergebnis
         Print("OrderSend:",OrderSend(q,s));                        // Versuch, eine Handelsoperation durchzuführen
         Print("s.retcode=",s.retcode,", s.comment=",s.comment);     // Ergebnis
        }
      if(0>0) // wenn die Bedingung korrigiert ist, werden wir verkaufen
        {
         // аналогично для продажи
        }
     }
  }

Der Expert Advisor empfängt Ereignisse vom Indikator, kann aber im Test (sowohl mit als auch ohne Visualisierung) keine Handelsoperation durchführen - der Fehler "Invalid Request" wird zurückgegeben, Returncode 10013. In Echtzeit funktioniert er normal. Wenn die Handelsoperation im Expert Advisor von OnTick() statt von OnChartEvent() ausgeführt wird, funktioniert es auch gut.

Ich habe das Senden der Handelsanforderung in die Expert Advisor-Vorlage eingefügt, die vom Autor des Artikels in CodeBase angeboten wird - auch die Handelsoperationen funktionieren nicht (gleicher Fehler).

Kann mir jemand sagen, was der Grund dafür ist? Ich habe in diesem Thread gelesen, dass OnChartEvent() im Tester nicht verarbeitet wird, aber in diesem Fall werden die vom Indikator gesendeten Ereignisse im Tester verarbeitet, aber es ist unmöglich, eine Handelsoperation von OnChartEvent() im Tester auszuführen.

Dateien:
ea.mq5  4 kb
SendEvent.mq5  1 kb
[Gelöscht]  
zdd:

Ich habe einen einfachen "Indikator-Spion" SendEvent.mq5 erstellt, der ein Ereignis sendet, wenn ein neues Angebot eintrifft:

Ich habe einen einfachen Expert Advisor erstellt, der Ereignisse von diesem Indikator empfängt und versucht, eine Handelsoperation durchzuführen (ich gebe einen Teil davon wieder, der vollständige Text ist in der angehängten Datei):

Der Expert Advisor empfängt Ereignisse vom Indikator, kann aber im Test (sowohl mit als auch ohne Visualisierung) keine Handelsoperation durchführen - es wird der Fehler "Invalid Request" zurückgegeben, Returncode 10013. In Echtzeit funktioniert er normal. Wenn eine Handelsoperation im Expert Advisor von OnTick() anstelle von OnChartEvent() ausgeführt wird, funktioniert sie ebenfalls problemlos.

Ich habe das Senden von Handelsanfragen in die vom Autor des Artikels in CodeBase angebotene Expert Advisor-Vorlage eingefügt - die Handelsoperationen funktionieren ebenfalls nicht (gleicher Fehler).

Kann mir jemand sagen, was der Grund dafür ist? Ich habe in diesem Thread gelesen, dass OnChartEvent() im Tester nicht verarbeitet wird, aber in diesem Fall werden die vom Indikator gesendeten Ereignisse im Tester verarbeitet, aber es ist unmöglich, eine Handelsoperation von OnChartEvent() im Tester auszuführen.

Versuchen Sie, mir meinen Fisch in den Kopf zu setzen. Natürlich ist die Logik nicht vollständig und sehr dumm, aber es scheint sehr ähnlich zu sein, was Sie brauchen.

Zumindest öffnen sich Positionen aus dem Markt sowohl im Tester als auch in der Demo.

Ich weiß nicht, warum (ich bin zu faul, um es herauszufinden), aber Ihr Beispiel gab mir 10013 in jeder Situation.

PS

Es ist besser, an Standardobjekte (wie CAccountInfo und CTrade) zu binden. Aber wenn Sie die Geduld haben, alles selbst zu schreiben, werde ich nur froh sein.

Die Implementierung des Spions selbst ist übrigens besser aus dem Artikel zu übernehmen, oder eine modifizierbare Kopie zu erstellen (ich schlage z.B. vor, dieses Jahr "(long)_Period" durch die Datumszeit des Sendens des Ereignisses oder andere nützliche Informationen zu ersetzen). Ihre Variante ist irgendwie ziemlich "roh".

Dateien:
DemoEA.mq5  20 kb
 
Interesting:

Versuchen Sie, meinen Fisch zum Laufen zu bringen. Die Logik ist unvollständig und sehr stumpfsinnig, aber sie scheint dem, was Sie brauchen, sehr ähnlich zu sein.

Danke, ich hab's. Wenn Sie die Strukturen MqlTradeRequest und MqlTradeResult auf globaler Ebene deklarieren, funktioniert es!
 
Vielen Dank für diesen Artikel!
 

Ich versuche, die Preise für die drei Paare EURUSD, EURGBP und GBPUSD zu ermitteln. Alles funktioniert gut, wenn ich im Strategietester"Alle Ticks" oder "Nur offene Preise" auswähle. Wenn ich jedoch "Every tick based on real ticks" wähle, können aus irgendeinem Grund mehrere "New Bar"-Ereignisse in einer Minute für ein Instrument auftreten.

Um dies zu wiederholen, können Sie ein Intervall auswählen, zum Beispiel vom 15.07.2016 bis zum 19.07.2016. Hier ist ein Beispielprotokoll, sehen Sie sich die 7. und 9:

2016.07.15 00:05:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333

2016.07.15 00:05:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:05:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33399

2016.07.15 00:06:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8334

2016.07.15 00:06:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:06:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33382

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33381

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33384

2016.07.15 00:08:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83329

2016.07.15 00:08:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11167

2016.07.15 00:08:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

2016.07.15 00:09:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33396

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

Was ist der Grund für dieses Verhalten, wenn Sie den Modus "Alle Ticks basierend auf echten Ticks" auswählen?
 
ooparadise:

Ich versuche, die Preise für die drei Paare EURUSD, EURGBP und GBPUSD zu ermitteln. Alles funktioniert gut, wenn ich im Strategietester"Alle Ticks" oder "Nur offene Preise" auswähle. Wenn ich aber "Every tick based on real ticks" auswähle, dann können aus irgendeinem Grund mehrere "New Bar"-Ereignisse in einer Minute für ein Instrument auftreten.

Um dies zu wiederholen, können Sie ein Intervall auswählen, zum Beispiel vom 15.07.2016 bis zum 19.07.2016. Hier ist ein Beispielprotokoll, sehen Sie sich die 7. und 9:

Was ist der Grund für dieses Verhalten, wenn Sie den Modus "Alle Ticks basierend auf echten Ticks" auswählen?

Wie fangen Sie das Ereignis "Neuer Balken" ab? In Build 1375 wurde die Genauigkeit der Tick-Ankunft auf Millisekunden verbessert:

Tester: Unterstützung für Millisekundengenauigkeit hinzugefügt. Zuvor betrug das Zeitquantum im Strategietester eine Sekunde.

  • Die Funktionen EventSetMillisecondTimer und Sleep arbeiten jetzt im Strategietester genauer.
  • Die Genauigkeit der Übermittlung von Ticks beim Testen von Expert Advisors mit mehreren Währungen wurde erhöht. Wenn früher mehrere Ticks in einer Sekunde platziert wurden (das Tickvolumen eines Minutenbalkens beträgt mehr als 60), wurde allen die gleiche Zeit zugewiesen. Beim Testen von Expert Advisors mit nur einer Währung spielt dies keine große Rolle, da die Ticks einfach nacheinander an den Expert Advisor übergeben werden. Beim Testen mehrerer Paare ist es jedoch wichtig zu wissen, welcher Paar-Tick zuerst kam. Bisher wurden die Ticks für jedes Symbol sequentiell an den Expert Advisor übermittelt: zuerst alle Ticks für ein Symbol für eine Sekunde, dann alle Ticks für ein anderes Symbol. Jetzt werden sie unter Berücksichtigung von Millisekunden übertragen.

    Beim Testen mit realen Ticks werden die Millisekunden aus den ursprünglichen Tickdaten entnommen. Bei der Erzeugung von Ticks werden die Millisekunden entsprechend dem Tick-Volumen buchstabiert. Wenn es beispielsweise 3 Ticks in einer Sekunde gibt, werden ihnen die Zeiten 000, 333 und 666 Millisekunden zugewiesen.
 

Ich fange einenneuen Balken so ab, wie es im Artikel beschrieben ist. Das heißt, der Indikator sendet das "New Bar"-Ereignis auf diese Weise (im Vergleich zu der vorherigen Zeit Minuten, Stunden, Tage, Monate):

   double price_current=price[rates_total-1];

   TimeCurrent(time);

   if(prev_calculated==0)

     {

      EventCustom(CHARTEVENT_INIT,price_current);

      prev_time=time; 

      return(rates_total);

     }

//--- new tick

   if((flag_event & CHARTEVENT_TICK)!=0) EventCustom(CHARTEVENT_TICK,price_current);       


//--- check change time

   if(time.min==prev_time.min && 

      time.hour==prev_time.hour && 

      time.day==prev_time.day &&

      time.mon==prev_time.mon) return(rates_total);


//--- new minute

   if((flag_event & CHARTEVENT_NEWBAR_M1)!=0) EventCustom(CHARTEVENT_NEWBAR_M1,price_current); 

UPDATE: Das Problem ist mit der Installation von Build 1375 verschwunden.

 

Vielen Dank für diesen umfangreichen Artikel. Ich habe bis jetzt noch nichts von EventChartCustom gehört. Ich habe andere Diagramm-Ereignisse ausprobiert, aber sie berücksichtigten nur Ereignisse, die durch menschliches Handeln verursacht wurden. Es löst viele Dinge.

Übrigens, ich arbeite mit MQL4, es war zu 98% das Gleiche.

Prost

 

Vielen Dank für diesen Artikel, er ist sehr nützlich. Gute Arbeit!