Errores, fallos, preguntas - página 2794

 
Mihail Matkovskij:

Mi indicador ha empezado a perder objetos gráficos por alguna razón y no los borra. Utilizo el borrado automático en el destructor de la clase. Yo lo llamo:

Como resultado, obtengo un falso positivo. Llamo a GetLastError() y obtengo el error 4101 ("Errory chart identifier"). Supongamos. Comparo el chartID del objeto gráfico eliminado con el resultado de la función ChartID() y son exactamente iguales. ¿Cuál puede ser el motivo de que no se elimine un objeto del gráfico y cómo puedo evitarlo?

He decidido probar otra forma. Al crear un gráfico, añado todos los objetos a la lista y utilizo el bucle para eliminar todos los objetos al borrar el indicador. Ahora la funciónGetLastError() da el error 4001 después de la llamada a la función ObjectDelete y algunos objetos del gráfico permanecen en el gráfico.

 
Mihail Matkovskij:

Mi indicador ha empezado a perder objetos gráficos por alguna razón y no los borra. Utilizo el borrado automático en el destructor de la clase. Yo lo llamo:

Como resultado, obtengo un falso positivo. Llamo a GetLastError() y obtengo el error 4101 ("Errory chart identifier"). Supongamos. Comparo el chartID del objeto gráfico que se borra con el resultado de la función ChartID() y son exactamente iguales. ¿Cuál puede ser el motivo de que no se elimine un objeto del gráfico y cómo puedo evitarlo?

He hecho un código fuente donde se produce este error:
//+------------------------------------------------------------------+
//|                                           DeleteChartObjects.mq5 |
//|                                      Copyright 2020, © Cyberdev. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, © Cyberdev."
#property version   "1.00"
#property indicator_chart_window

#property indicator_plots 0

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

#include <ChartObjects\ChartObjectsLines.mqh>
#include <Arrays\ArrayObj.mqh>

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//--- input parameters
input int      nBars = 100000;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int customN_Bars = 0;

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CArrayObj listOfTrendLines;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
//--- indicator buffers mapping
  int totalBars = iBars(NULL, PERIOD_CURRENT);
  customN_Bars = (nBars < totalBars) ? nBars : totalBars;
//---
  return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]
) {
  CChartObjectTrend * trend;
  int delta = rates_total - customN_Bars;
  int shift;
  int i;
  for(i = 0; i < customN_Bars; i++) {
    shift = delta + customN_Bars - i - 1;
    trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
  }
  return(rates_total);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}
//+------------------------------------------------------------------+

Acciones para demostrar el fallo.

1. Coloque el indicador en el gráfico.

2. Retire el indicador del gráfico.

3 Pulsa Ctrl+B, luego pulsa el botón "Listar todo" en la ventana y verás los objetos que no han sido eliminados.

Objetos

Tengo hasta 294 de 100000.

Si se reduce el valor del parámetro de entrada nBars, el error no aparece.

Archivos adjuntos:
 

Buenas tardes.

Llevo mucho tiempo estancado con la actualización de Windows 7 a 10, pero he vuelto a instalar esta semana.

Ahora tengo un problema, no puedo descargar las versiones demo de mis indicadores y otros EAs,

Le doy al botón de descarga y no pasa nada, lo he probado con el terminal abierto y cerrado.

Estoy intentando descargarlo para el terminal MT4, aún no he pasado a MT5.

¿Qué demonios está pasando?

 
Mihail Matkovskij:
Hice un código fuente donde se produce este error:

¿Qué ocurre cuando se borra un puntero?

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  
  CChartObjectTrend * trend;
  
  int i = listOfTrendLines.Total() - 1;
  for(; i >= 0; i--) {
    trend = dynamic_cast <CChartObjectTrend *> (listOfTrendLines.At(i));
    
    if(CheckPointer(trend) == POINTER_INVALID)
      continue;
    
    delete trend;
  }
}

¿Existe un comando para el gráfico para eliminar el objeto gráfico? Ver nota de ObjectDelete

Документация по MQL5: Графические объекты / ObjectDelete
Документация по MQL5: Графические объекты / ObjectDelete
  • www.mql5.com
При вызове ObjectDelete() всегда используется асинхронный вызов, поэтому функция возвращает только результат постановки команды в очередь графика. В этом случае true означает только то, что команда успешно поставлена в очередь, сам результат её выполнения неизвестен. Для проверки результата выполнения можно использовать функцию ObjectFind() или...
 
Mihail Matkovskij:

Tengo hasta 294 de 100000.

Si disminuimos el valor del parámetro de entrada nBars, el fallo no se produce.

¿Puede ocurrir que el bucle dure más tiempo del que tarda en ejecutarse OnDeinit?

En tu ejemplo todos los objetos tienen el prefijo "trend", ¿por qué no lo utilizas y lo rechazas desde el bucle?

int  ObjectsDeleteAll(
   long           chart_id,   // идентификатор графика
   const string     prefix,   // префикс имени объекта
   int       sub_window=-1,   // индекс окна
   int      object_type=-1    // тип объекта для удаления
   );
 
Rashid Umarov:

¿Qué ocurre cuando se borra un puntero?

¿Existe un comando para el gráfico para eliminar el objeto gráfico? Véase la nota sobre ObjectDelete

Ciertamente, ya he pensado en esta nota. Pero luego decidí, por alguna razón, que era un error del terminal. Por lo cual me disculpo. Así que debe ser mi culpa.

Pero no sé qué hacer en este caso. ¿Llamo a ObjectDelete y luego a ObjectFind y espero hasta que falle para saber si el objeto fue realmente eliminado? A juzgar por la misma nota, lleva demasiado tiempo. No sé si un segundo borrado funcionará (en mi indicador he intentado llamar a ObjectDelete dos veces seguidas, pero no funcionó). Y la función Sleep en los indicadores no funciona para dar al gráfico un tiempo para borrar cada objeto. ¿Quizás haya ejemplos en alguna parte sobre cómo evitar esto?

 
Alexey Viktorov:

¿No puede ocurrir que el bucle dure más que el tiempo de ejecución de OnDeinit?

Después de todo, todos los objetos de tu ejemplo tienen el prefijo "trend", ¿por qué no utilizarlo y rechazarlo desde el bucle?

Esto es sólo en el ejemplo. El indicador con el que estoy trabajando tiene nombres complejos. Y he puesto un ejemplo sólo a modo de demostración.

 
Mihail Matkovskij:

Ciertamente, ya había pensado en esta nota. Pero luego, por alguna razón, pensé que era un error del terminal. Por lo que pido disculpas. Resulta que la culpa es mía.

Pero no sé qué hacer en este caso. ¿Llamo a ObjectDelete y luego a ObjectFind y espero hasta que falle para saber si el objeto fue realmente eliminado? A juzgar por la misma nota, lleva demasiado tiempo. No sé si un segundo borrado funcionaría (en mi indicador intenté llamar a ObjectDelete dos veces seguidas, pero no funcionó). Y la función Sleep en los indicadores no funciona para dar al gráfico un tiempo para borrar cada objeto. ¿Quizás haya ejemplos en alguna parte de cómo sortear esto?

Creo que estás añadiendo todos los punteros a la lista. El propio subsistema de terminales borra estos objetos, cuyos punteros están en la lista CArrayObj

trend = new CChartObjectTrend();
    if(trend.Create(0, "trend"+(string)i, 0, time[shift], low[shift], time[shift], high[shift]))
      listOfTrendLines.Add(trend);
Aquí tienes una posible fuga de memoria. Y una posible invocación de un objeto no válido.
 
Artyom Trishkin:
Creo que se añaden todos los punteros a la lista. El propio subsistema de terminales elimina estos objetos, cuyos punteros están en la lista CArrayObj

Después de apagar el terminal, los objetos permanecen en el gráfico después del indicador. Y cuando vuelvo a iniciar el terminal, estos objetos son visibles y estropean toda la vista.

 
Mihail Matkovskij:

Después de apagar el terminal, los objetos permanecen en el gráfico después del indicador. Y cuando vuelvo a iniciar el terminal, estos objetos son visibles y estropean toda la vista.

No estoy en mi PC para comprobar su ejemplo. He añadido a mi post anterior lo que veo en los errores.