服务,MT5的新功能,MT4的葬礼就在眼前。 - 页 8

 

来自英国。

数据

饲料

datafeed -- 数据源(虽然 "源 "这个词不太合适)。


饲养员 - 饲养员,饲养员,饲养员

 

О датафидах. Сколько встречал этот термин, сложилось ощущение, что этим словом обозначают источник данных (котировок). Буквально "заполнитель данных". Когда речь идет о собственных инструментах, понимаю так, что мы сможем вычислять котировки, например, никем не котируемого MXNRUB по известным курсам MXNUSD и USDRUB, выгруженным из терминала в .csv формат, и легализовать для терминала новые котировки, указав файл .csv как новый датафид. Возможно, будет реализовано и более изящное решение, без выгрузки в файлы, путем онлайновых операций */ над тиками (MXNRUB =  MXNUSD * USDRUB). И это будет новый датафид.

他们已经为MT5导入了.csv点数的报价了吗?
 
Andrey Khatimlianskii:

没有留下讨论、错误报告或任何类似的链接?或者只是感觉有一个,但现在还没有检查?

在我的记忆中,OnCalculate中收集的刻度线与通过CopyTix请求的刻度线一致。

现在专门检查了一下......正如我所怀疑的那样,得到了一些垃圾,但不是我所期望的那样 :)

2017.05.22 12:47:10.591 (RTS-6.17,M1)   OnCalculate: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.591 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.599 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.605 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.617 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.637 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.649 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.683 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.765 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.27 ms v = 1, bid = 108320, ask = 108330, last = 108330, flags = 4
2017.05.22 12:47:10.771 (RTS-6.17,M1)   OnCalculate: 2017.05.22 10:47:11.193 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88
2017.05.22 12:47:10.781 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.193 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88
2017.05.22 12:47:10.843 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.244 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 0
2017.05.22 12:47:10.843 (RTS-6.17,M1)   OnBookEvent: Время последнего OnCalculate = 2017.05.22 10:47:11.193 ms (88), время последнего OnBookEvent = 2017.05.22 10:47:11.244 ms (0)
2017.05.22 12:47:10.859 (RTS-6.17,M1)   OnCalculate: 2017.05.22 10:47:11.282 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88
2017.05.22 12:47:10.863 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 10:47:11.282 ms v = 1, bid = 108320, ask = 108330, last = 108320, flags = 88

OnBookEvent()抓取标志为0的刻度...

 

而这正是我所期望看到的。

2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.242 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 11:24:38.689 ms v = 2, bid = 108540, ask = 108560, last = 108550, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: Время последнего STick = 2017.05.22 11:24:38.704 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME ), время последнего CopyTicks = 2017.05.22 11:24:38.697 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME )
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.253 (RTS-6.17,M1)   OnCalculate: Время последнего STick = 2017.05.22 11:24:38.704 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME ), время последнего CopyTicks = 2017.05.22 11:24:38.697 ms (TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME )
2017.05.22 13:24:38.254 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.255 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.255 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.255 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.704 ms v = 2, bid = 108550, ask = 108560, last = 108550, flags = 'TICK_FLAG_SELL TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.261 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.261 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.261 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.262 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.262 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.270 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 11:24:38.710 ms v = 1, bid = 108540, ask = 108560, last = 108560, flags = 'TICK_FLAG_BID '
2017.05.22 13:24:38.280 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.730 ms v = 2, bid = 108550, ask = 108560, last = 108560, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.280 (RTS-6.17,M1)   OnCalculate: Время последнего STick = 2017.05.22 11:24:38.730 ms (TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME ), время последнего CopyTicks = 2017.05.22 11:24:38.719 ms (TICK_FLAG_BID )
2017.05.22 13:24:38.282 (RTS-6.17,M1)   OnBookEvent: 2017.05.22 11:24:38.730 ms v = 2, bid = 108550, ask = 108560, last = 108560, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
2017.05.22 13:24:38.283 (RTS-6.17,M1)   OnCalculate: 2017.05.22 11:24:38.730 ms v = 2, bid = 108550, ask = 108560, last = 108560, flags = 'TICK_FLAG_BUY TICK_FLAG_LAST TICK_FLAG_VOLUME '
正如你所看到的,当用SymbolInfoTick() 在每次调用OnCalculate()时请求最后一个tick时--在CopyTicks()返回的一些ticks中出现了跳转。
 

要检查的代码。

#property indicator_chart_window
#property indicator_plots 0
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
MqlTick _tick;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Подписываемся на стакан
   MarketBookAdd(_Symbol);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   ResetLastError();
//--- Проверяем получение параметров тика
   if(!SymbolInfoTick(_Symbol,_tick))
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": параметры тика не получены!");
   else
      Print(__FUNCTION__,": "+GetMsToStringTime(_tick.time_msc)+" v = ",_tick.volume,", bid = "+DoubleToString(_tick.bid,_Digits)+
            ", ask = "+DoubleToString(_tick.ask,_Digits)+", last = "+DoubleToString(_tick.last,_Digits)+", flags = '"+GetStrFlags(_tick.flags)+"'");
//---
   ResetLastError();
//---
   MqlTick t[1];
   if(CopyTicks(_Symbol,t,COPY_TICKS_ALL,0,1)!=1)
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": Последний тик не получен!");
   else
     {
      if(t[0].time_msc!=_tick.time_msc)
        {
         Print(__FUNCTION__,": Время последнего STick = "+GetMsToStringTime(_tick.time_msc)+" ("+GetStrFlags(_tick.flags)+")"+
               ", время последнего CopyTicks = "+GetMsToStringTime(t[0].time_msc)+" ("+GetStrFlags(t[0].flags)+")");
        }
     }
//---
   return(rates_total);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnBookEvent(const string &symbol)
  {
//---
   if(symbol!=_Symbol)
      return;
//--- Структура - приемник последнего тика
   MqlTick tick;
//---
   ResetLastError();
//--- Проверяем получение параметров тика
   if(!SymbolInfoTick(_Symbol,tick))
      Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": параметры тика не получены!");
   else
      Print(__FUNCTION__,": "+GetMsToStringTime(tick.time_msc)+" v = ",tick.volume,", bid = "+DoubleToString(tick.bid,_Digits)+
            ", ask = "+DoubleToString(tick.ask,_Digits)+", last = "+DoubleToString(tick.last,_Digits)+", flags = '"+GetStrFlags(tick.flags)+"'");
//--- Сравниваем последний тик OnCalculate с последним тиком OnBookEvent
   if(tick.time_msc!=_tick.time_msc)
     {
      Print( __FUNCTION__,": Время последнего OnCalculate = "+GetMsToStringTime( _tick.time_msc )+" ("+GetStrFlags( _tick.flags )+")"+
            ", время последнего OnBookEvent = "+GetMsToStringTime( tick.time_msc )+" ("+GetStrFlags( tick.flags )+")" );
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Отписываемся от стакана
   MarketBookRelease(_Symbol);
  }
//+------------------------------------------------------------------+
//| Получаем строку времени из миллисекунд                                                                      |
//+------------------------------------------------------------------+
string GetMsToStringTime(const ulong ms)
  {
   const int MS_KOEF=1000;               // Коэффициент перевода секунд в миллисекунды
   return( TimeToString( ms/MS_KOEF, TIME_DATE|TIME_SECONDS )+"."+string( ms%MS_KOEF )+" ms" );
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
string GetStrFlags(const uint flags)
  {
   string s="";
//---
   if(( flags&TICK_FLAG_ASK)==TICK_FLAG_ASK)
      s+="TICK_FLAG_ASK ";
   if(( flags&TICK_FLAG_BID)==TICK_FLAG_BID)
      s+="TICK_FLAG_BID ";
   if(( flags&TICK_FLAG_BUY)==TICK_FLAG_BUY)
      s+="TICK_FLAG_BUY ";
   if(( flags&TICK_FLAG_SELL)==TICK_FLAG_SELL)
      s+="TICK_FLAG_SELL ";
   if(( flags&TICK_FLAG_LAST)==TICK_FLAG_LAST)
      s+="TICK_FLAG_LAST ";
   if(( flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME)
      s+="TICK_FLAG_VOLUME ";
//---
   return( s );
  }
//+------------------------------------------------------------------+
 
Alexey Kozitsyn:

要测试的代码。

我将只在调用OnCalculate时将ticks写入文件(以测试OnBookEvent和CopyTicks,但OnCalculate,如其所愿)。

然后通过脚本会生成同样的文件,通过CopyTicks获得ticks。差异将更加明显,并表明在OnCalculate中漏掉的点或CopyTicks的不正确操作。

 
Andrey Khatimlianskii:

为了确定(不是为了测试OnBookEvent和CopyTicks,而是为了测试OnCalculate,正如预期的那样),我会在OnCalculate被调用时只留下ticks写入文件。

然后通过脚本会生成同样的文件,通过CopyTicks获得ticks。差异会更明显,并表明在OnCalculate中跳过了刻度,或者CopyTicks的工作不正确。

有了这样一个简单的计算,我不认为有必要再费心。有两个调用 的具体比较:SymbolInfoTick() 和CopyTicks()。而SymbolInfoTick()的所有调用都清楚地显示出来。可以清楚地看到,CopyTicks()返回了tick,而这个tick在OnCalculate()的SymbolInfoTick()调用中没有收到。而这里的错误可能有两个原因。1.要么OnCalculate()错过了一个刻度,要么2。SymbolInfoTick()在某处返回错误的东西。

是的,这是日志的一部分,收集了大约30秒...因此,可以想象缺少的点数。

 
Alexey Kozitsyn:

我们与服务台的对话。

在OnCalculate中跳过刻度
开放, 开始时间: 2017.05.22 14:52, #1751442

看好不要迷失方向:https://www.mql5.com/ru/forum/190129/page8#comment_5081300 和 接下来的2个帖子。

来自指标的CopyTicks给出了一个指标在OnCalculate中没有得到的tick(无论是之前还是之后)。

支持团队2017.05.23 09:44
状态:未处理已打开
你的申请已被接受审查。
支持团队2017.05.23 09:46

OnCalculate在每个tick上被调用。

在一个单独的线程中,蜱虫被添加到数据库。也就是说,是异步的。使用CopyTicks,你会得到与调用OnCalculate相同的tick,这并不是事实。

Andrey Khatimlianskii 2017.05.23 14:08

这与此无关。

有了CopyTicks,就有可能得到一个tick,而这个tick并不在OnCalculate中(我们在OnCalculate中了解到的是一个tick,它的时间比错过的要长)。

看看这些日志吧。

支持团队2017.05.23 14:13

这正是我们正在谈论的问题。

一批蜱虫到来。两个线程开始处理这个数据包--一个线程在循环中对数据包中的每个tick执行OnCalculate;另一个线程将整个数据包放入tick数据库。这两个线程之间没有任何同步,不知道哪个线程会更快地处理一包ticks

Andrey Khatimlianskii 2017.05.23 14:26

但是,每一个来自包的勾都应该由OnCalculate来处理。而这并没有发生。

这段时间没有打勾。有一个时间较短的勾,也有一个时间较长的勾。而且中间没有调用OnCalculate。

支持团队2017.05.23 14:33

小册子

但是数据包中的每一个刻度都必须由OnCalculate来处理。而这并没有发生。

这段时间没有打勾。有一个时间较短的勾,也有一个时间较长的勾。而且它们之间没有调用OnCalculate。

在OnCalculate时,数据包中的每个勾都会被处理。那里没有跳线。循环是这样写的。

要想知道OnCalculate中处理的是哪个tick,请使用SymbolInfoTick--这里一切都很清楚。勾选被应用于符号信息,然后这个符号的所有指标被调用,都在一个线程中进行

Andrey Khatimlianskii 2017.05.23 14:36

请看一下链接中的日志。

来自OnCalculate的SymbolInfoTick没有看到tick,这可以从CopyTicks获得。

这就是为什么我写道

支持团队2017.05.23 14:40

我们需要完全按照你在https://www.mql5.com/ru/forum/190129/page8#comment_5082755 中的建议做。

为了确定(测试OnCalculate而不是OnBookEvent和CopyTicks,按原定计划),我只留下OnCalculate被调用时向文件写入ticks的情况。

然后通过脚本会生成同样的文件,通过CopyTicks获得ticks。差异会更明显,并表明在OnCalculate中跳过了刻度,或者CopyTicks的工作不正确。

而我们正是以这种方式在一次检查CopyTicks的正确性。测试脚本和指标已经留下,我们将再次检查。

 

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

虫子,虫子,问题

fxsaber, 2017.02.07 13:41

指标中的SymbolInfoTick与EA的工作方式完全不同。

在一个指标中,它总是返回作为OnCalculate调用发起者的tick。而指标中的这些启动点不应该被跳过--这是开发者的意识形态。问题是在形成这些小数点的队列中。

在专家顾问中,OnTick中的SymbolInfoTick并不返回启动OnTick调用的tick,而是对当前状态进行完整的请求。

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

mql5语言的特点、微妙之处以及技巧

fxsaber, 2017.03.29 22:32

计算事件是在每一个刻度 上产生的。因此,有一个指标的勾选队列。如果达到一定的数字,日志中就会有一个警告,说明指标太慢。

条形图本身的性质是指标,是由计算-事件产生的。因此,如果TF M1是10:15:00.020,一个50ms的数据包来了,它的第一个刻度仍然有时间10:14:59.970。而所有的指标都会在这个计算事件中被首先调用--首先是时间序列指标,然后是带有这些时间序列的自定义指标。也就是说,在这个布局中,10:15-条还没有形成零条。而零条是10:14。


然后,当数据包开始通过计算事件解开时,10:15-条也会出现。我想我已经详细地描述了它。

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

mql5语言的特点、微妙之处以及技巧

fxsaber, 2017.03.29 22:41

因此,对于一个EA来说,收到一个尚未形成的条形图的刻度是很正常的。但这是一个非常微妙的观点,甚至需要努力去故意重现。一般来说,它的理论性比实践性更强。


如果我们对速度有偏执 ,那么使用指示器(当然还有栏杆)就不是一种选择。一切都在EA中。

 
Andrey Khatimlianskii:

我们与服务台的对话。

不幸的是,服务台就在他们的剧目中。在讨论时,他们不需要抛出一个链接。但要举一个具体的例子,在他们的手指上。这不是他们在谈论的问题。也就是说,他们说,SymbolInfoTick()返回要检查的当前刻度,由于OnCalculate()处理每个刻度--事实证明,输出应该是每个刻度的。而CopyTicks()却告诉我们不是这样。嗯...他们说,不要看CopyTicks():)。大约有两个线程,他们也解释过我,当他们在年底修复CopyTicks()时。只是它不是这里的问题(虽然,也许在里面也有,我不知道)。

没有问过他们关于从OnBookEvent()收到的带有0标志的ticks吗?