程序库: 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 // 等待交易环境同步的最长时间(以微秒为单位 
#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 函数 造成的。


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

中的这样一个编辑将性能提高了 4.5 倍 - ~3 秒。

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


这是一个明显的例子,说明应该明智地频繁使用数组。在这种情况下,static 可以让你不必每次都在 ArrayCopy 中为数组分配内存。在实际任务中,我们可以用肉眼感受到性能提升了数倍。

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

旁通模式 下(例如,我在自定义报告 中使用)有大量 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

我认为这种行为是 MQ 的疏忽,因为request_id 应该以 1 开头。


这也是 MT4Orders 没有为 Tester 实现 OrderSendAsync 的原因之一。还有一个不太好的原因(来自书中)。

警告。在 Tester 中,OrderSendAsync 函数 的工作方式 OrderSend类似。这样就很难调试异步请求的延迟处理。
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
Учебник по MQL5: Автоматизация торговли / Создание экспертов / Отправка торгового запроса: OrderSend и OrderSendAsync
  • www.mql5.com
Для выполнения торговых операций MQL5 API предоставляет две функции: OrderSend и OrderSendAsync . Они, также как и OrderCheck , выполняют в...