ライブラリ: MT4Orders - ページ 86

 
シェアしてくれてありがとう。
 
本当にありがとう!最高です
 
時には、取引履歴の中のポジションを見つけるために、クローズしたチケットを使用する必要があります。
// 過去の注文の表におけるチケットの位置を返します。
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);
}


確認してください。

void OnStart()
{  
  long Tickets[];
  
  // 正しい。
  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();

  // パフォーマンス。
  for (uint i = ArraySize(Tickets); (bool)i--;)
    if (OrderSelectPos(Tickets[i]) == -1)
      Print(i);
      
  Print(DoubleToString((double)(GetMicrosecondCount() - StartTime) / ArraySize(Tickets), 2) + " mcs/unit.");
}


結果

1.62 mcs/unit.
 

ByPassモードCustomReportなどで 使用)のMT5取引/注文の数が多いと、履歴への最初のアクセスに時間がかかります。

#define  MT4ORDERS_BYPASS_MAXTIME 1000000 // 取引環境の同期を待つ最大時間(単位:µs 
#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秒!


このブレーキはArrayCopy関数に 起因していることが判明した。


Includefxsaberで このような編集をすると、パフォーマンスが4.5倍向上する

  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[];
// .....

のこのような編集は、パフォーマンスを4.5倍(~3秒)向上させる。

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


配列の頻繁な使用は賢く行うべきであるという明確な例である。この場合、staticを使えばArrayCopyで毎回配列のメモリを確保する必要がなくなる。そして、実際のタスクでは、肉眼で感じることができるほど、パフォーマンスが何倍も向上する。

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

ByPassモードCustomReportなどで 使用)のMT5取引/注文の数が多い場合、履歴への最初のアクセスに時間がかかることがあります。

更新されたByPass.mqhは、テストでこの手順を15倍高速化することができました。
 

こんにちは、作者様。OrderSendAsync関数を使用していて、MT4ORDERS::LastTradeResult.retcodeがTRADE_RETCODE_DONEに等しいことに気づきました。しかし、あなたのコードでは、MT4ORDERS::LastTradeResult.retcode ==TRADE_RETCODE_PLACED かどうかをチェックしています。これは間違いでしょうか、それとも私の誤解でしょうか?

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

OrderSendAsync関数を使用しているときに、MT4ORDERS::LastTradeResult.retcodeがTRADE_RETCODE_DONEと等しいことに気づきました。

サーバー名は?
 
fxsaber #:
サーバー名は?
言い忘れましたが、MT5のテスターを使っています。サーバーとは関係ないはずですよね?
 
hini #:
言い忘れましたが、私はMT5のテスターを使っています。サーバーとは関係ないはずですよね?
ライブ取引では、MT4ORDERS::LastTradeResult.retcode == TRADE_RETCODE_PLACEDは確かに正しいのですが、MT5テスターではTRADE_RETCODE_DONEになっています。これは私のミスでした。
 
hini #:
言い忘れましたが、私はMT5のテスターを使っています。サーバーとは関係ないはずですよね?

テスターでは、MT5-OrderSend/OrderSendAsyncの 最初の実行 成功時に、MqlTradeResult.request_id == 0と なります。

request_idは1から始まるはず なので、この動作はMQ側の見落としだと考えます。


これが、MT4OrdersがTesterにOrderSendAsyncを実装しない理由の1つです。もう一つ、あまり良くない理由があります(本から)。

警告です。Testerでは、OrderSendAsync 関数はOrderSendのように 動作します 。このため、非同期リクエストの遅延処理をデバッグすることが難しくなります。
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
  • www.mql5.com
Для выполнения торговых операций MQL5 API предоставляет две функции: OrderSend и OrderSendAsync . Они, также как и OrderCheck , выполняют в...