程序库: MT4Orders - 页 83

 
fxsaber #:

库(MT4Orders.mqh)不会占用这么多内存。例如,您可以运行此 EA 来亲自验证。

最有可能的是,您使用指标的方法不正确:您创建了新的指标句柄,但没有删除旧的指标句柄。

我不使用任何指标。

你说得没错,库不会消耗那么多内存,但它确实会使用内存:

HistorySelect(0,INT_MAX);

根据此页面:

https://www.mql5.com/zh/articles/211

"在大多数情况下,试图处理所有交易历史记录是错误的。当处理的交易/订单数量达到数千或数万左右时,程序的工作速度就会大大减慢。

如果有 100 多万笔交易,您的库会将所有交易存储在一个数组中。

我很感谢你制作了这个库,在 mt4 和 mt5 之间架起了一座桥梁,而且你还与大家分享了它,并不是要毁掉它。我只是觉得很遗憾,网上只有一个地方介绍了如何正确获取掉期和佣金值(鉴于经纪商实际上提供了这些值),而且写得如此模糊不清。

Orders, Positions and Deals in MetaTrader 5
Orders, Positions and Deals in MetaTrader 5
  • www.mql5.com
Creating a robust trading robot cannot be done without an understanding of the mechanisms of the MetaTrader 5 trading system. The client terminal receives the information about the positions, orders, and deals from the trading server. To handle this data properly using the MQL5, it's necessary to have a good understanding of the interaction between the MQL5-program and the client terminal.
 
pcdeni #:

虽然你说得没错,程序库不会占用这么多内存,但它确实会使用这些内存:

根据此页面:

https://www.mql5.com/zh/articles/211

"在大多数情况下,试图处理所有交易历史记录是错误的。当处理的交易/订单数量达到数千或数万左右时,程序的工作速度就会大大减慢"。

如果有 100 多万笔交易,您的库会将所有交易存储在一个数组中。

#define  MT4ORDERS_BYPASS_MAXTIME 1000000
#include <MT4Orders.mqh> //https://www.mql5.com/ru/code/16006

double GetSummaryCommissionMQL5()
{
  double Res = 0;
  
  if (HistorySelect(0, INT_MAX))
    for (uint i = HistoryDealsTotal(); (bool)i--; )
      Res += HistoryDealGetDouble(HistoryDealGetTicket(i), DEAL_COMMISSION);

  return(NormalizeDouble(Res, 2));
}

double GetSummaryCommissionMQL4()
{
  double Res = 0;
  
  for (uint i = OrdersHistoryTotal(); (bool)i--; )
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
      Res += OrderCommission();

  return(NormalizeDouble(Res, 2));
}

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

void OnStart()
{
  PRINT(MQLInfoInteger(MQL_MEMORY_USED));
  PRINT(TerminalInfoInteger(TERMINAL_MEMORY_USED));

  PRINT(GetSummaryCommissionMQL5());

  PRINT(MQLInfoInteger(MQL_MEMORY_USED));
  PRINT(TerminalInfoInteger(TERMINAL_MEMORY_USED));

  PRINT(GetSummaryCommissionMQL4());

  PRINT(MQLInfoInteger(MQL_MEMORY_USED));
  PRINT(TerminalInfoInteger(TERMINAL_MEMORY_USED));

  PRINT(HistoryDealsTotal());
  PRINT(HistoryOrdersTotal());
  PRINT(PositionsTotal());
}


结果是

MQLInfoInteger(MQL_MEMORY_USED) = 1
TerminalInfoInteger(TERMINAL_MEMORY_USED) = 1203

GetSummaryCommissionMQL5() = -43568.97
MQLInfoInteger(MQL_MEMORY_USED) = 1
TerminalInfoInteger(TERMINAL_MEMORY_USED) = 1404

GetSummaryCommissionMQL4() = -43568.97
MQLInfoInteger(MQL_MEMORY_USED) = 45
TerminalInfoInteger(TERMINAL_MEMORY_USED) = 1424

HistoryDealsTotal() = 130330
HistoryOrdersTotal() = 190241
PositionsTotal() = 0


130K 交易 + 190K 订单,终端内存消耗增加 20 MB(+10%)。

您可以自己测量性能。文档早已过时。

 
 
fxsaber #:
使用该库会增加多达 10%的内存消耗

这是什么原因呢?

 
Vitaly Muzichenko #:

这有什么关系?

关于交易、自动交易系统和测试交易策略的论坛

图书馆: MT4Orders

fxsaber, 2023.07.07 13:12

  • OrderSelect 从历史记录中计算所选订单的所有数据(OrderPrint 是免费的)。这是 HistoryOrderGet* 和 HistoryDealGet* 函数的绝佳组合,可处理任何复杂的市场情况和大量陷阱。查看 MT4ORDERS::GetHistoryPositionData()。这是一个适用于终端和测试器的单一函数,但针对测试器进行了特别加速,因为许多终端陷阱在测试器中并不存在。配置示例:
 
fxsaber #:
使用该库会增加多达 10% 的内存消耗

我还以为昨天有库更新,但一年都没赶上:)

我会期待的,谢谢你的支持!

 

子,在函数转移中使用 const 有多大好处?

同时,在函数内部创建类成员 是否合理,还是可以使用全局,在机器人交易中使用 7 个字符?

通过间谍指标对每个刻度线进行处理。

在空的情况下,对每个刻度线进行处理,通常不会发现异常,这是一个优化函数的问题...
 
// 更改列表:
// 21.07.2023
// 修复:已删除挂单的 OrderLotsOpen() 已修复。
// 添加:处理 MT5 交易没有 MT5 订单的情况。
// 修复:当 SL/TP 订单没有价格时,正确定义 OrderClosePriceRequest()。
// 添加:MT4ORDERS_AUTO_VALIDATION 宏允许您自动验证市场产品。
// 添加:MT4ORDERS_ORDERS_SORT 宏生成按关闭/删除时间排序的 MT4 订单历史记录。
 

fxsaber #:

/ 添加:MT4ORDERS_ORDERS_SORT 宏生成按关闭/删除时间排序的 MT4 订单历史记录。

下载了更新并进行了检查,现在限价订单一切正常,目前没有发现任何延迟。

谢谢!

 
Vitaly Muzichenko #:

尚未出现滞后。

现在使用的是正面变量

如果在调用 OrdersHistoryTotal() 的两次相邻调用之间更新了交易历史,下面的代码可以显示这种解决方案的执行时间。

#include <fxsaber\Benchmark\Benchmark.mqh> //https://www.mql5.com/zh/code/31279

ulong OrdersMQL5()
{
  ulong Res = 0;

  if (HistorySelect(0, INT_MAX))
  {
    const int Total = HistoryOrdersTotal();
    ulong Array[][2];
    
    ArrayResize(Array, Total);
    
    for (int i = 0; i < Total; i++)
    {
      const ulong Ticket = HistoryOrderGetTicket(i);

      Array[i][0] = HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE_MSC);
      Array[i][1] = Ticket;
    }
          
    ArraySort(Array);      
    
    Res = Array[Total - 1][1];
  }
  
  return(Res);
}

void OnStart()
{
  OrdersMQL5(); // 热身。
  
  for (int i = 0; i < 3; i++)
    _B(OrdersMQL5(), 1);
    
  Print(HistoryOrdersTotal());
}


在一些交易账户上运行结果。在 HistoryOrdersTotal() 的横轴上。

X - 历史订单总数()

您可以清楚地看到,100K MT5 订单的滞后时间为 10 毫秒(如果交易历史在上次运行后更新,则 OrdersHistoryTotal 的执行时间)。

在测试器中则完全没有滞后。只有在终端中才有。显然,可以加快速度,但不会达到这种程度。