ObjectMove

이 함수는 객체의 지정된 앵커 지점의 좌표를 변경합니다.

bool  ObjectMove(
   long      chart_id,        // 차트 식별자
   string    name,            // 오브젝트명
   int       point_index,     // 앵커 포인트 넘버
   datetime  time,            // 시간
   double    price            // 가격
   );

Parameter

chart_id

[in]  차트 식별자. 0은 현재 차트를 의미합니다.

name

[in]  객체명.

point_index

[in]  앵커 포인트 인덱스 앵커 지점의 수는 개체 유형에 따라 다릅니다.

time

[in]  선택한 앵커 지점의 시간 좌표입니다.

price

[in]  선택한 앵커 지점의 가격 좌표입니다.

반환값

명령이 지정한 차트의 대기열에 성공적으로 추가되면 함수가 true를 반환하고, 그렇지 않으면 false를 반환합니다.

참고

비동기 호출은 항상 ObjectMove()에 사용되므로 함수는 명령을 차트 대기열에 추가한 결과만 반환합니다. 이 경우 true는 명령이 성공적으로 대기열에 올랐지만 실행 결과를 알 수 없음을 의미합니다.

명령 실행 결과를 확인하려면 ObjectGetXXX와 같은 개체 속성을 요청하는 함수를 사용할 수 있습니다. 그러나 이러한 기능은 해당 차트의 대기열 끝에 추가되며 동기 호출로 인해 실행 결과를 기다리기 때문에 시간이 많이 걸릴 수 있습니다. 차트에서 많은 개체로 작업할 때는 이 기능을 고려해야 합니다.

 

예:

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#define   OBJ_NAME_ASK     "TestObjectMoveAsk"  // Ask price에 대한 그래픽 객체의 이름
#define   OBJ_NAME_BID     "TestObjectMoveBid"  // Bid price에 대한 그래픽 객체의 이름
#define   COUNT            100000000            // 히스토리에 로드할 틱의 수
#define   DELAY            1                    // 밀리세컨드로 틱 사이의 딜레이 
/+------------------------------------------------------------------+
//| Script program start function                                   |
/+------------------------------------------------------------------+
void OnStart()
  {
//--- 현재 차트 ID, 차트 심볼 및 심볼 Digits
   long   chart_idChartID();
   string symbol  = ChartSymbol(chart_id);
   int    digits  = (int)SymbolInfoInteger(symbolSYMBOL_DIGITS);
   
//--- 차트에 Ask 가격과 Bid 가격을 표시하기 위해 두 개의 가격 레이블을 만듭니다.
   if(!CreatePriceLabel(chart_idtrue) || !CreatePriceLabel(chart_idfalse))
      return;
   
//--- tick을 수신하기 위한 배열
   MqlTick ticks[]={};
   
//--- 차트에서 다음으로 보이는 바의 번호와 이 바가 열리는 시간(밀리초)을 가져옵니다.
   int   first= (int)ChartGetInteger(chart_idCHART_FIRST_VISIBLE_BAR)-1;
   ulong from = GetTime(symbolPERIOD_CURRENTfirst)*1000;
   
//--- 틱 기록을 배열에 로드합니다.
   Print("Started collecting ticks...");
   if(!GetTicksToArray(symbolticks))
      return;
      
//--- 틱 배열을 재설정하고 차트에서 보이는 바의 범위에서 틱을 가져옵니다.
   ZeroMemory(ticks);
   if(CopyTicksRange(symbolticksCOPY_TICKS_INFOfrom)<1)
     {
      PrintFormat("CopyTicksRange() from date %s failed. Error %d"TimeToString(GetTime(symbolPERIOD_CURRENTfirst)), GetLastError());
      return;
     }
   
   Sleep(500);
   PrintFormat("Tick ​​visualization started at %s (%I64u), ticks total: %u"TimeToString(GetTime(symbolPERIOD_CURRENTfirst)), fromticks.Size());
   
   int count=0;                  // 처리된 틱의 수
   int changes=0;                // 처리된 가격 변화의 수
   int total=(int)ticks.Size();  // 틱 배열 사이즈
   
//--- tick 배열을 통한 루프에서
   for(int i=0i<total && !IsStopped(); i++)
     {
//--- 배열에서 틱을 가져와 틱 카운터를 증가시킵니다.
      MqlTick  tick=ticks[i];
      count++;
      
//--- 틱 Ask 및 Bid 플래그를 체크
      bool ask_tick=((tick.flags &TICK_FLAG_ASK)==TICK_FLAG_ASK); 
      bool bid_tick=((tick.flags &TICK_FLAG_BID)==TICK_FLAG_BID); 
      bool done=false;
      
//--- Ask 가격이 변경되면
      if(ask_tick)
        {
         if(Move(chart_idOBJ_NAME_ASKtick.timetick.ask))
           {
            changes++;
            done=true;
           }
        }
//--- Bid 가격이 변경되는 경우
      if(bid_tick)
        {
         if(Move(chart_idOBJ_NAME_BIDtick.timetick.bid))
           {
            changes++;
            done=true;
           }
        }
//--- 그래픽 객체 중 하나(또는 둘 다)가 이동된 경우 차트를 업데이트합니다.
      if(done)
        {
         ChartRedraw(chart_id);
         Sleep(DELAY);
        }
     }
   
//--- 루프가 끝나면 처리된 틱 수를 저널에 보고합니다.
//--- 몇 초간 기다린 후 생성된 객체를 삭제하고 차트를 다시 그립니다.
   PrintFormat("Total ticks completed: %u, Total price changes: %d"countchanges);
   Sleep(2000);
   if(ObjectsDeleteAll(chart_id"TestObjectMove")>0)
      ChartRedraw(chart_id);
   /*
   스크립트 실행의 결과로,Ask 그리고Bid 가격은 현재 보이는 차트에 표시됩니다.
   차트의 왼쪽 가장자리부터 시작하여 과거 데이터의 끝까지
   다음 데이터가 저널에 표시됩니다:
   Started collecting ticks...
   AUDUSDreceived 13726794 ticks in 969 ms
   Tick ​​visualization started at 2025.01.31 09:00 (1738314000000), ticks total44380
   Total ticks completed44380Total price changes68513
   */
  }
/+------------------------------------------------------------------+
//| Create a "Price label" object                                   |
/+------------------------------------------------------------------+
bool CreatePriceLabel(const long chart_idconst bool obj_ask)
  {
   string obj_name=(obj_ask ? OBJ_NAME_ASK : OBJ_NAME_BID);
   ResetLastError();
   if(!ObjectCreate(chart_idobj_name, (obj_ask ? OBJ_ARROW_RIGHT_PRICE : OBJ_ARROW_LEFT_PRICE), 000))
     {
      PrintFormat("%s: ObjectCreate() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   return(ObjectSetInteger(chart_idobj_nameOBJPROP_COLOR, (obj_ask ? clrRed : clrBlue)));
  }
/+------------------------------------------------------------------+
//| 그래픽 객체를 지정된 가격/시간 좌표로 이동합니다.                     |
/+------------------------------------------------------------------+
bool Move(const long chart_idconst string obj_nameconst datetime timeconst double price)
  {
   ResetLastError();
   if(!ObjectSetInteger(chart_idobj_nameOBJPROP_TIMEtime))
     {
      PrintFormat("%s: ObjectSetInteger() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   if(!ObjectSetDouble(chart_idobj_nameOBJPROP_PRICEprice))
     {
      PrintFormat("%s: ObjectSetDouble() failed. Error %d",__FUNCTION__GetLastError());
      return(false);
     }
   return(true);
  }
/+------------------------------------------------------------------+
//| 배열에 ticks 로드                                                 |
/+------------------------------------------------------------------+
bool GetTicksToArray(const string symbolMqlTick &array[])
  {
   int  attempts=0;     // 틱 기록을 얻으려는 시도 카운터
   bool success =false// 성공적으로 틱을 복사한 플래그
   
//--- 틱을 받기 위해 3번 시도합니다.
   while(attempts<3
     {
//--- tick을 받기 전 시작 시간을 측정합니다.
      uint start=GetTickCount();
      
//--- 1970.01.01 00:00.001부터의 틱 기록을 요청합니다(매개변수 시작=1ms)
      ResetLastError();
      int received=CopyTicks(symbolarrayCOPY_TICKS_ALL1COUNT); 
      if(received!=-1
        { 
//--- 틱 수와 소요 시간에 데이터를 표시합니다.
         PrintFormat("%s: received %d ticks in %d ms"symbolreceivedGetTickCount()-start); 
//--- 틱 기록이 동기화되면 오류 코드는 0과 같습니다.
         if(GetLastError()==0
           { 
            success=true
            break
           } 
      else 
            PrintFormat("%s: %s ticks are not synchronized yet, %d ticks received for %d ms. Error=%d"
            __FUNCTION__symbolreceivedGetTickCount()-startGetLastError()); 
        } 
      //--- 카운트 시도
      attempts++; 
//--- tick 데이터베이스 동기화가 끝날 때까지 1초간 일시 정지합니다.
      Sleep(1000); 
     } 
//--- 요청된 틱을 틱 기록의 시작 부분에서 수신하는 데 3번 시도에 실패했습니다.  
   if(!success
     { 
      PrintFormat("Error! Failed to get ticks for symbol %s after three attempts"symbol); 
      return(false); 
     }
   return(true);
  }
/+------------------------------------------------------------------+
//| 바 인덱스로 시간을 반환합니다.                                      |
/+------------------------------------------------------------------+
datetime GetTime(const string symbolconst ENUM_TIMEFRAMES timeframeconst int index)
  {
   datetime array[1]={};
   ResetLastError();
   if(CopyTime(symboltimeframeindex1array)!=1)
      PrintFormat("%s: CopyTime() failed. Error %d",__FUNCTION__GetLastError());
   return(array[0]);
  }