文章 "MQL5 对决 QLUA - 为什么在 MQL5 中交易操作速度快达 28 倍?" - 页 3

 
Renat Fatkhullin:

同时,测量结果的差异也会浮动,比如 10%。

但是,如果根据数十次测试的结果,两者之间的差异稳定在 4-5 倍,那就没什么好讨论的了。

MT5 上的差异(不稳定)高达 2 倍。这就是为什么我决定,如果要衡量性能,我们应该看数据包到达的最大频率(相邻数据包之间的最短时间)。我编写了相应的智能交易系统

class FREQUENCY
{
private:
  ulong PrevTime;
  int MinInterval;
  datetime TimeMinInterval;

  static string ToString( const int Interval, const datetime ServerTime )
  {
    return("Frequency = " + ((Interval == 0) ? "Unknown" : ::DoubleToString(1 e6 / Interval, 1)) +
           " Hz (" + ::DoubleToString(Interval / 1000.0, 3) + " ms), ServerTime = " + (string)ServerTime);
  }

public:
  const string symbol;

  FREQUENCY( const string Symb = NULL ) :
         symbol((Symb == NULL) ? ::Symbol() : Symb), MinInterval(INT_MAX), PrevTime(0)
  {
  }

  ~FREQUENCY( void )
  {
    ::Comment("");
  }

  void Refresh( const string Symb )
  {
    if (Symb == this.symbol)
    {
      const ulong NowTime = ::GetMicrosecondCount();

      if (this.MinInterval == INT_MAX)
        this.MinInterval--;
      else
      {
        const int Interval = (int)(NowTime - this.PrevTime);

        if (Interval < this.MinInterval)
        {
          this.MinInterval = Interval;
          this.TimeMinInterval = ::TimeCurrent();

          ::Alert(this.ToString());
        }

        ::Comment(FREQUENCY::ToString(Interval, ::TimeCurrent()) + "\n" + this.ToString());
      }

      this.PrevTime = NowTime;
    }

    return;
  }

  string ToString( void ) const
  {
    return("Max" + FREQUENCY::ToString(this.MinInterval, this.TimeMinInterval) +
           ", ServerName = " + ::AccountInfoString(ACCOUNT_SERVER) + ", Symbol = " + this.symbol);
  }
};

class FREQUENCY_BOOK : public FREQUENCY
{
public:
  FREQUENCY_BOOK( const string Symb = NULL ) : FREQUENCY(Symb)
  {
    ::MarketBookAdd(this.symbol);
  }

  ~FREQUENCY_BOOK( void )
  {
    ::MarketBookRelease(this.symbol);
  }
};
/*
FREQUENCY Frequency;

void OnTick( void )
{
 Frequency.Refresh(_Symbol);

 return;
}
*/

FREQUENCY_BOOK FrequencyBook;

void OnBookEvent( const string &symbol )
{
  FrequencyBook.Refresh(symbol);

  return;
}

得到的结果是

2016.09.14 10:21:47.059 Frequency (Si-9.16,M1)  MaxFrequency = 28571.4 Hz (0.035 ms), ServerTime = 2016.09.14 10:21:28, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:47.014 Frequency (Si-9.16,M1)  MaxFrequency = 6211.2 Hz (0.161 ms), ServerTime = 2016.09.14 10:21:28, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:40.062 Frequency (Si-9.16,M1)  MaxFrequency = 5988.0 Hz (0.167 ms), ServerTime = 2016.09.14 10:21:21, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:35.199 Frequency (Si-9.16,M1)  MaxFrequency = 1242.2 Hz (0.805 ms), ServerTime = 2016.09.14 10:21:16, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:35.149 Frequency (Si-9.16,M1)  MaxFrequency = 222.9 Hz (4.486 ms), ServerTime = 2016.09.14 10:21:16, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:34.459 Frequency (Si-9.16,M1)  MaxFrequency = 122.0 Hz (8.200 ms), ServerTime = 2016.09.14 10:21:15, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:28.640 Frequency (Si-9.16,M1)  MaxFrequency = 120.7 Hz (8.286 ms), ServerTime = 2016.09.14 10:21:09, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:25.602 Frequency (Si-9.16,M1)  MaxFrequency = 115.2 Hz (8.684 ms), ServerTime = 2016.09.14 10:21:06, ServerName = BCS-MetaTrader5, Symbol = Si-9.16
2016.09.14 10:21:24.572 Frequency (Si-9.16,M1)  MaxFrequency = 106.7 Hz (9.373 ms), ServerTime = 2016.09.14 10:21:05, ServerName = BCS-MetaTrader5, Symbol = Si-9.16

如果相邻的 BookEvent 事件之间相隔 ~10ms 是合理的。但 0.035 毫秒就说不过去了。事实证明,BookEvent 事件的创建原理与 Tick 事件相同:

Tick 事件以超高频率发生:

MaxFrequency = 12820.5 Hz (0.078 ms), ServerTime = 2016.09.14 09:29:05, ServerName = RoboForexEU-MetaTrader 5, Symbol = EURUSD.e

这只能解释为,如果一个 tick 数据包到达,那么数据包中的每个 tick 都 会以一定的间隔和数量(由开发人员设置)生成 一个 Tick-event。这样,我们就不会错过智能交易系统中的收盘跳动点。


至于 "计算-事件",在将代码转换为指标后,"计算-事件 "之间的最大频率远高于 "滴答-事件"。这是因为在软件包中,似乎所有 ticks 都会创建一个计算事件。

因此,这种测量方法并不适用于 Tick/Calculate/BookEvent 事件。如何在 MQL5 中监控新报价网络数据包的到达还不清楚。

 
Renat Fatkhullin:

任何测试都必须包含冷启动保护。

因此,跳过 N 个刻度就表明我们意识到了这一事实,并将其考虑在内。这样做的目的是为了避免明显意料之中的 "你们为什么不对冷启动的影响进行补偿 "的说法。


关于三个终端会话开始的 视频是 2016 年 8 月 25 日为另一位声称 MT5 在会话开始时会变慢的交易员准备的。后来的事实证明,该交易员根本没有使用 MT5,只是在论坛上散布了一些猜测。此外,一些交易员并不知道,交易所交易工具的图表并不是根据出价(Bid),而是根据最后成交价(Last)绘制的。他们认为更改出价和不在图表上显示出价是 "MT5 刹车"。

当然,并没有什么 "刹车"。

谢谢,现在我明白了!
 
fxsaber:

MT5 上的差异(不稳定)高达两倍。因此我决定,如果要衡量性能,我们应该看数据包到达的最大频率(相邻数据包之间的最短时间)。我编写了相应的智能交易系统

得到的结果是

如果相邻的 BookEvent 事件之间相隔 ~10ms 是合理的。但 0.035 毫秒就说不过去了。事实证明,BookEvent 的创建原理与 Tick 事件相同:

可信。

数据是以交易的方式产生的,您看到两个连续交易的时间很短,这充分证明了我们处理的正确性以及终端本身和 MQL5 子系统的性能。


因此,这种测量方法不适合 Tick/Calculate/BookEvent 事件。如何在 MQL5 中监控新报价网络数据包的到达,目前还不清楚。

它非常适合。

看看我们的代码--它专门测量的不是单个短数据,而是愚蠢地收集 30 秒的 ticks。这将消除任何波动和错误。

在上述视频中,MQL5 在 30 秒内收到了 1,278 个刻度线,而 QLUA 只收到了 254 个刻度线。这对 QLUA 算法交易来说是一个残酷的打击。

 
Renat Fatkhullin:

可信。

数据是以事务方式传送的,而您看到的两个连续事务时间很短,这充分证明了我们处理的正确性以及终端和 MQL5 子系统的性能。

但它们是以网络数据包的形式出现的。我想测量网关速度。

这很合适。

看看我们的代码--它专门测量的不是单个短数据,而是愚蠢地收集 30 秒的刻度。这样可以消除任何波动和错误。

在上述视频中,MQL5 在 30 秒内收到了 1,278 个刻度,而 QLUA 只收到了 254 个刻度。这对 QLUA 算法交易来说是一个残酷的打击。

您没有理解我的意思。我根本不关心 QLUA 制动,一切都很清楚(文章中也没有任何问题)。我想了解 MT5 本身的性能特点。而我所采用的 MaxFrequency 方法并不合适。因为 MT5 在创建 Tick/Calculate/BookEvent 事件方面存在特殊性。在您的位置运行 Expert Advisor - 您会很快发现这一点。
 
fxsaber:

但它们在网络数据包中是捆绑在一起的。我想测量网关的速度。

没关系。

MT5 终端会将这些刻度一个接一个准确无误地发送给您。


你误解我了。我不关心 QLUA 制动--一切都很清楚(文章中也没有任何问题)。我想了解 MT5 本身的性能特点。而我所采用的 MaxFrequency 方法并不合适。因为 MT5 在创建 Tick/Calculate/BookEvent 事件方面存在特殊性。在您的地方运行 Expert Advisor - 您会很快发现这一点。

每个 tick 都 是独立发送的交易" 这一原则意味着,从意识形态上讲,一切都建立在正确的基础上。我们从零开始建立了 5 个平台,并不止一次地经历了所有的陷阱,怎么可能会出错呢?

你们获得了非常高的性能。你开始编造频率显然是无稽之谈。我们有数据时才有数据,有数据时才有数据。因此,谈论 "频率稳定性/不稳定性 "没有任何逻辑意义。你不是在测试石英振荡器的稳定性,而是在试图稳定玻璃中出现价格的随机过程。

这只是快,最初建立在控制快照频率上的所有过程。结果自然水到渠成。

 
Renat Fatkhullin:

没关系。

蜱虫一个接一个地出现,MT5 终端设法将它们准确无误地发送给您。


每个刻度线都是独立发送的一笔交易 "这一原则意味着,从意识形态上讲,一切都建立在正确的基础上。我们从零开始建立了 5 个平台,并不止一次地经历了所有的陷阱,怎么可能有错。

你们获得了非常高的性能。你开始编造频率显然是无稽之谈。我们有数据时才有数据,有数据时才有数据。因此,谈论 "频率稳定性/不稳定性 "没有任何逻辑意义。你不是在测试石英振荡器的稳定性,你是在试图稳定价格在玻璃上出现的随机过程。

我可以很容易地解释频率原理。堆栈是由交易所本身以不稳定的速度形成的,因为它取决于市场参与者的行为。

我想测量堆栈更新的 最大频率,即 MT5 在单位时间内可以生成多少堆栈。结果发现,赌注是一揽子进入 MT5 的。有可能来自交易所的赌注根本没有丢失,而是全部都来了。而 BookEvent 事件不是为一个包创建的,而是为包中的所有赌注(从最早到最晚)创建的。在 MQL5 中不可能获得牌堆形成的时间。包到达的时间是相同的。因此,事实证明,我测量相应 MT5 性能特征的实现并不能显示我想看到的结果。

事实上,BookEvent 是以数据包的形式形成的,我对此表示支持。对于 Expert Advisor 而言,这是最大的信息量和最小的麻烦。性能测量的唯一问题就是我所描述的。

 
fxsaber:

我可以很容易地解释频率原理。堆栈是由交易所本身以可变速率形成的,因为它取决于市场参与者的行为。

我想测量堆栈更新的最大频率,即 MT5 在单位时间内可以生成多少堆栈。结果发现,赌注是一揽子进入 MT5 的。有可能来自交易所的赌注根本没有丢失,而是全部都来了。而 BookEvent 事件不是为一个包创建的,而是为包中的所有赌注(从最早到最晚)创建的。在 MQL5 中不可能获得牌堆形成的时间。包到达的时间是相同的。因此,事实证明,我测量相应 MT5 性能特征的实现并不能显示我想看到的结果。

事实上,BookEvent 是以数据包的形式形成的,我对此表示支持。对于 Expert Advisor 而言,这是最大的信息量和最小的麻烦。但是,我所描述的性能测量只有一个问题。

我再次重申--以这种方式测量频率并得出这样的结论毫无意义。

不要试图根据两个刻度线之间的时间差来测量堆栈中价格出现的随机过程的频率。很明显,你会得到一个从 1 到 XXXXX 的随机数字。

您提出了错误的问题,进行了错误的计算,得出了错误的结论。同时,您的一句 "MT5 不会显示您想看到的东西,您无法测量它 "也给柳条蒙上了一层阴影。

不存在 "性能测量 "的问题,因为您测量错了东西,用错了方法。您得出了错误的特征和根本错误的计算结果。


注:但在测试中,我们通过收集 30 秒的报价并除以所用时间,正确测量了报价到达的频率。

 
Renat Fatkhullin:

我再重复一遍--以这种方式测量频率并得出这样的结论是毫无意义的。

不要试图根据两个刻度线之间的时间差来测量玻璃杯中价格出现的随机过程的频率。很明显,你会得到一个从 1 到 XXXXX 的随机数字。

您提出了错误的问题,进行了错误的计算,得出了错误的结论。同时,您的一句 "MT5 不会显示您想看到的东西,您无法测量它 "也给柳条蒙上了阴影。

ps: 但我们在测试中通过收集报价 30 秒并除以所用时间正确测量了报价到达的频率。

我测量的是最大频率,而不是当前频率!我详细描述了进行这种测量的原因和结果,并提供了数据来源。出于某种原因,您觉得我给 MT5 蒙上了阴影。

任何论坛的老前辈只要读过这个讨论,就会明白我的意思。您不会看到我对 MT5 有任何阴影。我的实施结果是错误的。是我的,不是你的!你在为自己辩护,而我甚至没有给出理由。

是我的实现不允许您测量您想要的。MQL5 没有这种可能性,这很正常。就像我想要果汁,但 MQL5 却不提供这样的机会一样正常。

如果有人想测量相应事件的相邻调用之间的时间,并将其解释为性能,我只分享结果。有必要清楚地认识到实际显示的是什么。

 

你从根本上就错了。

当您实际测量随机过程的 delta 时,两个事件的 delta 值均为 0,那么最大频率是多少?

如果正确执行了 tick 传输(我们也正确执行了),您显然会得到最大 "频率"=(用程序代码处理 MQL5 调用的时间)/(定时器误差)。

从理论上讲,如果达到定时器的精度并得到 0 微秒,频率将为无穷大。以及除以 0 的关键误差(您的代码中没有除以 0 的控制)。

 
Renat Fatkhullin:

你从根本上就错了。

当您实际测量随机过程的 delta 时,两个事件的 delta 值均为 0,那么最大频率是多少?

如果正确执行了 tick 传输(我们也正确执行了),您肯定会得到最大 "频率"=(用程序代码处理 MQL5 调用的时间)/(计时器误差)。

是的,我就是这样得到的。原来我测量的是一个随机过程,而我想测量的是网络数据包传送过程。但没有成功。

理论上,如果你能满足计时器的精度,得到 0 微秒,那么频率将是无穷大。嗯,还有一个关键的 除以零错误(你的代码中没有除以零控制)。

是的,我有!