ObjectMove

Cambia las coordinadas del punto de anclaje de un objeto.

bool  ObjectMove(
   long      chart_id,        // identificador del gráfico
   string    name,            // nombre del objeto
   int       point_index,     // número de anclaje
   datetime  time,            // hora
   double    price            // precio
   );

Parámetros

chart_id

[in]  Identificador del gráfico. 0 significa el gráfico actual.

name

[in]  Nombre del objeto.

point_index

[in]  Número del punto de anclaje. La cantidad de puntos de anclaje depende del tipo de objeto.

time

[in]  Coordinada de hora del punto de anclaje especificado.

price

[in]  Coordinada de precio del punto de anclaje especificado.

Valor devuelto

Retorna true en el caso de que se haya añadido con éxito el comando a la cola del gráfico indicado, de lo contrario, false.

Nota

Al llamar ObjectMove() siempre se usa una llamada asincrónica, por eso la función retorna solo el resultado de la colocación de la orden en la cola del gráfico. En este caso, true solo significa que el comando se ha puesto en la cola con éxito, el propio resultado de su ejecución aún se desconoce.

Para comprobar el resultado de la ejecución se puede usar una función que solicite las propiedades del objeto, por ejemplo, del tipo ObjectGetXXX. Pero, en esta caso, además, se deberá tener en cuenta que estas funciones se colocan al final de la cola de comandos del gráfico y esperan el resultado de la ejecución (puesto que que son llamadas sincrónicas), es decir, pueden consumir bastante tiempo. Hay que tener esta circunstancia en cuenta al trabajar con multitud de objetos en el gráfico.

 

Ejemplo:

#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
 
#define   OBJ_NAME_ASK     "TestObjectMoveAsk"  // nombre del objeto gráfico para el precio Ask
#define   OBJ_NAME_BID     "TestObjectMoveBid"  // nombre del objeto gráfico para el precio Bid
#define   COUNT            100000000            // número de ticks para cargar la historia
#define   DELAY            1                    // retraso entre ticks en milisegundos
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- identificador actual del gráfico, símbolo de este gráfico y Digits del símbolo
   long   chart_idChartID();
   string symbol  = ChartSymbol(chart_id);
   int    digits  = (int)SymbolInfoInteger(symbolSYMBOL_DIGITS);
   
//--- creamos dos etiquetas de precio para mostrar en el gráfico el precio Ask y el precio Bid
   if(!CreatePriceLabel(chart_idtrue) || !CreatePriceLabel(chart_idfalse))
      return;
   
//--- array de obtención de ticks
   MqlTick ticks[]={};
   
//--- obtenemos el número de la barra que sigue a la primera visible en el gráfico y la hora de apertura de esta barra en milisegundos
   int   first= (int)ChartGetInteger(chart_idCHART_FIRST_VISIBLE_BAR)-1;
   ulong from = GetTime(symbolPERIOD_CURRENTfirst)*1000;
   
//--- cargamos la historia de ticks en un array
   Print("Started collecting ticks...");
   if(!GetTicksToArray(symbolticks))
      return;
      
//--- ponemos a cero el array de etiquetas y obtenemos los ticks del rango visible de barras en el gráfico
   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;                  // número de ticks procesados
   int changes=0;                // número de cambios de precio procesados
   int total=(int)ticks.Size();  // tamaño del array de ticks
   
//--- en un ciclo por el array de ticks
   for(int i=0i<total && !IsStopped(); i++)
     {
      //--- obtenemos un tick del array e incrementamos el contador de ticks
      MqlTick  tick=ticks[i];
      count++;
      
      //--- comprobamos las banderas Ask y Bid del tick
      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;
      
      //--- si hay un cambio en el precio Ask
      if(ask_tick)
        {
         if(Move(chart_idOBJ_NAME_ASKtick.timetick.ask))
           {
            changes++;
            done=true;
           }
        }
      //--- si hay un cambio en el precio Bid
      if(bid_tick)
        {
         if(Move(chart_idOBJ_NAME_BIDtick.timetick.bid))
           {
            changes++;
            done=true;
           }
        }
      //--- si se ha desplazado cualquiera de los objetos gráficos (o ambos), actualizamos el gráfico
      if(done)
        {
         ChartRedraw(chart_id);
         Sleep(DELAY);
        }
     }
   
//--- al final del ciclo, informaremos en el diario sobre el número de ticks procesados,
//--- esperamos un par de segundos, eliminamos los objetos creados y redibujamos el gráfico
   PrintFormat("Total ticks completed: %u, Total price changes: %d"countchanges);
   Sleep(2000);
   if(ObjectsDeleteAll(chart_id"TestObjectMove")>0)
      ChartRedraw(chart_id);
   /*
   como resultado de la ejecución del script, en el gráfico visible se mostrarán los movimientos de los precios Ask y Bid,
  comenzando desde el borde izquierdo del gráfico y continuando hasta el final de los datos históricos,
  en el diario se mostrá la siguiente información:
   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
   */
  }
//+------------------------------------------------------------------+
//| Crea el objeto "Etiqueta de precio"                              |
//+------------------------------------------------------------------+
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)));
  }
//+------------------------------------------------------------------+
//| Desplaza el objeto gráfico a las coordenadas de precio/hora especificados |
//+------------------------------------------------------------------+
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);
  }
//+------------------------------------------------------------------+
//| Carga los ticks en un array                                      |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbolMqlTick &array[])
  {
   int  attempts=0;     // contador de intentos de obtención de la historia de ticks
   bool success =false// bandera de ejecución exitosa del copiado de ticks 
   
//--- haceremos tres intentos para obtener los ticks
   while(attempts<3
     {
      //--- medimos la hora de inicio antes de obtener los ticks 
      uint start=GetTickCount();
      
      //--- solicitamos la historia de ticks desde el momento 1970.01.01 00:00.001 (parámetro from=1 ms) 
      ResetLastError();
      int received=CopyTicks(symbolarrayCOPY_TICKS_ALL1COUNT); 
      if(received!=-1
        { 
         //--- mostramos la información sobre el número de ticks y el tiempo invertido 
         PrintFormat("%s: received %d ticks in %d ms"symbolreceivedGetTickCount()-start); 
         //--- si la historia de ticks está sincronizada, el código de error será igual a cero 
         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()); 
        } 
      //--- calculamos los intentos 
      attempts++; 
      //--- pausa de 1 segundo a la espera de que finalice la sincronización de la base de ticks 
      Sleep(1000); 
     } 
//--- no ha sido posible obtener los ticks solicitados desde el principio de la historia después de tres intentos  
   if(!success
     { 
      PrintFormat("Error! Failed to get ticks for symbol %s after three attempts"symbol); 
      return(false); 
     }
   return(true);
  }
//+------------------------------------------------------------------+
//| Retorna la hora según el índice de la barra                      |
//+------------------------------------------------------------------+
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]);
  }