CopyTicks

이 함수는 MqlTick ticks_array로의 형태에서 틱을 수신합니다. 이 경우 틱은 과거에서 현재로 인덱싱되며, 즉, 0 인덱스는 배열에서 가장 오래된 틱입니다. 틱 분석을 위해서는 틱에서 정확히 변경된 내용을 보여주는 플래그 필드를 확인하십시오.

int  CopyTicks(
   string           symbol_name,           // 심볼명
   MqlTick&         ticks_array[],         // 배열을 수신하는 틱
   uint             flags=COPY_TICKS_ALL,  // 수신된 틱 유형을 결정하는 플래그
   ulong            from=0,                // 틱 요청 시작일
   uint             count=0                // 수신할 틱 수
   );

Parameters

symbol_name

[in]  심볼.

ticks_array

[out]  틱 수신용 MqlTick 유형의 배열.

flags

[in]  요청된 틱 유형을 정의하는 플래그. COPY_TICKS_INFO – 입찰 및/또는 요청 사항이 있는 틱, COPY_TICKS_TRADE – Last 및 Volume이 변경된 틱, COPY_TICKS_ALL – 모든 틱. 모든 요청 유형의 경우 이전 틱 값이 MqlTick 구조의 나머지 필드에 추가됩니다.

from

[in]   틱 요청 시작일. 1970.01.01 이후 밀리초. from=0이면, 최근 count 틱이 반환됩니다.

count

[in]  요청된 틱 수. 'from' 및 'count' 매개 변수를 지정하지 않으면 사용 가능한 모든 최근 눈금(2000개 이하)이 ticks_array[]에 기록됩니다.

Returned value

오류가 발생한 경우 복사된 틱의 수 또는 -1입니다.

참고

CopyTicks() 함수를 사용하면 수신된 모든 틱을 요청하고 분석할 수 있습니다. CopyTicks()를 처음 호출하면 하드 디스크에 저장된 심볼의 틱 데이터베이스 동기화가 시작됩니다. 로컬 데이터베이스가 요청된 모든 틱을 제공하지 않는 경우 누락된 틱이 트레이드 서버에서 자동으로 다운로드됩니다. CopyTicks()에 지정된 from 날짜부터 시작하여 현재 순간이 동기화될 때까지 체크합니다. 그런 다음 이 심볼에 대해 도착하는 모든 틱이 틱 데이터베이스에 추가되므로 동기화된 상태를 유지합니다.

fromcount 매개 변수를 지정하지 않으면 사용 가능한 모든 최근 틱(2000개 이하)이 ticks_array[]에 기록됩니다. 플래그 매개 변수를 사용하면 필요한 틱 유형을 지정할 수 있습니다.

COPY_TICKS_INFO – 입찰 및/또는 가격 변경이 포함된 틱이 반환됩니다. 다른 필드의 데이터도 추가됩니다. 예를 들어, Bid만 변경된 경우 요청거래량 필드는 마지막으로 알려진 값으로 채워집니다. 변경된 내용을 정확하게 확인하려면 TICK_FLAG_BID 및/또는 TICK_FLAG_ASK 값을 갖는 플래그 필드를 분석합니다. 틱이 입찰 및 청구가격의 값을 0으로 하고 플래그에 해당 데이터가 변경되었음을 나타내는 경우 (플래그=TICK_FLAG_BID|TICK_FLAG_ASK), 이것은 주문장(Market Depth)가 비어 있음을 의미합니다. 다시 말해, 사고파는 주문이 없습니다.

COPY_TICKS_TRADE – 마지막 가격 및 거래량 변경 내용이 포함된 틱이 반환됩니다. 다른 필드의 데이터도 추가됩니다. 즉, 마지막으로 알려진 입찰 및 요청 값이 해당 필드에 지정됩니다. 변경된 내용을 정확하게 확인하려면 TICK_FLAG_LAST 및 TICK_FLAG_VOLUME 값을 갖는 플래그 필드를 분석합니다.

COPY_TICKS_ALL – 변경 내용이 포함된 모든 틱이 반환됩니다. 변경되지 않은 필드는 마지막으로 알려진 값으로 채워집니다.

COPY_TICKS_ALL 플래그가 있는 CopyTicks()를 호출하면 요청 간격에서 모든 틱이 즉시 반환되는 반면, 다른 모드의 호출에서는 틱을 처리하고 선택하는 데 약간의 시간이 필요하므로 속도 이점이 크지 않습니다.

틱 요청시(COPY_TICKS_INFO 또는 COPY_TICKS_TRADE), 모든 틱에는 틱 시간의 전체 가격 정보(입찰, 요청, 최근 거래량)가 포함됩니다. 이 함수는 각 틱의 시점의 거래 상태를 보다 쉽게 분석할 수 있도록 제공되므로, 상세 틱 내역을 요청하거나 다른 필드의 값을 검색할 필요가 없습니다.

지표에서 CopyTicks() 함수는 다음과 같은 결과를 반환합니다: 지표에서 호출되면 CopyTick()은 즉시 심볼의 사용 가능한 모든 틱을 반환하고 사용 가능한 데이터가 충분하지 않은 경우 틱 데이터베이스의 동기화를 시작합니다. 하나의 심볼에 있는 모든 지표는 하나의 공통된 스레드에서 작동하므로 동기화가 완료될 때까지 기다릴 수 없습니다. 동기화 후 CopyTicks()는 다음 호출 중에 요청된 모든 틱을 반환합니다. 지표에서 OnCalculate() 함수는 각 틱이 도착한 후에 호출됩니다.

CopyTicks()는 Expert Advisor 및 스크립트에서 결과를 45초간 기다릴 수 있습니다: 지표와 달리 모든 Expert Advisor와 스크립트는 별도의 스레드로 작동하므로 동기화가 완료될 때까지 45초 동안 기다릴 수 있습니다. 이 시간 동안 필요한 양의 틱이 동기화되지 않으면 CopyTicks()는 시간 초과 시 사용 가능한 틱을 반환하고 동기화를 계속합니다. OnTick()은 모든 틱을 처리하는 것은 아니며 시장의 변화에 대해서만 Expert Advisor에게 알립니다. 이것은 변경 사항 일괄 처리일 수 있습니다: 터미널에서 몇 가지 틱을 동시에 할 수 있지만 OnTick()은 한 번만 호출되어 EA에 최신 마켓의 상태를 알립니다.

데이터 반환 속도: 고속 액세스 캐시에서 각 금융상품당 4,096개의 마지막 틱(Market Depth가 실행 중인 심볼의 경우 65,536개의 틱)에 터미널이 저장됩니다. 현재 거래 세션에 대해 요청된 틱이 캐시를 벗어나면 CopyTicks()가 터미널 메모리에 저장된 틱을 호출합니다. 이러한 요청은 실행하는 데 더 많은 시간이 필요합니다. 이 경우 디스크에서 데이터를 읽기 때문에 다른 날짜에 대해 틱을 요청하는 요청이 가장 느립니다.

예:

#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property script_show_inputs
//--- 전체 틱 기록을 수신하기 위해 1억 개의 틱을 요청합니다
input int      getticks=100000000; // 요청된 틱 수
//+------------------------------------------------------------------+
//| 스크립트 프로그램 시작 함수                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---  
   int     attempts=0;     // 시도 횟수
   bool    success=false;  // 틱 복사에 성공한 플래그
   MqlTick tick_array[];   // 배열을 수신하는 틱
   MqlTick lasttick;       // 마지막 틱 데이터를 수신
   SymbolInfoTick(_Symbol,lasttick);
//--- 틱 수신을 3회 시도
   while(attempts<3)
     {
      //--- 틱 수신 전 시작 시간 측정
      uint start=GetTickCount();
//--- 1970.01.01 00:00.001 이후의 틱 기록 요청(from=1 ms인 매개 변수)
      int received=CopyTicks(_Symbol,tick_array,COPY_TICKS_ALL,1,getticks);
      if(received!=-1)
        {
         //--- 틱 수 및 소요 시간에 대한 정보 표시
         PrintFormat("%s: received %d ticks in %d ms",_Symbol,received,GetTickCount()-start);
         //--- 틱 기록이 동기화되면 오류 코드가 0입니다
         if(GetLastError()==0)
           {
            success=true;
            break;
           }
         else
            PrintFormat("%s: 틱이 아직 동기화되지 않았습니다, %d 개 틱 수신 (%d ms). Error=%d",
            _Symbol,received,GetTickCount()-start,_LastError);
        }
      //--- 시도 횟수 계산
      attempts++;
      //--- 틱 데이터베이스의 동기화가 종료될 때까지 대기하기 위해 1초 일시 중지
      Sleep(1000);
     }
//--- 세 번의 시도 중 틱 기록 시작부터 요청된 틱을 수신하지 못했습니다.
   if(!success)
     {
      PrintFormat("오류! 세 번의 시도 동안 %s 개 중 %d 개 틱 수신 실패",getticks,_Symbol);
      return;
     }
   int ticks=ArraySize(tick_array);
//--- 배열의 첫 번째 틱 시간 표시
   datetime firstticktime=tick_array[ticks-1].time;
   PrintFormat("최근 틱 시간 = %s.%03I64u",
               TimeToString(firstticktime,TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick_array[ticks-1].time_msc%1000);
//--- 배열의 마지막 틱 시간 표시
   datetime lastticktime=tick_array[0].time;
   PrintFormat("첫번째 틱 시간 = %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) 실패, 오류 %d",       
                  _Symbol,TimeToString(startday),TimeToString(endday),GetLastError());          
      return;                                                                                  
     }
   ticks=MathMax(100,ticks);
//--- 마지막 날의 처음 100개 틱 표시
   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]));
        }
     }
//--- 마지막 날의 처음 100개 딜(deal) 표시
   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]));
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| 틱의 문자열 설명을 반환합니다                         |
//+------------------------------------------------------------------+
string GetTickDescription(MqlTick &tick)
  {
   string desc=StringFormat("%s.%03d ",
                            TimeToString(tick.time),tick.time_msc%1000);
//--- 플래그 확인
   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);
//--- 먼저 틱에서 거래 플래그 확인
   if(buy_tick || sell_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
     {
      //--- 정보성 틱을 위해 다른 결과 형성
      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)";
     }
//--- 틱 설명 반환
   return desc;
  }
//+------------------------------------------------------------------+
/* 결과 예시
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, Structure for Current Prices, OnTick()