ObjectMove

Изменяет координаты указанной точки привязки объекта.

bool  ObjectMove(
   long      chart_id,        // идентификатор графика
   string    name,            // имя объекта
   int       point_index,     // номер привязки
   datetime  time,            // время
   double    price            // цена
   );

Параметры

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
#define   OBJ_NAME_BID     "TestObjectMoveBid"  // имя графического объекта для цены Bid
#define   COUNT            100000000            // количество тиков для загрузки истории
#define   DELAY            1                    // задержка между тиками в мсек
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- идентификатор текущего графика, символ этого графика и 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;
   
//--- массив для приёма тиков
   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();  // размер массива тиков
   
//--- в цикле по массиву тиков
   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
   */
  }
//+------------------------------------------------------------------+
//| Создаёт объект "Ценовая метка"                                   |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Загружает тики в массив                                          |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbolMqlTick &array[])
  {
   int  attempts=0;     // счетчик попыток получения истории тиков
   bool success =false// флаг успешного выполнения копирования тиков 
   
//--- сделаем 3 попытки получить тики 
   while(attempts<3
     {
      //--- замерим время старта перед получением тиков 
      uint start=GetTickCount();
      
      //--- запросим тиковую историю с момента 1970.01.01 00:00.001 (параметр from=1 ms) 
      ResetLastError();
      int received=CopyTicks(symbolarrayCOPY_TICKS_ALL1COUNT); 
      if(received!=-1
        { 
         //--- выведем информацию о количестве тиков и затраченном времени 
         PrintFormat("%s: received %d ticks in %d ms"symbolreceivedGetTickCount()-start); 
         //--- если тиковая история синхронизирована, то код ошибки равен нулю 
         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++; 
      //--- пауза в 1 секунду в ожидании завершения синхронизации тиковой базы 
      Sleep(1000); 
     } 
//--- не удалось получить запрошенные тики от самого начала истории с трех попыток  
   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]);
  }