Bibliotheken: MT4Orders - Seite 86

 
Danke für den Austausch.
 
Herzlichen Dank!!! Das ist super AWESOME
 
Manchmal müssen Sie ein geschlossenes Ticket verwenden, um seine Position in der Handelshistorie zu finden.
// Gibt die Ticketposition in der Tabelle der historischen Bestellungen zurück.
int OrderSelectPos( const long Ticket = -1 )
{
#ifdef  MT4ORDERS_ORDERS_SORT
  #ifdef __MQL5__
    #ifdef __VIRTUAL__
      if (!VIRTUAL::GetHandle())
    #endif // #ifdef __VIRTUAL__
    
    return(-1);  
  #endif // #ifdef __MQL5__ 
#else // #ifdef MT4ORDERS_ORDERS_SORT
  #ifdef __VIRTUAL__
    if (VIRTUAL::GetHandle())
      return(-1);  
  #endif // #ifdef __VIRTUAL__ 
#endif // #ifdef MT4ORDERS_ORDERS_SORT #else

  int Pos = -1;
  
  if (::OrderSelect(Ticket, SELECT_BY_TICKET, MODE_HISTORY) && ::OrderCloseTime())
  {
    static int PrevHistoryTotal = 0;
    static CHashMap<long, int> Tickets;
        
    const long SearchTicket = (::OrderType() <= OP_SELL) ? ::OrderTicket() : -::OrderTicket();    
    const int Total = ::OrdersHistoryTotal();
    
    while (PrevHistoryTotal < Total)
    {
      if (::OrderSelect(PrevHistoryTotal, SELECT_BY_POS, MODE_HISTORY))        
      {
        const long NewTicket = (::OrderType() <= OP_SELL) ? ::OrderTicket() : -::OrderTicket();
        
        if (NewTicket == SearchTicket)
          Pos = PrevHistoryTotal;
          
        Tickets.Add(NewTicket, PrevHistoryTotal);       
      }
      
      PrevHistoryTotal++;      
    }
    
    if ((Pos == -1) && !Tickets.TryGetValue(SearchTicket, Pos))
      Pos = -1;
  }
  
  return(Pos);
}


Prüfen.

void OnStart()
{  
  long Tickets[];
  
  // Korrektheit.
  for (uint i = ArrayResize(Tickets, OrdersHistoryTotal()); (bool)i--;)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
    {
      Tickets[i] = OrderTicket();
      
      if (OrderSelectPos(OrderTicket()) != i)
        Print(i);
    }

  const ulong StartTime = GetMicrosecondCount();

  // Leistung.
  for (uint i = ArraySize(Tickets); (bool)i--;)
    if (OrderSelectPos(Tickets[i]) == -1)
      Print(i);
      
  Print(DoubleToString((double)(GetMicrosecondCount() - StartTime) / ArraySize(Tickets), 2) + " mcs/unit.");
}


Ergebnis.

1.62 mcs/unit.
 

Bei einer großen Anzahl von MT5-Trades/Orders im ByPass-Modus (ich verwende sie z.B. im CustomReport) kann der erste Zugriff auf die Historie sehr lange dauern.

#define  MT4ORDERS_BYPASS_MAXTIME 1000000 // Maximale Wartezeit (in µs) für die Synchronisierung der Handelsumgebung 
#include <MT4Orders.mqh>

#define  PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{  
  for (int i = 0; i < 3; i++)
  {
    const ulong StartTime = GetMicrosecondCount();
    PRINT(OrdersHistoryTotal());
    PRINT(GetMicrosecondCount() - StartTime);
  }
  
  PRINT(HistoryDealsTotal());
  PRINT(HistoryOrdersTotal());
}
OrdersHistoryTotal() = 235627
GetMicrosecondCount() - StartTime = 14831029

HistoryDealsTotal() = 259381
HistoryOrdersTotal() = 619850

14 Sekunden!


Es stellte sich heraus, dass die Bremsen von der ArrayCopy Funktion kommen.


Eine solche Bearbeitung in Include\fxsaber\TradesID\ByPass.mqh

  bool IsPosDeal( const ulong Ticket )
  {
    bool Res = true;

    const ulong PositionID = ::HistoryDealGetInteger(Ticket, DEAL_POSITION_ID);

    if (PositionID)
    {
      static ulong Deals[];
// .....

  bool IsPosOrder( const ulong Ticket )
  {
    bool Res = true;

    const ulong PositionID = ::HistoryOrderGetInteger(Ticket, ORDER_POSITION_ID);

    if (PositionID)
    {
      const long TicketTime = ::HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE_MSC);

      static ulong OldOrders[];
// .....

erhöht die Leistung um das 4,5-fache - ~3 Sekunden.

OrdersHistoryTotal() = 235627
GetMicrosecondCount() - StartTime = 3307875


Ein klares Beispiel dafür, dass häufiges Arbeiten mit Arrays mit Bedacht geschehen sollte. In diesem Fall erlaubt static, dass man nicht jedes Mal Speicher für ein Array in ArrayCopy zuweisen muss. Und wir erhalten eine mehrfache Leistungssteigerung in einer realen Aufgabe, die mit dem bloßen Auge zu spüren ist.

Проверь своего брокера!
Проверь своего брокера!
  • 2021.11.12
  • www.mql5.com
На просторах интернета можно видеть довольно частые сценарии торговли. Управляющий ПАММ-счетом набрал инвесторов. Хорошо торговал, но с какого-то момента прибыльность сильно уменьшилась, вплоть до
 
fxsaber #:

Bei einer großen Anzahl von MT5-Trades/Orders im ByPass-Modus (die ich z.B. im CustomReport verwende), kann der erste Zugriff auf die Historie sehr lange dauern.

Mit der aktualisierten ByPass.mqh konnte dieser Vorgang bei Tests um das 15-fache beschleunigt werden.
 

Hallo Autor, bei der Verwendung der Funktion OrderSendAsync habe ich festgestellt, dass MT4ORDERS::LastTradeResult.retcode gleich TRADE_RETCODE_DONE ist. In Ihrem Code wird jedoch geprüft, ob MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACED. Könnte dies ein Fehler sein, oder habe ich es falsch verstanden?

#define  RETURN_ASYNC(A) return((A) && ::OrderSendAsync(MT4ORDERS::LastTradeRequest, MT4ORDERS::LastTradeResult) &&                        \
                               (MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACED) ? MT4ORDERS::LastTradeResult.request_id : 0);
 
hini #:

bei der Verwendung der Funktion OrderSendAsync habe ich festgestellt, dass MT4ORDERS::LastTradeResult.retcode gleich TRADE_RETCODE_DONE ist

Name des Servers?
 
fxsaber #:
Server-Name?
Ich habe vergessen zu erwähnen, dass ich den MT5-Tester verwende. Es sollte nichts mit dem Server zu tun haben, richtig?
 
hini #:
Ich habe vergessen zu erwähnen, dass ich den MT5-Tester verwende. Es sollte nichts mit dem Server zu tun haben, richtig?
Im Live-Handel ist MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACED tatsächlich korrekt, während es im MT5-Tester TRADE_RETCODE_DONE ist. Das war mein Fehler.
 
hini #:
Ich habe vergessen zu erwähnen, dass ich den MT5-Tester verwende. Es sollte nichts mit dem Server zu tun haben, richtig?

Im Tester ist bei der ersten erfolgreichen Ausführung von MT5-OrderSend/OrderSendAsync, MqlTradeResult.request_id == 0.

Ich halte dieses Verhalten für ein Versehen von MQ, da die request_id mit 1 beginnen sollte.


Dies ist einer der Gründe, warum MT4Orders OrderSendAsync für Tester nicht implementiert. Es gibt einen weiteren, weniger guten Grund(aus dem Buch).

Warnung. Im Tester funktioniert die FunktionOrderSendAsyncwieOrderSend. Dies erschwert die Fehlersuche bei der verzögerten Verarbeitung von asynchronen Aufträgen.
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
  • www.mql5.com
Для выполнения торговых операций MQL5 API предоставляет две функции: OrderSend и OrderSendAsync . Они, также как и OrderCheck , выполняют в...