CopyTicks
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 开始日期直到当前时刻的报价将会同步。在那之后,到达该交易品种的所有报价将被添加到报价数据库,因此保持同步状态。
如果没有指定from 和 count 参数,所有可用的现有报价(不超过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)
*/