Bibliotheken: MT4Orders - Seite 12

 
Ein Beispiel dafür, wie übersichtlich und zuverlässig der Handelsteil eines Expert Advisors sein kann, wenn man die Bibliothek auf einem Nettokonto verwendet.

Handelssignale für MetaTrader 5 mit automatischer Ausführung auf Ihrem Konto

LCHI2017

MetaTrader 5
Kostenlos

Der Expert Advisor handelt mit Aktieninstrumenten.

#include <MT4Orders.mqh>     // https://www.mql5.com/de/code/16006
#include <TypeToBytes.mqh>   // https://www.mql5.com/de/code/16280
#include <Price_Compare.mqh> // https://www.mql5.com/de/code/16169

sinput double exLots = 1;

int OrderScan( const int Type0, const int Type1 = -1, const int Type2 = -1, const int Type3 = -1 )
{
  int Res = -1;

  int Types[4];
    
  Types[0] = Type0;
  Types[1] = Type1;
  Types[2] = Type2;
  Types[3] = Type3;
  
  for (int i = 0; (i < 4) && (Types[i] != -1) && (Res == -1); i++)
    for (int j = OrdersTotal() - 1; j >= 0; j--)
      if (OrderSelect(j, SELECT_BY_POS) && (OrderType() == Types[i]) && (OrderSymbol() == _Symbol))
      {
        Res = Types[i];
        
        break;
      }
      
  return(Res);    
}

bool MyOrderModify( const double Price )
{
  return((CP(Price) != OrderOpenPrice()) && OrderModify(OrderTicket(), Price, 0, 0, 0));
}

bool MyOrderSend( const int Type, const double Price )
{
  const double Lots = exLots + OrderLots();      
  
  return((OrderScan(Type) == -1) ? OrderSend(_Symbol, Type, Lots, Price, 0, 0, 0) : MyOrderModify(Price));
}

MqlTick Ticks[];

void OnTick( void )
{  
  static const MqlTick NullTick = {0};
  
  const MqlTick Level = GetLevel(Ticks);
  
  if (_R(Level) != NullTick)
  {
    const int Type = OrderScan(OP_BUY, OP_SELL, OP_BUYLIMIT, OP_SELLLIMIT);
    
    if (Type == OP_BUY)
      MyOrderSend(OP_SELLLIMIT, Level.bid);
    else if (Type == OP_SELL)
      MyOrderSend(OP_BUYLIMIT, Level.ask);
    else if (Type != -1)
      MyOrderModify((OrderScan(OP_BUYLIMIT, OP_SELLLIMIT) == OP_BUYLIMIT) ? Level.ask : Level.bid);
    else
      OrderSend(_Symbol, OP_BUYLIMIT, exLots, Level.ask, 0, 0, 0);
  }
  
  return;
}
 
Sehr hilfreich, danke!
 
Die neueste Version finden Sie immer hier.
 

Ein Skript, das eine Besonderheit der OrderSelect-Implementierung im Modus SELECT_BY_POS+MODE_TRADES zeigt

#include <MT4Orders.mqh>
#include <MQL4_To_MQL5.mqh>

void OnStart()
{
  OrderSend(_Symbol, OP_BUYLIMIT, 1, Ask - 100 * _Point, 0, 0, 0);  // BuyLimit festlegen
  OrderSend(_Symbol, OP_SELLLIMIT, 1, Bid + 100 * _Point, 0, 0, 0); // SellLimit festlegen
  OrderSend(_Symbol, OP_BUY, 1, Ask, 100, 0, 0);                    // Eröffnet eine Kaufposition
  
  bool FirstRun = true;
  
  for (int i = OrdersTotal() - 1; i >= 0; i--)
    if (OrderSelect(i, SELECT_BY_POS))
    {
      OrderPrint();
      
      if (FirstRun)
      {
        OrderSend(_Symbol, OP_SELL, 1, Bid, 100, 0, 0); // Verkaufsposition eröffnen
        
        FirstRun = false;
      }
    }    
}

MT4

#196155484 2017.05.04 15:38:07 buy 1.00 EURUSD 1.09229 0.00000 0.00000 1.09221 0.00 0.00 -8.00  0
#196155480 2017.05.04 15:38:06 sell limit 1.00 EURUSD 1.09321 0.00000 0.00000 1.09221 0.00 0.00 0.00  0
#196155479 2017.05.04 15:38:06 buy limit 1.00 EURUSD 1.09129 0.00000 0.00000 1.09229 0.00 0.00 0.00  0

MT5

#147352190 2017.05.04 15:38:06 sell limit 1.00 EURUSD 1.09322 0.00000 0.00000 1.09222 0.00 0.00 0.00 0
#147352193 2017.05.04 15:38:06 sell 1.00 EURUSD 1.09222 0.00000 0.00000 1.09231 0.00 0.00 -9.00 0
#147352191 2017.05.04 15:38:06 buy 1.00 EURUSD 1.09231 0.00000 0.00000 1.09222 0.00 0.00 -9.00 0

Obwohl das Handelsergebnis des Skripts auf beiden Plattformen identisch ist, funktioniert OrderSelect anders. Daher auch die unterschiedlichen Protokolle.

Das Skript ist speziell ausgesaugt, und ich kann diese Art, Handelslogik zu schreiben, nicht empfehlen, da sie auf jeder Plattform mit schwer erkennbaren logischen Fehlern behaftet ist. Außerdem ist ein solcher Code bei der Ausführung nicht mehr zu 100 % identisch.

Deshalb scheint es unzweckmäßig, die Bibliothek so zu korrigieren, dass solche seltenen MT4-Kurven in MT5 absolut perfekt ausgeführt werden, wie es bei normalem Code der Fall ist.

Wenn ich mich über die Krümmung und Seltenheit solcher MT4-Handelskonstruktionen irre, bitte ich um Aufklärung.

 
Irgendwie wird es sogar lustig mit der Verlangsamung.
 
Vitaly Muzichenko:
Das mit der Verlangsamung ist schon irgendwie komisch.

Forum zum Thema Handel, automatisierte Handelssysteme und Testen von Handelsstrategien

MT4-Tester VS MT5-Tester

fxsaber, 2017.05.08 01:11 pm.

Wenn es Zweifel gibt, dass die MT5-Verlangsamung durch die Verwendung einer Drittanbieter-Bibliothek verursacht wird, können diejenigen, die es wünschen, die einfache MT4-Logik dieses EA in MQL5 nach ihrem Geschmack umschreiben und die Hypothese testen.
 
fxsaber:

Ein Skript, das eine Besonderheit der OrderSelect-Implementierung im SELECT_BY_POS+MODE_TRADES-Modus zeigt

Das Skript ist besonders ausgelutscht, und ich kann diese Art, Handelslogik zu schreiben, nicht empfehlen

Bei einer anderen, nicht zu empfehlenden Art, Handelslogik zu schreiben, können Sie auf eine andere Funktion von OrderSelect stoßen, allerdings bereits im Modus SELECT_BY_TICKET+MODE_HISTORY.

#include <MT4Orders.mqh>

#define Ask (::SymbolInfoDouble(_Symbol, SYMBOL_ASK))

void OnTick()
{
  static bool FirstRun = true;
  
  if (FirstRun && OrderSelect(OrderSend(_Symbol, OP_BUY, 1, Ask, 0, 0, 0), SELECT_BY_TICKET) &&
      OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0))  
  {
    Print(OrderTicket()); // 2 - OFFENE Position war mit diesem Ticket
    
    Print(OrderSelect(OrderTicket(), SELECT_BY_TICKET, MODE_HISTORY)); // falsch, потому что тикет ЗАКРЫТОЙ позиции равен тикету закрывающей сделки.
    Print(OrderSelect(OrderTicket() + 1, SELECT_BY_TICKET, MODE_HISTORY)); // wahr, aus dem oben genannten Grund.
      
    FirstRun = false;
  }
}

Dies ist ein Expert Advisor für einen Tester. In den Kommentaren steht der Grund für dieses Verhalten. Und es ist richtig, weil

  • Das Ticket einer offenen Position (in der Regel) ist gleich dem Ticket des Eröffnungsauftrages (nicht eines Trades). (MT5-Begriffe).
  • Wenn eine Position teilweise geschlossen wird, dürfen die Tickets der geschlossenen korrespondierenden Positionen nicht gleich dem Ticket der offenen Position sein, um Mehrdeutigkeiten zu vermeiden (MT5-Bedingungen).

  • D.h. MT5 selbst ist so "krumm" gemacht, dass es schwer ist, sich ein anderes Verhalten für MT4Orders vorzustellen. Natürlich, wenn Sie SELECT_BY_POS zuerst über die Historie machen und alle Tickets aufzeichnen, dann funktioniert SELECT_BY_TICKET ohne Probleme.

    Generell gilt: Wenn die MT4-Handelslogik "schlecht" geschrieben ist, kann es zu Diskrepanzen zwischen den Ergebnissen von MT5+MT4Orders und den MT4-Ergebnissen kommen, die für das MT4-Verständnis ungewöhnlich sind. Wenn Sie sich an den "richtigen" MT4-Schreibstil halten, dann sind keine Probleme in der Bibliothek zu erkennen.

     
    fxsaber:

    Wenn Sie eine andere, nicht zu empfehlende Art der Handelslogik verwenden, können Sie auf eine andere Funktion von OrderSelect stoßen, allerdings bereits im Modus SELECT_BY_TICKET+MODE_HISTORY.

    Generell gilt: Wenn die MT4-Handelslogik "schlecht" geschrieben ist, kann es zu für MT4 ungewohnten Diskrepanzen zwischen MT5+MT4Orders und MT4-Ergebnissen kommen. Wenn Sie sich an den "richtigen" MT4-Schreibstil halten, werden Sie in der Bibliothek keine Probleme finden.


    Die Bibliothek ist großartig, vielen Dank :) Nach dem Hinzufügen der History-Synchronisation ist sie unverzichtbar. Arbeitet schnell, auch für hft-Strategien

    Ich würde sie zum Standardlieferumfang von mt5 hinzufügen

     

    aktualisieren

    // Liste ändern:
    // 14.06.2017:
    // Hinzufügen: Die Implementierung der SL/TP-Erkennung von geschlossenen Positionen (geschlossen über OrderClose) ist aktiviert.
    // Hinzufügen: MagicNumber ist jetzt vom Typ long - 8 Bytes (vorher int - 4 Bytes).
    // Hinzufügen: Wenn in OrderSend, OrderClose oder OrderModify der Farbeingabeparameter (der jüngste) gleich INT_MAX gesetzt ist, wird er generiert.
    // die entsprechende MT5-Handelsanfrage (MT4ORDERS::LastTradeRequest), die jedoch NICHT gesendet wird. Stattdessen wird sie von MT5 geprüft,
    // dessen Ergebnis in MT4ORDERS::LastTradeCheckResult verfügbar sein wird.
    // Wenn OrderModify und OrderClose erfolgreich sind, geben sie true zurück, andernfalls false.
    // OrderSend gibt bei Erfolg 0 zurück, andernfalls -1.
    //
    // Wenn der entsprechende Farbeingabeparameter auf INT_MIN gesetzt ist, dann wird NUR bei erfolgreicher MT5-Prüfung der generierten
    // Handelsanfrage (wie im Fall von INT_MAX) wird gesendet.
    // Hinzufügen: Asynchrone Analoga der MQL4-Handelsfunktionen hinzugefügt: OrderSendAsync, OrderModifyAsync, OrderCloseAsync, OrderDeleteAsync.
    // Rückgabe der entsprechenden Result.request_id bei Erfolg, sonst 0.

    Der INT_MIN-Modus ermöglicht es Ihnen, das Verstopfen der Testerprotokolle vollständig zu beseitigen - dies ist besonders kritisch während der Optimierung, da eine Fülle von Meldungen aufgrund einer fehlerhaften Handelslogik die Optimierungsleistung um ein Vielfaches verringern und folglich nicht nur die Zeit, sondern auch die Kosten (Cloud) erhöhen kann.

    Auch bei der geschlossenen Positionen zu ermitteln.

    Vielleicht wird diese Funktionalität eines Tages als Standard für MT5 eingeführt.


    Beispiel für die Verwendung asynchroner MQL4-Funktionen

    #property script_show_inputs
    
    sinput int Amount = 5; // Anzahl der Tests OrderSend(Async)
    
    #include <MT4Orders2.mqh>
    
    #define Ask SymbolInfoDouble(_Symbol, SYMBOL_ASK)
    #define  PRINT(A) Print(#A + " = " + (string)(A));
    
    void OnStart()
    {  
    // OrderSendAsync  
      const ulong StartTime1 = GetMicrosecondCount();
      
      for (int i = 0; i < Amount; i++)
        PRINT(OrderSendAsync(NULL, OP_BUY, 0.1, Ask, 100, 0, 0))
        
      PRINT(GetMicrosecondCount() - StartTime1)
    
    // BestellungSenden
      const ulong StartTime2 = GetMicrosecondCount();
      
      for (int i = 0; i < Amount; i++)
      {
        PRINT(OrderSend(NULL, OP_BUY, 0.1, Ask, 100, 0, 0))
        Print(MT4ORDERS::LastTradeResult.comment);
      }
        
      PRINT(GetMicrosecondCount() - StartTime2)
      
      PRINT(TerminalInfoInteger(TERMINAL_PING_LAST))
    }


    Ergebnis

    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 117
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 118
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 119
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 120
    OrderSendAsync(NULL,OP_BUY,0.1,Ask,100,0,0) = 121
    GetMicrosecondCount()-StartTime1 = 403
    
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 221.820 + 0.013 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 252.067 + 0.008 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 220.909 + 0.005 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 189.578 + 0.005 ms
    OrderSend(NULL,OP_BUY,0.1,Ask,100,0,0) = 153496331
    Request executed 180.182 + 0.010 ms
    GetMicrosecondCount()-StartTime2 = 1064775
    
    TerminalInfoInteger(TERMINAL_PING_LAST) = 97942