程序库: TesterBenchmark - 页 2

 

想法是好的,但实施起来不对。已在私信中回复:

fxsaber

下午好!

您能否将交易逻辑调整到您的交易库中,以衡量其性能?

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

库: TesterBenchmark

fxsaber, 2017.08.15 19:31

名额分配如下

  1. Pure MQL5 - 100% 性能。
  2. MT4Orders.mqh - ~95% 性能。
  3. SB Trade\Trade.mqh - ~84% 的性能。
SB 开始减少滞后。


ZЫ 我想知道其他贸易库的表现如何...

谢谢!

我不明白什么的性能?库?没有策略是不行的。你需要一个战略。然后,我们需要测量借助库编写的策略的性能。假设我们测量了它,得到了结果。我们应该与什么进行比较呢?我们需要与纯 MQL 编写的相同策略进行比较。从哪里获得两个策略?假设我们有这样两个策略。但哪里能保证它们在交易进出场方面完全相同呢?假设我们有两个保证彼此相同的策略,我们测量它们的速度。速度只相差一点点。这是否意味着发动机是高效的?不,不是的,因为策略并没有使用引擎/MQL 的所有功能。突然发现,如果您在另一个策略中请求长期历史报价,引擎的工作速度会慢很多倍。这是否意味着引擎的工作速度比纯 MQL 慢很多倍?不,这并不意味着这一特定操作会更慢,但如果对提供数据的类进行优化,那么在新版本中,引擎在相同操作上的运行速度将快于 CopyXXX 系统。这就是为什么整个故事的主要内容并不清楚: 我们是什么?.

 
Vasiliy Sokolov:

想法是好的,但实施起来不对。已在私信中回复:


它包含相同的简单交易逻辑,但有三种方式:纯 MQL5、Trade.mqh 和 MT4Orders.mqh。

因此,可以用完全相同的交易结果来衡量每个变体的性能。

到目前为止,Trade.mqh 落后 15%。但性能测量方法是通用的--您可以在任何交易 API 上重复交易逻辑。在此,我建议您将其写入您的跨平台 "圣经",并通过与纯 MQL5 进行比较来测量速度。

通过这样的测量,我能够找到我的圣经中的瓶颈,并将其消除。在优化时,这有时会转化为节省的时间。总的来说,我认为这很有用。


在您的顾问中,您只需要
#include <TesterBenchmark.mqh>

就可以了。然后选择 "优化 "并运行。你会在日志中看到性能。

 

在您的测试版智能交易系统代码中,每个刻度都 会对历史交易进行全面搜索,同时考虑总手数和利润,并计算当前交易的成交量:

if (HistorySelect(0, TimeCurrent()))
    {
      const int Total = HistoryDealsTotal() - 1;
      double SumProfit = 0;
      double SumLots = 0;
      for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
      {
        const ulong Ticket = HistoryDealGetTicket(i);

        if ((ENUM_DEAL_ENTRY)HistoryDealGetInteger(Ticket, DEAL_ENTRY) == DEAL_ENTRY_OUT)
        {
          SumProfit += HistoryDealGetDouble(Ticket, DEAL_PROFIT) * (AmountLastDeals - Count);
          SumLots += HistoryDealGetDouble(Ticket, DEAL_VOLUME) * (AmountLastDeals - Count);

          Count++;
        }
      }
      SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;
      ...
   }

您的 Expert Advisor 除了加载 HistorySelect 外,什么也没做。因此,除了 HistorySelect 本身之外,它不能作为衡量任何其他性能的基准。因此,我引用您的陈述"MT5 比 MT4 快 4.4 倍!" 至少应更正为 MT5 中的 HistorySelect 比 MT4 中类似的内部程序快 4.4 倍。

至于我的引擎 CStrategy,它目前根本不允许处理交易,只能处理头寸,因此现在写的示例无法在 CStrategy 中使用。

附注: 我要指出的是,在您的示例中,工作速度等于 O(n)。在这种情况下,MT4 和 MT5 的唯一区别在于 HistorySelect/HistoryOrderSelect 的速度。当然,在复杂度为 O(n) 的任务中,CStrategy 会使用基本调用,在本例中就是 HistorySelect,自然会比直接调用 HistorySelect 慢一些。但是,如果需要调用 HistoryOrderSelect(ticket),那么一切都会变得更加有趣,在某些任务中,CStrategy 将打破对环境的标准访问,这是因为要通过字典访问并在程序内存中存储数据。

 
Vasiliy Sokolov:

在您的测试版智能交易系统代码中,每个刻度都 会对历史交易进行全面搜索,同时考虑总手数和利润,并计算当前交易的成交量:

您的 Expert Advisor 除了加载 HistorySelect 外,什么也没做。因此,除了 HistorySelect 本身之外,它不能作为衡量任何其他性能的基准。因此,我引用您的陈述"MT5 比 MT4 快 4.4 倍!" 至少应更正为 MT5 中的 HistorySelect 比 MT4 中类似的内部程序快 4.4 倍。

您太妄下结论了。只有在开仓时才会每隔几秒执行一次。也就是说,很少执行。

至于我的 CStrategy 引擎,它目前根本不允许处理交易,而只允许处理头寸,因此现在编写的示例无法在 CStrategy 中使用。

下面是 OnTick 测试 EA 的 MQL4 代码,它也只能处理头寸。

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , null, 0, 0, 0, int_min);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

当然,在您的 API 上重写这样简单的逻辑并不困难。但是,如果您有更好的 EA 来分析交易 API 性能的建议(只是交易,而不是时间序列等),我将很高兴看到您的交易逻辑版本。我可以为纯 MQL5、MQL4 和 Trade.mqh 快速重写它。


ZY 启动测试顾问时选择余额 = 1e7。以便始终有足够的资金建仓。

 
fxsaber:

你的结论太早了。给定的乐曲每隔一秒才会在开局位置执行一次。也就是说,很少执行。

下面是测试的 Expert Advisor 的 OnTick 的 MQL4 代码,它也只对仓位起作用。

当然,在您的 API 上重写这样简单的逻辑并不困难。但如果您有更好的 EA 以分析交易 API 性能的建议(只分析交易,不分析时间序列等),我很乐意看到您的交易逻辑版本。我可以为纯 MQL5、MQL4 和 Trade.mqh 快速重写它。

请仔细查看您的代码,并告诉我它的测量结果

if (!OrderSelect(0, SELECT_BY_POS))
{
  const int Total = OrdersHistoryTotal() - 1;

  double SumProfit = 0;
  double SumLots = 0;

  for (int i = Total, Count = 0; (i >= 0) && (Count < AmountLastDeals); i--)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      SumProfit += OrderProfit() * (AmountLastDeals - Count);
      SumLots += OrderLots() * (AmountLastDeals - Count);

      Count++;
    }

  SumLots /= (AmountLastDeals * (1 + AmountLastDeals)) >> 1;

  const int Type = (Total >= 0) && OrderSelect(Total, SELECT_BY_POS, MODE_HISTORY) && (OrderType() == OP_BUY) ? OP_SELL : OP_BUY;

  OrderSend(_Symbol, Type, (SumProfit >= 0) ? Lots : CorrectLot(SumLots),
            SymbolInfoDouble(_Symbol, (Type == OP_BUY) ? SYMBOL_ASK : SYMBOL_BID), 0, 0, 0); // , null, 0, 0, 0, int_min);
}
else if (TimeCurrent() - OrderOpenTime() >= Interval)
  OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);

这里有两个瓶颈:for 循环和订单发送 本身。您想比较 for 循环在哪里运行得更快?在 CTrade 中还是在纯 MQL 中?在哪里发送订单更快?在 CTrade 中还是在 OrderSend 中?当然在纯 OrderSend 中更快,因为在 CTrade 中,订单发送前要进行大量检查。但从中可以得出什么结论呢?

 
Vasiliy Sokolov:

仔细看看你的代码,告诉我它的测量结果是什么

这里有两个瓶颈:for 循环和实际发送订单。您想比较一下 for 循环在哪里运行得更快?

由于某些原因,您没有看到

fxsaber:

给定的指令仅在每隔几秒开仓时执行一次。也就是说,很少执行。


Vasiliy Sokolov:

在哪里发送订单更快?在 CTrade 还是在 OrderSend?当然是在纯 OrderSend 中更快,因为在 CTrade 中,订单发送前会进行大量检查。但这有什么影响呢?

与 MT4Orders 相比,CTrade 所做的检查要少得多。现在的结论很简单--SB 比纯 MQL5 落后 16%,而且可以绝对准确地加速。任何使用 CTrade 的人都会在优化期间损失额外的云资金和优化本身的时间。

 

你还是不明白你的代码在做什么。我特意运行了剖析器,在一个小时内,我以 1 秒钟的间隔进行了 1800 次交易。 99,66% 的 OnTick 执行时间被两个OrderSend 函数 占用

你打算优化什么?剩下的 0.34% 没有意义。你不能优化订单发送。

好吧。最有趣的部分把 #include <Trade\Trade.mqh> 放进去,看看使用 CTrade 库时发生了什么变化:


现在调用 Trade.Buy/Sell 和 Trade.PositionClose 需要 100% 的时间。我们调用 Trade.PositionClose,嗒-哒-嗯:

也就是说,在 99.97% 的时间里,Trade.PositionClose 调用的都是相同的 OrderSend。同样,Trade.Buy 和 Trade.Sell 也是如此。

那么,您打算在 SB 中优化什么?测试对象在哪里?您一般要测试什么?

(对于那些不理解剖析数据的人,我会解释一下:程序执行时间的 99.97% 是通过 OrderSend 直接发送订单,剩余的 0.03% 是通过 CTrade 绑定和订单发送前的必要检查。也就是说,使用合格的 OOP 带来的延迟微乎其微,可以忽略不计,并将其视为等于零。这并不是 0.03%,而是更少,因为这 0.03% 的大部分时间都被强制性检查占用了,而这些检查应该以适当的方式实现,无论是在程序代码中还是其他地方)。

 
Vasiliy Sokolov:

我专门运行了剖析器,在一小时内,我以 1 秒钟的间隔进行了 1800 笔交易。

这跟在线有什么关系?这与测试仪有关。

 
Andrey Khatimlianskii:

这与在线测试有什么关系?这与测试仪有关。

如果我们谈论的是 MT5 及其策略测试器,那么同样有 99% 的时间(也许更少一点)用于重现交易环境(因此运行速度比 MT4 慢)。没有理由认为,如果订单发送在现实生活中需要花费 99.9% 的时间,那么在策略测试器中,它的运行速度就会突然快两个数量级。
 
Vasiliy Sokolov:
如果我们谈论的是 MT5 及其策略测试工具,那么同样有 99% 的时间(也许更少)用于重现交易环境(因此运行速度比 MT4 慢)。没有理由认为,如果订单发送在现实生活中需要花费 99.9% 的时间,那么在策略测试器中就会突然快两个数量级。

瓦西里,你是在认真讨论订单发送在测试器中的执行速度与实时执行速度的可比性吗?

在线执行速度是最慢的,因为它向服务器发送信息并等待响应,而在测试器中(如果不包括延迟,但这是不可能的),它即时发送并等待响应。

该库的任务是测量测试仪的速度(就交易功能而言)。