CopyTicks

该函数以 MqlTick 格式接收报价到ticks_array。 在这种情况下,从过去到现在索引报价,例如0号报价是数组中最早的报价。对于报价分析,请检查flags 字段,它会显示报价中实际变化的内容。

int  CopyTicks(
   string           symbol_name,           // 交易品种名称
   MqlTick&         ticks_array[],         // 报价接收数组
   uint             flags=COPY_TICKS_ALL,  // 决定接收报价类型的标记
   ulong            from=0,                // 您想请求报价的日期
   uint             count=0                // 您想接收报价的数量
   );

参数

symbol_name

[in]  交易品种。

ticks_array

[out]  接收报价MqlTick 类型的数组。

flags

[in]  确定请求报价类型的标记。COPY_TICKS_INFO – 卖价和/或买价变化的报价, COPY_TICKS_TRADE – 最后价和交易量变化的报价, COPY_TICKS_ALL – 全部报价。对于任何请求类型,之前的报价值添加到其余的MqlTick结构的字段。

from

[in]   您想请求报价的开始日期。从1970.01.01开始以毫秒计算。如果from=0,将返回最近的count 报价。

count

[in]  请求报价的数量。如果没有指定'from' 和 'count' 参数,所有可用的现有报价(不超过2000)将被写入ticks_array[]。

返回值

复制报价的数量或错误情况下的-1。

进一步注释

CopyTicks() 函数允许请求和分析所有接收的报价。第一次调用CopyTicks() 即开始同步硬盘上存储的交易品种报价数据库。如果本地数据库没有提供所有请求的报价,那么丢失的报价将会自动从交易服务器下载。从CopyTicks()指定的from 开始日期直到当前时刻的报价将会同步。在那之后,到达该交易品种的所有报价将被添加到报价数据库,因此保持同步状态。

如果没有指定fromcount 参数,所有可用的现有报价(不超过2000)将被写入ticks_array[]flags 参数允许指定所需报价类型。

COPY_TICKS_INFO – 返回卖价和/或买价变化的报价。其他字段的数据也将被添加。例如,如果只有卖价改变,买价交易量 字段将填写最近得知的值。若要找出实际变化的内容,请分析具有TICK_FLAG_BID和/或TICK_FLAG_ASK值的flags字段。如果报价有零值的卖价和买价,那么标记会显示这些数据已经更改(flags=TICK_FLAG_BID|TICK_FLAG_ASK),这意味着订单簿 (市场深度) 为空。换句话说,没有买入和卖出订单。

COPY_TICKS_TRADE – 返回最后价和交易量变化的报价。其他字段的数据也将被添加,例如最近得到的卖价和买价值将在适当字段指明。若要找出实际变化的内容,请分析具有TICK_FLAG_LAST 和 TICK_FLAG_VOLUME值的flags 字段。

COPY_TICKS_ALL – 返回任何变化的所有报价。未改变的字段将会填写最近得到的值。

调用COPY_TICKS_ALL标记的CopyTicks() 立即返回请求间隔的全部报价,而其他模式的调用则需要一定的时间来处理和选择报价,因此它们不提供显著的速度优势。

请求报价时 (既有 COPY_TICKS_INFO 还有 COPY_TICKS_TRADE),每个报价都包括直至报价时间为止的完整的价格信息(卖价,买价,最后价 交易量)。该功能主要用于更轻松的分析每次报价时的交易状态,所以不需要请求深度报价历史和搜索其他字段的值。

在指标中,CopyTicks() 函数返回结果: 从指标调用时,CopyTick() 立即返回交易品种的所有可用报价,并且如果可用数据不足时,将启动同步报价数据库。一个交易品种的所有指标在一个常见线程中运行,所有指标不会等候同步完成。同步之后,CopyTicks() 将返回下次调用期间所有的请求报价。在指标中,每次报价到达之后都会调用OnCalculate() 函数。

CopyTicks() 可以等候45秒来等待EA交易和脚本的结果: 不同于指标,每个EA交易和脚本都在独立的线程中运行,因此可以等待45秒,直到同步完成。如果所需的报价数在此期间同步失败,那么CopyTicks() 将通过timeout返回可用报价并将继续同步。EA交易中的OnTick() 并不是每个报价处理程序,它仅通知EA交易有关市场中的变化。如果产生大量变化:程序端可以同时做出几个报价,但是OnTick() 将只能调用一次来通知EA最新市场状态。

数据返回速度: 每个工具,程序端可以存储快速访问缓存4096个最新报价(运行市场深度,是65536个报价用于交易品种。如果当前交易期请求的报价超出了缓存,CopyTicks() 则会调用存储在程序端内存的报价。这些请求需要更多的执行时间。最慢的请求就是那些其他日期的请求报价,因为在这种情况下从磁盘读取数据。

例如:

#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
//--- Requesting 100 million ticks to be sure we receive the entire tick history
input int      getticks=100000000; // The number of required ticks
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---  
   int     attempts=0;     // Count of attempts
   bool    success=false;  // The flag of a successful copying of ticks
   MqlTick tick_array[];   // Tick receiving array
   MqlTick lasttick;       // To receive last tick data
   SymbolInfoTick(_Symbol,lasttick);
//--- Make 3 attempts to receive ticks
   while(attempts<3)
     {
      //--- Measuring start time before receiving the ticks
      uint start=GetTickCount();
//--- Requesting the tick history since 1970.01.01 00:00.001 (parameter from=1 ms)
      int received=CopyTicks(_Symbol,tick_array,COPY_TICKS_ALL,1,getticks);
      if(received!=-1)
        {
         //--- Showing information about the number of ticks and spent time
         PrintFormat("%s: received %d ticks in %d ms",_Symbol,received,GetTickCount()-start);
         //--- If the tick history is synchronized, the error code is equal to zero
         if(GetLastError()==0)
           {
            success=true;
            break;
           }
         else
            PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d",
            _Symbol,received,GetTickCount()-start,_LastError);
        }
      //--- Counting attempts
      attempts++;
      //--- A one-second pause to wait for the end of synchronization of the tick database
      Sleep(1000);
     }
//--- Receiving the requested ticks from the beginning of the tick history failed in three attempts
   if(!success)
     {
      PrintFormat("Error! Failed to receive %d ticks of %s in three attempts",getticks,_Symbol);
      return;
     }
   int ticks=ArraySize(tick_array);
//--- Showing the time of the first tick in the array
   datetime firstticktime=tick_array[ticks-1].time;
   PrintFormat("Last tick time = %s.%03I64u",
               TimeToString(firstticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[ticks-1].time_msc%1000);
//--- выведем время последнего тика в массиве
   datetime lastticktime=tick_array[0].time;
   PrintFormat("First tick time = %s.%03I64u",
               TimeToString(lastticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[0].time_msc%1000);
 
//---                                                           
   MqlDateTime today;
   datetime current_time=TimeCurrent();                         
   TimeToStruct(current_time,today);                            
   PrintFormat("current_time=%s",TimeToString(current_time));   
   today.hour=0;
   today.min=0;
   today.sec=0;
   datetime startday=StructToTime(today);
   datetime endday=startday+24*60*60;
   if((ticks=CopyTicksRange(_Symbol,tick_array,COPY_TICKS_ALL,startday*1000,endday*1000))==-1) 
     {
      PrintFormat("CopyTicksRange(%s,tick_array,COPY_TICKS_ALL,%s,%s) failed, error %d",       
                  _Symbol,TimeToString(startday),TimeToString(endday),GetLastError());          
      return;                                                                                  
     }
   ticks=MathMax(100,ticks);
//--- Showing the first 100 ticks of the last day
   int counter=0;
   for(int i=0;i<ticks;i++)
     {
      datetime time=tick_array[i].time;
      if((time>=startday) && (time<endday) && counter<100)
        {
         counter++;
         PrintFormat("%d. %s",counter,GetTickDescription(tick_array[i]));
        }
     }
//--- Showing the first 100 deals of the last day
   counter=0;
   for(int i=0;i<ticks;i++)
     {
      datetime time=tick_array[i].time;
      if((time>=startday) && (time<endday) && counter<100)
        {
         if(((tick_array[i].flags&TICK_FLAG_BUY)==TICK_FLAG_BUY) || ((tick_array[i].flags&TICK_FLAG_SELL)==TICK_FLAG_SELL))
           {
            counter++;
            PrintFormat("%d. %s",counter,GetTickDescription(tick_array[i]));
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Returns the string description of a tick                         |
//+------------------------------------------------------------------+
string GetTickDescription(MqlTick &tick)
  {
   string desc=StringFormat("%s.%03d ",
                            TimeToString(tick.time),tick.time_msc%1000);
//--- Checking flags
   bool buy_tick=((tick.flags&TICK_FLAG_BUY)==TICK_FLAG_BUY);
   bool sell_tick=((tick.flags&TICK_FLAG_SELL)==TICK_FLAG_SELL);
   bool ask_tick=((tick.flags&TICK_FLAG_ASK)==TICK_FLAG_ASK);
   bool bid_tick=((tick.flags&TICK_FLAG_BID)==TICK_FLAG_BID);
   bool last_tick=((tick.flags&TICK_FLAG_LAST)==TICK_FLAG_LAST);
   bool volume_tick=((tick.flags&TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME);
//--- Checking trading flags in a tick first
   if(buy_tick || sell_tick)
     {
      //--- Forming an output for the trading tick
      desc=desc+(buy_tick?StringFormat("Buy Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
      desc=desc+(sell_tick?StringFormat("Sell Tick: Last=%G Volume=%d ",tick.last,tick.volume):"");
      desc=desc+(ask_tick?StringFormat("Ask=%G ",tick.ask):"");
      desc=desc+(bid_tick?StringFormat("Bid=%G ",tick.ask):"");
      desc=desc+"(Trade tick)";
     }
   else
     {
      //--- Form a different output for an info tick
      desc=desc+(ask_tick?StringFormat("Ask=%G ",tick.ask):"");
      desc=desc+(bid_tick?StringFormat("Bid=%G ",tick.ask):"");
      desc=desc+(last_tick?StringFormat("Last=%G ",tick.last):"");
      desc=desc+(volume_tick?StringFormat("Volume=%d ",tick.volume):"");
      desc=desc+"(Info tick)";
     }
//--- Returning tick description
   return desc;
  }
//+------------------------------------------------------------------+
/* Example of the output
Si-12.16: received 11048387 ticks in 4937 ms
Last tick time = 2016.09.26 18:32:59.775 
First tick time = 2015.06.18 09:45:01.000 
1.  2016.09.26 09:45.249 Ask=65370 Bid=65370 (Info tick)
2.  2016.09.26 09:47.420 Ask=65370 Bid=65370 (Info tick)
3.  2016.09.26 09:50.893 Ask=65370 Bid=65370 (Info tick)
4.  2016.09.26 09:51.827 Ask=65370 Bid=65370 (Info tick)
5.  2016.09.26 09:53.810 Ask=65370 Bid=65370 (Info tick)
6.  2016.09.26 09:54.491 Ask=65370 Bid=65370 (Info tick)
7.  2016.09.26 09:55.913 Ask=65370 Bid=65370 (Info tick)
8.  2016.09.26 09:59.350 Ask=65370 Bid=65370 (Info tick)
9.  2016.09.26 09:59.678 Bid=65370 (Info tick)
10. 2016.09.26 10:00.000 Sell Tick: Last=65367 Volume=3 (Trade tick)
11. 2016.09.26 10:00.000 Sell Tick: Last=65335 Volume=45 (Trade tick)
12. 2016.09.26 10:00.000 Sell Tick: Last=65334 Volume=95 (Trade tick)
13. 2016.09.26 10:00.191 Sell Tick: Last=65319 Volume=1 (Trade tick)
14. 2016.09.26 10:00.191 Sell Tick: Last=65317 Volume=1 (Trade tick)
15. 2016.09.26 10:00.191 Sell Tick: Last=65316 Volume=1 (Trade tick)
16. 2016.09.26 10:00.191 Sell Tick: Last=65316 Volume=10 (Trade tick)
17. 2016.09.26 10:00.191 Sell Tick: Last=65315 Volume=5 (Trade tick)
18. 2016.09.26 10:00.191 Sell Tick: Last=65313 Volume=3 (Trade tick)
19. 2016.09.26 10:00.191 Sell Tick: Last=65307 Volume=25 (Trade tick)
20. 2016.09.26 10:00.191 Sell Tick: Last=65304 Volume=1 (Trade tick)
21. 2016.09.26 10:00.191 Sell Tick: Last=65301 Volume=1 (Trade tick)
22. 2016.09.26 10:00.191 Sell Tick: Last=65301 Volume=10 (Trade tick)
23. 2016.09.26 10:00.191 Sell Tick: Last=65300 Volume=5 (Trade tick)
24. 2016.09.26 10:00.191 Sell Tick: Last=65300 Volume=1 (Trade tick)
25. 2016.09.26 10:00.191 Sell Tick: Last=65300 Volume=6 (Trade tick)
26. 2016.09.26 10:00.191 Sell Tick: Last=65299 Volume=1 (Trade tick)
27. 2016.09.26 10:00.191 Bid=65370 (Info tick)
28. 2016.09.26 10:00.232 Ask=65297 (Info tick)
29. 2016.09.26 10:00.276 Sell Tick: Last=65291 Volume=31 (Trade tick)
30. 2016.09.26 10:00.276 Sell Tick: Last=65290 Volume=1 (Trade tick)
*/

另见

SymbolInfoTick当前价格的结构OnTick()