CustomTicksAdd

MqlTick 유형의 배열에 있는 데이터를 사용자 지정 심볼의 가격 내역에 추가. 종합 시세 창에서 사용자 지정 심볼을 선택해야 합니다.

int  CustomTicksAdd(
   const string     symbol,             // 심볼 이름
   const MqlTick&   ticks[],            // 사용자 지정 심볼에 적용해야 하는 틱 데이터가 있는 배열
   uint             count=WHOLE_ARRAY   // 사용할 ticks[] 배열 요소의 수
   );

매개변수

심볼

[in]  사용자 지정 심볼의 이름.

ticks[]

[in]   MqlTick 유형의 틱 데이터 배열은 이전 데이터에서 최근 데이터까지 시간 순서대로 배열됩니다, 예를 들면 ticks[k].time_msc <= ticks[n].time_msc, if k<n.

count=WHOLE_ARRAY

[in]  추가하는데 사용할 ticks[] 배열 요소의 수. WHOLE_ARRAY 는 모든 ticks[] 배열 요소를 사용해야 함을 의미합니다.

값 반환

오류가 발생한 경우 추가된 틱 수 또는 -1.

추가 참고

CustomTicksAdd 기능은 종합 시세 창에 열린 사용자 지정 심볼에 대해서만 작동합니다. 종합 시세(Market Watch)에서 심볼이 선택되지 않은 경우, CustomTicksReplace을 사용하여 틱을 추가해야 합니다.

CustomTicksAdd 기능을 통해 브로커의 서버에서 제공된 것처럼 틱을 전송할 수 있습니다. 데이터는 체크 표시 데이터베이스에 직접 기록되지 않고 종합 시세(Market Watch) 창으로 전송됩니다. 그런 다음 종합 시세의 틱을 데이터베이스에 저장합니다. 한 함수 호출 중에 전송되는 데이터 양이 많으면 리소스 사용을 줄이기 위해 함수 동작이 변경됩니다. 256개 이상의 틱이 통과되면 데이터가 두 부분으로 나뉩니다. 첫 번째, 즉 큰 부분은 CustomTicksReplace에서 수행한 것 처럼 틱 데이터베이스에 직접 기록됩니다. 128개의 틱이 포함된 두 번째 부분은 종합 시세 창으로 전달되며, 이 창에서 터미널은 틱을 데이터베이스에 저장합니다.

MqlTick 구조에는 시간 값(초 단위의 눈금 시간)과 1970년 1월 1일부터 카운트되는 time_msc (밀리초 단위의 눈금 시간)의 두 필드가 있습니다. 추가된 틱의 이러한 필드는 다음 순서로 처리됩니다.

  1. ticks[k].time_msc!=0인 경우, ticks[k].time 필드를 채우는데 사용하며, 예를 들어 틱에 대해 ticks[k].time=ticks[k].time_msc/1000 (정수 부분)이 설정
  2. ticks[k].time_msc==0 이고 ticks[k].time!=0인 경우, 밀리초 단위의 시간은 1000을 곱하여 얻습니다, 예를 들어 ticks[k].time_msc=ticks[k].time*1000
  3. ticks[k].time_msc==0 이고 ticks[k].time==0인 경우, 현재 거래 서버 시간은 CustomTicksAdd 호출 시점 현재 밀리초까지 이 필드에 기록됩니다.

ticks[k].bid, ticks[k].ask, ticks[k].last 또는 ticks[k].volume의 값이 0보다 크면 적절한 플래그 조합이 ticks[k].flags 필드에 기록됩니다:

  • TICK_FLAG_BID – 틱이 입찰 가격을 변경했습니다
  • TICK_FLAG_ASK  – 틱이 요청 가격을 변경했습니다
  • TICK_FLAG_LAST – 틱이 마지막 거래 가격을 변경했습니다
  • TICK_FLAG_VOLUME – 틱이 볼륨을 변경했습니다

필드 값이 0보다 작거나 같으면 해당 플래그가 ticks[k].flags 필드에 기록되지 않습니다.

 

TICK_FLAG_BUY 및 TICK_FLAG_SELL 플래그는 사용자 지정 심볼의 기록에 추가되지 않습니다.

 

예:

//+------------------------------------------------------------------+
//|                                               CustomTicksAdd.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#define   CUSTOM_SYMBOL_NAME     Symbol()+".C"     // 사용자 지정 심볼명
#define   CUSTOM_SYMBOL_PATH     "Forex"           // 심볼을 생성할 그룹 명
#define   CUSTOM_SYMBOL_ORIGIN   Symbol()          // 사용자 정의 심볼의 기반이 되는 심볼 명
 
#define   DATATICKS_TO_COPY      UINT_MAX          // 복사 되는 틱의 수
#define   DATATICKS_TO_PRINT     20                // 저널에 보내진 틱의 수
 
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 사용자 정의 심볼을 생성할 때 오류 코드를 가져옵니다.
   int create=CreateCustomSymbol(CUSTOM_SYMBOL_NAMECUSTOM_SYMBOL_PATHCUSTOM_SYMBOL_ORIGIN);
   
//--- 오류 코드가 0(심볼 생성 성공)도 아니고 5304(심볼이 이미 생성됨)도 아닌 경우 - 그대로 둠
   if(create!=0 && create!=5304)
      return;
 
//--- 표준 심볼 틱 데이터를 MqlTick 배열로 가져옵니다.
   MqlTick array[]={};
   if(!GetTicksToArray(CUSTOM_SYMBOL_ORIGINDATATICKS_TO_COPYarray))
      return;
   
//--- 표준 심볼의 첫 번째 및 마지막 수신 틱 시간을 출력합니다.
   int total=(int)array.Size();
   PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
               TimeToString(array[0].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
               TimeToString(array[total-1].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
               
//--- 저널에 있는 표준 심볼의 마지막 틱 DATATICKS_TO_PRINT를 출력합니다.
   PrintFormat("\nThe last %d ticks for the standard symbol '%s':"DATATICKS_TO_PRINTCUSTOM_SYMBOL_ORIGIN);
   for(int i=total-DATATICKS_TO_PRINTi<totali++)
     {
      if(i<0)
         continue;
      PrintFormat("  %dth Tick: %s"iGetTickDescription(array[i]));
     }
   
//--- 종합 시세 창에 사용자 정의 심볼을 추가합니다.
   ResetLastError();
   if(!SymbolSelect(CUSTOM_SYMBOL_NAMEtrue))
     {
      Print("SymbolSelect() failed. Error "GetLastError());
      return;
     }
     
//--- 사용자 지정 심볼 가격 히스토리에 틱 배열 데이터를 추가합니다.
   Print("...");
   uint start=GetTickCount();
   PrintFormat("Start of adding %u ticks to the history of the custom symbol '%s'"array.Size(), CUSTOM_SYMBOL_NAME);
   int added=CustomTicksAdd(CUSTOM_SYMBOL_NAMEarray);
   PrintFormat("Added %u ticks to the history of the custom symbol '%s' in %u ms"addedCUSTOM_SYMBOL_NAMEGetTickCount()-start);
   
//--- 사용자 정의 심볼 틱 데이터를 MqlTick 배열로 가져옵니다.
   Print("...");
   if(!GetTicksToArray(CUSTOM_SYMBOL_NAMEarray.Size(), array))
      return;
   
//--- 사용자 정의 심볼의 첫 번째 및 마지막 수신 틱 시간을 출력합니다.
   total=(int)array.Size();
   PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
               TimeToString(array[0].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
               TimeToString(array[total-1].timeTIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
               
//--- 저널에 있는 사용자 정의 심볼의 마지막 틱 DATATICKS_TO_PRINT를 출력합니다.
   PrintFormat("\nThe last %d ticks for the custom symbol '%s':"DATATICKS_TO_PRINTCUSTOM_SYMBOL_NAME);
   for(int i=total-DATATICKS_TO_PRINTi<totali++)
     {
      if(i<0)
         continue;
      PrintFormat("  %dth Tick: %s"iGetTickDescription(array[i]));
     }
 
//--- 차트 주석에 스크립트 종료 키에 대한 힌트를 표시합니다.
   Comment(StringFormat("Press 'Esc' to exit or 'Del' to delete the '%s' symbol and exit"CUSTOM_SYMBOL_NAME));
//--- Esc 또는 Del 키를 눌러 무한 루프를 종료할 때까지 기다립니다.
   while(!IsStopped() && TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE)==0)
     {
      Sleep(16);
//--- Del 키를 누르면 생성된 사용자 정의 심볼 및 해당 데이터가 삭제됩니다.
      if(TerminalInfoInteger(TERMINAL_KEYSTATE_DELETE)<0)
        {
//--- 바 데이터 삭제
         int deleted=CustomRatesDelete(CUSTOM_SYMBOL_NAME0LONG_MAX);
         if(deleted>0)
            PrintFormat("%d history bars of the custom symbol '%s' were successfully deleted"deletedCUSTOM_SYMBOL_NAME);
         
         //--- 틱 데이터 삭제
         deleted=CustomTicksDelete(CUSTOM_SYMBOL_NAME0LONG_MAX);
         if(deleted>0)
            PrintFormat("%d history ticks of the custom symbol '%s' were successfully deleted"deletedCUSTOM_SYMBOL_NAME);
         
         //--- 심볼 삭제
         if(DeleteCustomSymbol(CUSTOM_SYMBOL_NAME))
            PrintFormat("Custom symbol '%s' deleted successfully"CUSTOM_SYMBOL_NAME);
         break;
        }
     }
//--- 종료하기 전에 차트를 삭제
   Comment("");
   /*
   결과:
   Requested 4294967295 ticks to download tick history for the symbol 'EURUSD'
   The tick history for the 'EURUSDsymbol is received in the amount of 351183943 ticks in 56454 ms
   First tick time2011.12.19 00:00:08.000Last tick time2024.06.20 21:18:12.010
   
   The last 20 ticks for the standard symbol 'EURUSD':
     351183923th Tick2024.06.20 21:17:46.380 Bid=1.07124 (Info tick)
     351183924th Tick2024.06.20 21:17:47.779 Ask=1.07125 Bid=1.07125 (Info tick)
     351183925th Tick2024.06.20 21:17:48.584 Ask=1.07124 Bid=1.07124 (Info tick)
     351183926th Tick2024.06.20 21:17:49.481 Ask=1.07125 (Info tick)
     351183927th Tick2024.06.20 21:17:49.985 Ask=1.07122 Bid=1.07122 (Info tick)
     351183928th Tick2024.06.20 21:17:50.482 Ask=1.07124 Bid=1.07124 (Info tick)
     351183929th Tick2024.06.20 21:17:51.584 Ask=1.07123 Bid=1.07123 (Info tick)
     351183930th Tick2024.06.20 21:17:52.786 Ask=1.07124 Bid=1.07124 (Info tick)
     351183931th Tick2024.06.20 21:17:53.487 Ask=1.07125 Bid=1.07125 (Info tick)
     351183932th Tick2024.06.20 21:17:53.989 Ask=1.07126 Bid=1.07126 (Info tick)
     351183933th Tick2024.06.20 21:17:55.789 Ask=1.07125 Bid=1.07125 (Info tick)
     351183934th Tick2024.06.20 21:17:58.495 Ask=1.07126 Bid=1.07126 (Info tick)
     351183935th Tick2024.06.20 21:18:00.102 Bid=1.07126 (Info tick)
     351183936th Tick2024.06.20 21:18:00.698 Ask=1.07129 Bid=1.07129 (Info tick)
     351183937th Tick2024.06.20 21:18:03.699 Bid=1.07129 (Info tick)
     351183938th Tick2024.06.20 21:18:04.699 Ask=1.07128 Bid=1.07128 (Info tick)
     351183939th Tick2024.06.20 21:18:05.901 Ask=1.07129 Bid=1.07129 (Info tick)
     351183940th Tick2024.06.20 21:18:07.606 Ask=1.07128 Bid=1.07128 (Info tick)
     351183941th Tick2024.06.20 21:18:11.512 Ask=1.07127 Bid=1.07127 (Info tick)
     351183942th Tick2024.06.20 21:18:12.010 Ask=1.07126 Bid=1.07126 (Info tick)
   ...
   Start of adding 351183943 ticks to the history of the custom symbol 'EURUSD.C'
   Added 351183943 ticks to the history of the custom symbol 'EURUSD.Cin 269890 ms
   ...
   Requested 351183943 ticks to download tick history for the symbol 'EURUSD.C'
   The tick history for the 'EURUSD.Csymbol is received in the amount of 351183943 ticks in 116407 ms
   First tick time2011.12.19 00:00:08.000Last tick time2024.06.20 21:18:12.010
   
   The last 20 ticks for the custom symbol 'EURUSD.C':
     351183923th Tick2024.06.20 21:17:46.380 Ask=1.07124 Bid=1.07124 (Info tick)
     351183924th Tick2024.06.20 21:17:47.779 Ask=1.07125 Bid=1.07125 (Info tick)
     351183925th Tick2024.06.20 21:17:48.584 Ask=1.07124 Bid=1.07124 (Info tick)
     351183926th Tick2024.06.20 21:17:49.481 Ask=1.07125 Bid=1.07125 (Info tick)
     351183927th Tick2024.06.20 21:17:49.985 Ask=1.07122 Bid=1.07122 (Info tick)
     351183928th Tick2024.06.20 21:17:50.482 Ask=1.07124 Bid=1.07124 (Info tick)
     351183929th Tick2024.06.20 21:17:51.584 Ask=1.07123 Bid=1.07123 (Info tick)
     351183930th Tick2024.06.20 21:17:52.786 Ask=1.07124 Bid=1.07124 (Info tick)
     351183931th Tick2024.06.20 21:17:53.487 Ask=1.07125 Bid=1.07125 (Info tick)
     351183932th Tick2024.06.20 21:17:53.989 Ask=1.07126 Bid=1.07126 (Info tick)
     351183933th Tick2024.06.20 21:17:55.789 Ask=1.07125 Bid=1.07125 (Info tick)
     351183934th Tick2024.06.20 21:17:58.495 Ask=1.07126 Bid=1.07126 (Info tick)
     351183935th Tick2024.06.20 21:18:00.102 Ask=1.07126 Bid=1.07126 (Info tick)
     351183936th Tick2024.06.20 21:18:00.698 Ask=1.07129 Bid=1.07129 (Info tick)
     351183937th Tick2024.06.20 21:18:03.699 Ask=1.07129 Bid=1.07129 (Info tick)
     351183938th Tick2024.06.20 21:18:04.699 Ask=1.07128 Bid=1.07128 (Info tick)
     351183939th Tick2024.06.20 21:18:05.901 Ask=1.07129 Bid=1.07129 (Info tick)
     351183940th Tick2024.06.20 21:18:07.606 Ask=1.07128 Bid=1.07128 (Info tick)
     351183941th Tick2024.06.20 21:18:11.512 Ask=1.07127 Bid=1.07127 (Info tick)
     351183942th Tick2024.06.20 21:18:12.010 Ask=1.07126 Bid=1.07126 (Info tick)
   */
  }
//+------------------------------------------------------------------+
//| 사용자 지정 심볼 생성, 에러 코드 반환                |
//+------------------------------------------------------------------+
int CreateCustomSymbol(const string symbol_nameconst string symbol_pathconst string symbol_origin=NULL)
  {
//--- 사용자 정의 심볼의 기반이 될 심볼명을 정의합니다.
   string origin=(symbol_origin==NULL ? Symbol() : symbol_origin);
   
//--- 사용자 정의 심볼 생성에 실패했고 오류 5304가 아닌 경우 저널에 이를 보고합니다.
   ResetLastError();
   int error=0;
   if(!CustomSymbolCreate(symbol_namesymbol_pathorigin))
     {
      error=GetLastError();
      if(error!=5304)
         PrintFormat("CustomSymbolCreate(%s, %s, %s) failed. Error %d"symbol_namesymbol_pathoriginerror);
     }
//--- 성공
   return(error);
  }
//+------------------------------------------------------------------+
//| 사용자 정의 심볼 삭제                                           |
//+------------------------------------------------------------------+
bool DeleteCustomSymbol(const string symbol_name)
  {
//--- 종합시세 창에서 심볼 숨기기
   ResetLastError();
   if(!SymbolSelect(symbol_namefalse))
     {
      PrintFormat("SymbolSelect(%s, false) failed. Error %d"GetLastError());
      return(false);
     }
      
//--- 사용자 정의 심볼 삭제에 실패한 경우 이를 저널에 보고하고 'false'를 반환합니다.
   ResetLastError();
   if(!CustomSymbolDelete(symbol_name))
     {
      PrintFormat("CustomSymbolDelete(%s) failed. Error %d"symbol_nameGetLastError());
      return(false);
     }
//--- 성공
   return(true);
  }
//+------------------------------------------------------------------+
//| 배열에서 지정된 틱 수를 가져옵니다.                   |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbolconst uint countMqlTick &array[])
  {
//--- 히스토리 데이터 로딩의 시작을 알립니다.
   PrintFormat("Requested %u ticks to get tick history for the symbol '%s'"countsymbol);
   
//--- 틱 수신을 위해 3번 시도합니다.
   int attempts=0;
   while(attempts<3)
     {
      //--- 틱을 받기 전에 시작 시간을 측정합니다.
      uint start=GetTickCount();
      
      //--- 1970.01.01 00:00.001 이후의 틱 내역을 요청합니다(매개변수 =1ms)
      int received=CopyTicks(symbolarrayCOPY_TICKS_ALL1count);
      if(received!=-1)
        {
         //--- 틱 수 및 소요 시간에 대한 정보 표시 
         PrintFormat("The tick history for the '%s' symbol is received in the amount of %u ticks in %d ms"symbolreceivedGetTickCount()-start);
         
         //--- 틱 히스토리가 동기화되면 오류 코드는 0과 같습니다. - 'true'를 반환합니다.
         if(GetLastError()==0)
            return(true);
 
         PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d"
                     symbolreceivedGetTickCount()-startGetLastError());
        }
      //--- 카운트 시도
      attempts++; 
      //--- 틱 데이터베이스 동기화가 끝날 때까지 기다리기 위한 1초 일시 중지 
      Sleep(1000);
     }
//--- 3번의 시도에서 틱 복사에 실패했습니다.
   return(false);
  }
//+------------------------------------------------------------------+ 
//| 틱의 문자열 설명을 반환합니다.                          |
//+------------------------------------------------------------------+ 
string GetTickDescription(MqlTick &tick
  { 
   string desc=StringFormat("%s.%03u "TimeToString(tick.timeTIME_DATE|TIME_MINUTES|TIME_SECONDS),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); 
   
//--- 우선 거래 플래그에 대한 체크를 확인하십시오(CustomTicksAdd()에는 플래그가 없습니다).
   if(buy_tick || sell_tick
     { 
      //--- 거래 틱에 대한 출력 형성 
      desc += (buy_tick ? StringFormat("Buy Tick: Last=%G Volume=%d "tick.lasttick.volume)  : ""); 
      desc += (sell_tickStringFormat("Sell Tick: Last=%G Volume=%d ",tick.lasttick.volume) : ""); 
      desc += (ask_tick ? StringFormat("Ask=%G "tick.ask) : ""); 
      desc += (bid_tick ? StringFormat("Bid=%G "tick.ask) : ""); 
      desc += "(Trade tick)"
     } 
   else 
     { 
      //--- 정보 틱에 대한 출력을 약간 다르게 구성 
      desc += (ask_tick   ? StringFormat("Ask=%G ",  tick.ask)    : ""); 
      desc += (bid_tick   ? StringFormat("Bid=%G ",  tick.ask)    : ""); 
      desc += (last_tick  ? StringFormat("Last=%G "tick.last)   : ""); 
      desc += (volume_tickStringFormat("Volume=%d ",tick.volume): ""); 
      desc += "(Info tick)"
     } 
//--- 틱 설명 반환
   return(desc); 
  } 

 

추가 참조

CustomRatesDelete, CustomRatesUpdate, CustomTicksReplace, CopyTicks, CopyTicksRange