新的mql4提供时间戳中的毫秒.... - 页 3

 

所有。

这里的问题是要获得tick的时间戳,而不是像建议的那样,使用GetTickCount() 获得tick到达终端的时间(即每当start()函数被调用时)。

MarketInfo(Symbol(), MODE_TIME)返回从经纪商的服务器发送的数据源的时间戳。

注意

尊敬的先生

 
AnkaSoftware:

所有。

这里的问题是要获得tick的时间戳,而不是像建议的那样,使用GetTickCount()获得tick到达终端的时间(即每当start()函数被调用时)。

MarketInfo(Symbol(), MODE_TIME)返回从经纪商的服务器发送的数据源的时间戳。

不幸的是,它的精度只有1秒。
 
ubzen:

1)GetTickCount(),应该是现场工作。对历史数据毫无意义。

2) 即使是mt5_data也不是以毫秒为单位保存。但是,在现场没有问题。

3) 我不明白你为什么要这么做。如果是以毫秒为单位的同一时间,那么有毫秒就没有帮助。如果是以毫秒为单位的不同时间,那么GetTickCount()可能有帮助。帮助是指你的代码在不到一毫秒的时间内处理当前的刻度。 有多重要取决于你要完成的任务...我想。


谢谢大家的回答。 有一个指标被发布到代码库,即Rogue Tick Detector。 但它还没有被批准。 你可以暂时在这里 找到它。

基本的想法是,有些时候,当前的tick0会比前一个tick1的时间戳晚。 但价格将不再是可操作的,但EA或人类交易员在事后才知道这一点。 这导致基于价格的事件被错误地触发。流氓的tick检测器能够标记这些假tick并阻止EA对其采取行动(等待下一个 "好 "tick)。

目前捕捉刻度线时间的方法,MarketInfo(Symbol(), MODE_TIME),并没有返回毫秒级的时间戳。 所以我来到这里,想看看是否有我们忽略的其他方法。

包含流氓勾选检测功能的EA都运行在纽约的VPS上,配有SSD驱动器和WINDOWS 2008,并且通常距离经纪商服务器<2ms。 没有HFT或超规模交易(交易平均保持时间约为1小时)。

这使我回到了我最初的问题之一。 那么,MT4(和MT5)平台[本身]如何正确区分在 "同一时间 "进入的ticks?

编辑,感谢ankasoftware的澄清。

 
4evermaat:


这使我回到了我最初的问题之一。 那么,MT4(和MT5)平台[本身]应该如何正确区分 "同一时间 "进来的刻度?

你不能 ......你的经纪人是否真的向你发送了多个同时发生的ticks? 或者他们只是将计数增加2,然后发送后一个tick? 你怎么能知道他们是否这样做?
 
RaptorUK:
你不能 ......你的经纪人是否真的向你发送了多个同时发生的跳动? 或者他们只是将计数增加2,然后发送后一个跳动? 你怎么能知道他们是否这样做?


是的,我知道不同的经纪商有不同的饲料,tick计数会有很大的不同。 但是,恰好在某些时候,主要是在交易获利平仓的时候,发出了流氓的ticks。 这影响了平仓和订单的触发,所以我们找到了一种方法来检测并尽可能地忽略它们。 我甚至怀疑一些经纪人在某些时候故意操纵饲料。

但是,也许我们应该有一个蜱虫计数比率,即我们计算蜱虫总数

这很可能不会影响很多人,但我认为潜在的损害足以保证进一步调查。

 
据我所知,目前还没有任何函数/程序完全 满足你的要求。
4evermaat:但也许我们应该有一个tick计数比率,我们计算总的ticks

你有什么想法?这与mt4交易量有什么不同?什么两个数字的比率[计数和?]。

这个问题很快就变得非常混乱了。包括我自己在内,我不知道关于ticks的一切,也不知道metaQuotes是如何处理的,更不知道为什么它会对某人非常关键。请允许我总结一下我的一些观察。

1)metaQuotes说:你想要毫秒级的时间戳,[他们立即开始思考tick_data],谁来持有这个tick_data的经纪人? 你是说告诉你在那一分钟内有200个ticks对你来说还不够好?你真的想让我们保存200条数据,因为OHLC+V不够好?

2) 1号交易员说:我不需要任何人保存信息,我只需要毫秒的时间戳来确定旧数据。

3) 2号交易员说:我不需要你保存信息给我,只要给我导入信息的能力,我就能得到自己的数据。

4)3号交易员说:我不明白为什么保存和提供tick数据有这么大的问题。拜托,现在的电脑有更大的功率和内存,我的经纪人肯定能在某个地方提供数据。

5) 经纪人说:伙计,我给你3个多月的M1数据已经很困难了,你凭什么认为我有能力或愿意在你连接或测试时提供这么多数据。

6)4号交易员:我们不需要它来做测试,只需要一小部分数据就足够了,我现在不抱怨M1不足,那有什么问题。

7) metaQuotes: 还是不行,这意味着我们必须促进返回毫秒的函数和区分刻度的指标等......你是想让终端崩溃还是什么?

8) trader number5: 你的意思是Volume不是market_depth,而是一个特定时间段内的ticks数量的计数:).你的意思是我可以错过刻度?你的意思是说刻度会在网络空间中丢失或延迟?你是说不同经纪商的tick_count不同?你是说经纪人储存的数据与我收到的数据不一样?那么,关于tick的大惊小怪又是什么呢?

9) xxxxxxxxxxxx说:tick是最高机密,所提供的当然是足够好的,我帮助设计了tick生成器,对提供那种分辨率兴趣不大。不会发生....。

10) 6号交易员:技术上有限制,可以提供什么,tick计数如何工作,可以接收什么,等等。这不是MetaTrader的问题,而是所有的零售平台都有这个问题。请关注机构软件,并准备好花大钱。

Trader#3 to Trader#10: 我不同意。

Ubzen说:我只是不知道该说些什么了。

Ps> 差点忘了交易员#7:好吧,我将保存我自己的tick,它来到我的终端,并编写我自己的指标和这样的程序来处理这些数据......这是我对问题的理解,因此我推荐使用GetTickCount()。

 
ubzen:

Ps> 差点忘了trader#7:好的,我将保存我自己的tick,它来到我的终端,并编写我自己的指标等来处理这些数据。这就是我对问题的理解,因此我推荐使用GetTickCount()。

不幸的是,这仍然无法应对错过的点数......在实践中,不可能保存你自己的点数,你不可能得到所有的点数,因为你会错过一些,除非记录这一事实,否则保存的数据将是不正确的,所以可能比无用的更糟糕,它将是误导。
 
RaptorUK: 不幸的是,这仍然无法应对错过的时间点......在实践中,不可能保存你自己的时间点,你不可能得到所有的时间点,因为你会错过一些,除非这个事实被记录下来,否则保存的数据将是不正确的,所以可能比无用的更糟糕,它将是误导。

我希望能在这里保持主题:)。说到这里,想象一下,一个经纪人在每一个tick 中发送毫秒级的时间戳。但是,她并不保存这些信息。考虑到人们对经纪商的不信任,这个经纪商将打开大量的询问。但这次人们在几毫秒内就有了证据,但经纪人却没有记录可以反驳。因此,从某种意义上说,要求提供tick_data | milliseconds或其他导致同样争论的东西,基本上是要求经纪人保存tick_data,并要求平台为其提供便利。

其次,考虑大多数人做的反向测试。当你运行一个策略一周后,再对这一周进行反向测试,以验证你是否会得到同样的结果。这个人有毫秒级的实时时间戳,还有延迟和丢失的数据包。当然,像原来的发帖者一样,你忽略了丢失的数据和/或忽略了延迟的数据。然而,当你进行回测时,所有经纪人的数据和正确的时间戳都在那里。这显然会产生与你刚刚收到的实盘不同的结果。

所以,请告诉我,你是被现场误导了,还是在回测期间被误导了?

不过我同意 你的上述说法。我认为,所有这一切造成了一系列的悖论,导致我完全远离分钟间过程。这个平台有局限性,我只是接受并继续前进。

 
ubzen:
...

不过我同意 你的上述说法。我认为,所有这些都创造了一系列的悖论,导致我完全远离了分钟间进程。这个平台有局限性,我只是接受并继续前进。

;-)
 

有趣的链接,谢谢你,这让我看到了Windows的微秒级分辨率时间服务。我根据这些网页的信息进行了一些测试。

我在Win 7 PC和Windows 2012 VPS上的测试表明,无论系统定时器设置如何,GetTickCount()的分辨率总是15.6毫秒(每秒64次中断),而通过调用kernel32.dll函数GetSystemTime()[或GetLocalTime()]或GetSystemTimeAsFileTime()获取毫秒时间时,其分辨率受系统定时器设置影响,在我测试的两台机器上的分辨率可能低至0.5毫秒。

GetTickCount()分辨率

以下是测试GetTickCount()分辨率的脚本代码。

// Script to test Millisecond Resolution via GetTickCount()

void OnStart() {
  uint startMsecsU = GetTickCount(), nowMsecsU;
  for (int j=0; j<1000000000; j++) {
    if ((nowMsecsU = GetTickCount()) > startMsecsU) {
      MessageBox(StringFormat("GetTickCount %u -> %u diff %u", startMsecsU, nowMsecsU, nowMsecsU - startMsecsU), "Test Millisecond Resolution via GetTickCount");
      return;
    }
}

在测试的两台机器上,无论下面提到的其他测试的系统定时器分辨率如何变化,它总是给出15或16(即15.6)。

GetSystemTime()的分辨率

现在事情开始变得有趣了。下面是测试GetSystemTime()分辨率的脚本代码。

/* Script to test Millisecond Resolution via GetSystemTime()

Windows struct for a GetSystemTime() or GetLocalTime() call:
typedef struct _SYSTEMTIME {
  WORD wYear;
  WORD wMonth;
  WORD wDayOfWeek;
  WORD wHour;
  WORD wMinute;
  WORD wSecond;
  WORD wDay;
  WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
*/

// MT4 equivalent struct:
struct _SYSTEMTIME {
  ushort wYear;         // 2014 etc
  ushort wMonth;        // 1 - 12
  ushort wDayOfWeek;    // 0 - 6 with 0 = Sunday
  ushort wDay;          // 1 - 31
  ushort wHour;         // 0 - 23
  ushort wMinute;       // 0 - 59
  ushort wSecond;       // 0 - 59
  ushort wMilliseconds; // 0 - 999
};

#import "kernel32.dll"
void GetSystemTime(_SYSTEMTIME &time);
#import

void OnStart() {
  _SYSTEMTIME st;
  GetSystemTime(st);
  int startMsecs = st.wMilliseconds, nowMsecs;
  for (int j=0; j<1000000000; j++) {
    GetSystemTime(st);
    if (st.wMilliseconds != startMsecs) {
      nowMsecs = st.wMilliseconds;
      if (nowMsecs < startMsecs)
        nowMsecs += 1000; // wMilliseconds wrapped
      MessageBox(StringFormat("GetSystemTime msecs %d -> %d diff %d", startMsecs, nowMsecs, nowMsecs - startMsecs), "Test Millisecond Resolution via GetSystemTime");
      return;
    }
  }
}

在没有运行其他软件的情况下,刚启动的PC上的分辨率为15/16毫秒,但如果PC上运行的是Chrome浏览器,则分辨率为1毫秒!正如angevoyageur的第二个链接所解释的那样,Chrome将系统定时器设置为1毫秒的分辨率,其他一些软件也是如此。

我发现了两个用于设置系统定时器分辨率的小工具,这样就可以在干净的机器上以可控的方式获得1毫秒(甚至0.5毫秒)的分辨率。

Windows系统定时器工具:http://vvvv.org/contribution/windows-system-timer-tool

Timer-Resolution:http://www.lucashale.com/timer-resolution/

我更喜欢这两个中的第一个,Windows系统定时器工具。有了它,我可以通过GetSystemTime()可靠地获得1毫秒的分辨率。GetLocalTime()也可以类似地使用。

上面的脚本代码是一个例子,说明由于结构的存在,新的MT4代码可以变得更好。在旧版MT4中,访问GetSystemTime()需要使用一个整数数组和大量混乱的位操作。

GetSystemTimeAsFileTime()的分辨率

最后,我注意到Windows的微秒级分辨率时间服务 提到,GetSystemTimeAsFileTime()是一个访问系统时间的更快的函数,同时需要一个更小、更简单的结构。后者对于新MT4来说当然是正确的,因为 "结构 "可以减少到只有一个ulong。

以下是测试GetSystemTimeAsFileTiime()分辨率的脚本代码。

// Script to test Millisecond Resolution via GetSystemTimeAsFileTime()

#import "kernel32.dll"
void GetSystemTimeAsFileTime(ulong &SystemTimeAsFileTime); // Returns the system time in 100 nsec units in a ulong
#import

void OnStart() {
  ulong startL, nowL;
  GetSystemTimeAsFileTime(startL);
  for (int j=0; j<1000000000; j++) {
    GetSystemTimeAsFileTime(nowL);
    if (nowL > startL) {
      int diff = int(nowL - startL);
      MessageBox(StringFormat("GetSystemTimeAsFileTime %llu -> %llu diff %d in 100 nsec units = %.1f msecs",
                 startL, nowL, diff, diff/10000.0), "Test Millisecond Resolution via GetSystemTimeAsFileTime");
      return;
    }
  }
}

如果使用 Windows 系统定时器工具设置 0.5 秒的系统定时器分辨率,该小脚本报告的分辨率为 5000(有时为 5001)100 nsecs 单位 = 0.5 msecs。

使用GetSystemTimeAsFileTiime()确实更简单,而且可以显示更精细的分辨率。

下面是一些使用中的照片。

在一次干净的启动后。

清洁启动后

使用Timer Tool将系统定时器的分辨率设置为1ms。

用定时器工具将系统定时器的分辨率设置为1ms

在使用定时器工具时,将系统定时器的分辨率设置为0.5毫秒。

用定时器工具将系统定时器的分辨率设置为0.5ms

总结

在MT4中获取毫秒级时间的最佳函数是GetSystemTimeAsFileTiime(),如上述测试脚本所示,使用Windows System Timer Tool等工具来设置所需的系统定时器分辨率。