Diskussion zum Artikel "Der Prototyp eines automatischen Handelssystems" - Seite 2

 

Ich empfehle, dieses Design zu vermeiden

//------------------------------------------------------------------ CheckNewBar
bool CExpertAdvisor::CheckNewBar()          // Funktion zur Überprüfung, ob ein neuer Balken erscheint
  {
   MqlRates rt[2];
   if(CopyRates(m_smb,m_tf,0,2,rt)!=2)      // Kopieren der Balken
     { Print("CopyRates of ",m_smb," failed, no history"); return(false); }
   if(rt[1].tick_volume>1) return(false);   // Überprüfung der Lautstärke 
   return(true);
  }

da die Verarbeitung des vorherigen Ticks so viel Zeit in Anspruch nehmen kann, dass das Eintreffen des ersten Ticks des neuen Balkens verpasst wird.

Entsprechend ist es möglich, die Eröffnung zu verpassen.

Es ist besser, sich an den Zeitpunkt der Balkeneröffnung zu binden, aber dazu müssen Sie z.B. den vorherigen Zeitpunkt des Nullbalkens speichern, um ihn mit dem aktuellen Zeitpunkt des Nullbalkens zu vergleichen.

Wenn sie gleich ist, gibt es keinen neuen Balken.

Wenn sie unterschiedlich sind, wird zumindest ein neuer (nächster) Balken geöffnet, nach dem wir die gespeicherte Zeit des Nullbalkens mit der aktuellen Zeit des Nullbalkens initialisieren.

Diese Konstruktion ist zuverlässiger.

Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
Документация по MQL5: Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций
  • www.mql5.com
Стандартные константы, перечисления и структуры / Торговые константы / Свойства позиций - Документация по MQL5
 

Behandeln Sie dies in einem zukünftigen Artikel:

  • *robuste* (d. h. serverseitige) Stop-Loss- und Take-Profit-Aufträge auf verschiedenen Ebenen pro Handel; diese sind *erforderlich*, um Probleme im Zusammenhang mit Netzwerk- und Client-Programmausfällen zu vermeiden (längere Netzwerkunterbrechungen, durch Netzwerkverzögerungen verursachte Slippage (und Requotes), Beendigung des Client-Programms oder Betriebssystems, Neustarts, Abstürze (längere Abwesenheit der Client-Software) usw.); Sogenannte "virtuelle" Aufträge reichen nicht aus, ebenso wenig wie Nicht-OCO-Ersatzprodukte (nein, das ist *nicht* verhandelbar, wenn Robustheit eine Anforderung ist, müssen Stop-Loss- und Take-Profit-Aufträge serverseitig sein, und wenn einer getroffen wird, muss der andere gleichzeitig *vom Server* entfernt werden)
  • *robuste* Wiederherstellung des Status pro Handel im Falle eines Absturzes; mit anderen Worten, wenn der Client/das Betriebssystem abstürzt (und automatisch neu gestartet wird), möchte ich, dass der EA genau weiß, was in der Zwischenzeit mit den ausstehenden Einzelhandelsgeschäften und Aufträgen passiert ist: gefüllt, geschlossen, noch aktiv, welche zugehörigen s/l- und t/p-Aufträge zu welchem Trade/Auftrag gehören usw. (nein, Status auf die Festplatte zu schreiben *nicht* reicht nicht aus, weil es eine Race Condition zwischen dem Öffnen eines Trades und dem Schreiben des Status auf die Festplatte gibt und das Client-Programm genau zum falschen Zeitpunkt abstürzen kann; serverseitige Auftragskommentare könnten es tun, *wenn* sie veränderbar wären)

Soweit ich weiß, unterstützt MT5 nur *1* (eine) serverseitige s/l- und t/p-Order *pro Instrument* (nicht pro Handel) und keine OCO-Orders (OCO-Orders können verwendet werden, um s/l- und t/p-Orders pro Handel zu simulieren, aber auch hier gibt es eine Race Condition). Solange die oben genannten Probleme nicht gelöst sind, würde ich nicht mehr als 100 $ für den Handel über MT5 einsetzen (vereinfachte Single-Order Single-Timeframe Single-Direction MA Cross EAs). Und ich bin nicht einmal sicher über die $100.

 
olyakish:

Ich empfehle, dieses Design zu vermeiden

da die Verarbeitung des vorherigen Ticks so viel Zeit in Anspruch nehmen kann, dass das Eintreffen des ersten Ticks des neuen Balkens verpasst wird.

Entsprechend ist es möglich, die Eröffnung zu verpassen.

Es ist besser, sich an den Zeitpunkt der Balkeneröffnung zu binden, aber dazu müssen Sie z.B. den vorherigen Zeitpunkt des Nullbalkens speichern, um ihn mit dem aktuellen Zeitpunkt des Nullbalkens zu vergleichen.

Wenn sie gleich ist, gibt es keinen neuen Balken.

Wenn sie unterschiedlich ist, wird zumindest ein neuer (nächster) Balken geöffnet, nach dem wir die gespeicherte Zeit des Nullbalkens mit der aktuellen Zeit des Nullbalkens initialisieren.

Diese Konstruktion ist zuverlässiger.

Ich habe es auf diese Weise gemacht:

bool CUniexp::checkNewBar(void)
{
   static datetime prevTime[1];
   datetime currentTime[0];
   CopyTime(_Symbol,_Period,0,1,currentTime);
   if (currentTime[0]==prevTime[0])
   {return (false);}
   else
   {
      prevTime[0] = currentTime[0];
      return (true);
   }
}
 
isNewBar
isNewBar
  • Stimmen: 7
  • 2010.05.07
  • Prival
  • www.mql5.com
Функция анализа появления нового бара на заданном таймфрейме.
 

Kompiliert, aber Debugger schlägt fehl.

Laden von C:\Programmdateien\MetaTrader 5\MQL5\Experts\Examples\eMyEA.ex5 fehlgeschlagen

 
Rosh:

Neuer Artikel Der Prototyp des Handelsroboters ist veröffentlicht:

Autor: Алексей Сергеев


Vielen Dank für den tollen Artikel! Ich bin ein Neuling, aber ich habe eine Frage über den Code.


In der Funktion void CExpertAdvisor::TrailingPosition(long dir,int TS), gibt es eine Zeile:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // Stop Loss berechnen


Sollten wir apr sowohl für das zweite als auch für das dritte Argument beim Aufruf von NormalSL verwenden? Ich dachte, es sollte sein:

sl=NormalSL(dir,op,apr,TS,StopLvl);

da das zweite Argument der Geld-/Briefkurs für die "angegebene" Richtung (d.h. die Variable op) und nicht für die "umgekehrte" Richtung (d.h. die Variable apr) sein sollte.


Vielen Dank!

 
echostate:


In der Funktion void CExpertAdvisor::TrailingPosition(long dir,int TS), gibt es eine Zeile:

sl=NormalSL(dir,apr,apr,TS,StopLvl); // Stop Loss berechnen


Sollten wir apr sowohl für das zweite als auch für das dritte Argument beim Aufruf von NormalSL verwenden? Ich dachte, es sollte sein:

sl=NormalSL(dir,op,apr,TS,StopLvl);

Nein.
das zweite und dritte Argument muss apr sein.

denn die Berechnung von tral wird von dem Preis abgeleitet, zu dem die Position geschlossen wird. Die Funktion Bid für Buy und Ask für Sell ist korrekt.

da das zweite Argument der Geld-/Briefkurs für die "angegebene" Richtung (d. h. die Variable op) und nicht für die "umgekehrte" Richtung (d. h. die Variable apr) sein sollte.

sollte aus der "umgekehrten" Richtung berechnet werden . In diesem Fall ist apr.
 
sergeev:

nein.
das zweite und dritte Argument müssen apr. sein.

sein, da die Berechnung von tral von dem Preis abgeleitet wird, zu dem die Position geschlossen wird. Die Funktion Bid für Buy und Ask für Sell ist korrekt.

sollte aus der "umgekehrten" Richtung berechnet werden . In diesem Fall also apr.


Danke für die schnelle Antwort! Ich dachte, ich müsste falsch liegen.


Kann ich auch in der Funktion fragen

double CExpertAdvisor::CountLotByRisk(int dist,double risk,double lot) // Berechnung des Loses nach Größe des Risikos
  {
   if(dist==0 || risk==0) return(lot);
   m_smbinf.Refresh();
   return(NormalLot(AccountInfoDouble(ACCOUNT_BALANCE)*risk/(dist*10*m_smbinf.TickValue())));
  }

warum wir eine "10" zwischen "dist" und "m_smbinf.TickValue()" im Rückgabewert haben? Ich vermute, "dist" ist der Stop-Loss (in Pips), und "m_smbinf.TickValue()" ist der US-Dollar-Wert pro Pip pro Lot für das Währungspaar. Ich bin mir also nicht sicher, warum wir eine weitere "10" dazwischen multiplizieren.

Vielen Dank!

 
Tausend Dank.
 

Sehr nützlicher Artikel. Vielen Dank!