Discusión sobre el artículo "Preparación de indicadores de símbolo/periodo múltiple" - página 2

 

Realicé una pequeña prueba de estrés. Apagué el Internet, puso en marcha el indicador con el panel en el gráfico. Ya he proporcionado los parámetros anteriores. Luego encendí Internet y obtuve el siguiente resultado:

CL      0       22:29:43.402    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(10) indicator (handle 10) added to the collection
OS      0       22:29:43.402    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::AddNewMA: MA(EURUSD,H1:10) indicator (handle 11) added to the collection
DQ      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
QL      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
IO      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
PQ      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
LN      0       22:29:43.439    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
KE      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
JH      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
RK      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
OD      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
CR      0       22:29:43.443    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
GE      0       22:30:04.495    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::OnTimer::MA(EURUSD,H1:10): Tick emulation. Attempt 1 of 3 ...
II      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
LD      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
DH      0       22:30:34.092    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
NH      0       22:30:34.093    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RG      0       22:30:34.093    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
JM      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(10): Waiting for data to sync...
KP      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(10): Error in indicator calculation: Data is not synchronized
CD      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for data to sync...
FL      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Data is not synchronized
RK      0       22:30:35.539    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
OM      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CIndMSTF::Calculate::MA(EURUSD,H1:10): Waiting for a new tick and when the indicator will be calculated...
PI      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate::MA(EURUSD,H1:10): Error in indicator calculation: Calculation not completed
ND      0       22:30:37.935    TestMSTFMovingAverages (EURUSD,M15)     CMSTFIndicators::Calculate: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators
PN      2       22:30:39.604    TestMSTFMovingAverages (EURUSD,M15)     array out of range in 'TestMSTFMovingAverages.mq5' (211,34)


El indicador se estrelló.

 

También he notado algo extraño. Gráfico M15 en USDCHF.



Si nos fijamos en el gráfico USDCHF, o más bien en la curva roja del indicador MA(USDCHF, H1), durante las últimas 7 horas la transición al siguiente valor se produjo a las 00 minutos 5 veces. Lo he resaltado con verticales rojas. Y sólo para las últimas 2 horas todo es normal. Verticales azules. Imho, un claro error con el llenado de búfer....

 
Denis Kirichenko #:

Realicé una pequeña prueba de estrés. Apagué el Internet, puso en marcha el indicador con el panel en el gráfico. Ya he proporcionado los parámetros anteriores. Luego encendí el Internet y obtuve el siguiente resultado:


El indicador se estrelló.

Denis Kirichenko #:

También me di cuenta de algunas cosas extrañas. Gráfico M15 en USDCHF.



Si nos fijamos en el gráfico USDCHF, o más bien en la curva roja del indicador MA(USDCHF, H1), durante las últimas 7 horas la transición al siguiente valor se produjo a las 00 minutos 5 veces. Lo he resaltado con verticales rojas. Y sólo para las últimas 2 horas todo es normal. Verticales azules. Imho, un claro error con el llenado de búfer....

Gracias, lo miraré
 
Denis Kirichenko #:

Realicé una pequeña prueba de estrés. Apagué el Internet, puso en marcha el indicador con el panel en el gráfico. Ya he proporcionado los parámetros anteriores. Luego encendí el Internet y obtuve el siguiente resultado:


El indicador se estrelló.

En la línea 211, en la posición 34 del cursor, se accede al array predefinido time[]:

DrawData(mouse_bar_index,time[mouse_bar_index]);

Resulta que el índice pasado al array es incorrecto.

Difícilmente puede ser mayor que rates_total-1, lo más probable es que sea igual a -1, porque recibe sus valores en el manejador OnChartEvent por la función iBarShift(), que puede devolver -1:

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- Trabajar con el panel
//--- Llama al manejador de eventos del panel
   panel.OnChartEvent(id,lparam,dparam,sparam);

//--- Si el cursor se mueve o se hace clic en el gráfico
   if(id==CHARTEVENT_MOUSE_MOVE || id==CHARTEVENT_CLICK)
     {
      //--- Declare variables para almacenar en ellas las coordenadas de tiempo y precio
      datetime time=0;
      double price=0;
      int wnd=0;
      //--- Si las coordenadas del cursor se convierten a fecha y hora
      if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price))
        {
         //--- escribe el índice de la barra donde se encuentra el cursor en la variable global
         mouse_bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time);
         //--- Mostrar los datos de la barra bajo el cursor en el panel
         DrawData(mouse_bar_index,time);
        }
     }

//--- Si recibimos un evento de usuario, enviamos un mensaje al log sobre el mismo
   if(id>CHARTEVENT_CUSTOM)
     {
      //--- Aquí puede ser el manejo de hacer clic en el botón de cierre en el panel
      PrintFormat("%s: Event id=%ld, object id (lparam): %lu, event message (sparam): %s",__FUNCTION__,id,lparam,sparam);
     }
  }


En DrawData(), un valor de índice inválido se maneja llamando a CopyRates(), que no obtendrá ningún dato si el índice es negativo, y entonces saldrá de DrawData():

//--- Si no se han podido obtener los datos de la barra por el índice especificado - exit
   if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)
      return;

Así que - antes de acceder al array time[], es necesario comprobar el índice de barra pasado al array (en la línea 211):

//--- Mostrar los datos de la barra bajo el cursor en el panel (o la barra actual si el cursor está fuera del gráfico)
   if(mouse_bar_index>WRONG_VALUE && mouse_bar_index<rates_total)
      DrawData(mouse_bar_index,time[mouse_bar_index]);


En general - teoría. No lo he probado, ya que estoy ocupado desarrollando la continuación del tema (buffers de colores de multi-indicadores y así sucesivamente). Después de que se publique el próximo artículo sobre este tema, lo comprobaré y probaré (si no lo pruebas antes que yo con los cambios en p.211).

 
Artyom Trishkin #:

En la línea 211, se accede a la matriz predefinida time[] en la posición 34 del cursor:

Parece que el índice del array se pasa incorrectamente.

Difícilmente puede ser mayor que rates_total-1, lo más probable es que sea igual a -1, porque recibe sus valores en el manejador OnChartEvent por la función iBarShift(), que puede devolver -1:


En DrawData(), un valor de índice inválido se maneja llamando a CopyRates(), que no obtendrá ningún dato si el índice es negativo, y entonces saldrá de DrawData():

Así que - antes de acceder a la matriz time[], es necesario comprobar el índice de barra pasado a la matriz (en la línea 211):


En general - teoría. No lo he probado, ya que estoy ocupado desarrollando la continuación del tema (buffers de colores de multiindicadores y demás). Después de la publicación del próximo artículo sobre este tema, voy a comprobar y probar (si no lo prueba antes que yo con los cambios en la p.211).

Artem, el índice de barra puede ser actual, iBarShift() devuelve 0. Pero no se puede poner menos de 1 en CopyRates(). Por eso probablemente deberíamos escribir iBarShift()+1 en cualquier variante, ya que el número de barra y el número de barras no son iguales.

 
Alexey Viktorov #:

Artem, el índice de barra puede ser actual, iBarShift() devuelve 0. Pero no se puede poner menos de 1 en CopyRates(). Por lo tanto, probablemente deberíamos escribir iBarShift()+1 en cualquier variante, ya que el número de barra y el número de barras no son iguales.

En este contexto: el índice es el número de compás

 
Artyom Trishkin #:

En este contexto: el índice es el número de compás

Artem, índice - sí, puede ser cero. Pero el número de elementos copiados

int  CopyRates( 
   string           symbol_name,       // nombre del personaje 
   ENUM_TIMEFRAMES  timeframe,         // período 
   int              start_pos,         // donde empezaremos 
   int              count,             // cuánto copiamos 
   MqlRates         rates_array[]      // array donde se copiarán los datos 
   );

no puede ser igual a cero.

Al igual que el número de elementos y el índice en la lista de elementos ...

 
Alexey Viktorov #:

Artem, el índice - sí, puede ser cero. Pero el número de elementos copiados

no puede ser igual a cero.

Al igual que el número de elementos y el índice en la lista de elementos ...

Justo aquí:

if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)

¿dónde apunta el índice?

 
Artyom Trishkin #:

Está aquí mismo:

¿dónde apunta el índice?

Ya está, me callo. No miré el código de la función DrawData(mouse_bar_index,time); por eso me equivoqué...

 

Foro sobre negociación, sistemas automatizados de negociación y ensayo de estrategias de negociación

Discusión del artículo "Preparación de indicadores multisímbolo multiperiodo"

Artyom Trishkin, 2023.11.01 04:46 AM

...Después de publicar el próximo artículo sobre este tema, voy a comprobar y probar (si no me prueba antes con los cambios en p.211).


Para probar algo, hay que estar en el paradigma de lo que pasa ))

Me di cuenta de que es más fácil para mí esbozar mi propia versión, ya que no estoy cerca del enfoque actual. En concreto, me parece que la clase CIndMSTF es una especie de superclase. A partir de ella se crean un montón de clases indicadoras. Creepy - el archivo IndMSTF.mqh es 4 mil líneas de código )) Tomé el camino de usar una instancia de la clase CIndicators como una colección de indicadores . Es muy conveniente. No hace falta inventar una bicicleta.

Entonces, ¿por qué la clase CIndMSTF debe almacenar los datos en buffers (SBuffer m_buffers[])? Los calculamos una vez en OnCalculate() y es suficiente. Es decir, aceptados como parámetro por referencia, calculados y dados....

Escribiré más tarde sobre lo que no estoy de acuerdo una vez termine mi versión....

Sí, me gusta que exista este mecanismo:

...При работе с данными не текущего графика для исключения "освобождения" таймсерии, необходимо не реже. чем раз в две минуты обращаться к этой таймсерии. В этом случае будет происходить "удержание" таймсерии, что ускорит к ней обращение (не нужно будет каждый раз дожидаться синхронизации данных)...


Artem, una cosa más. Si los artículos están escritos como un manual, que hay un deseo de estudiar, entonces, imho, no hay suficientes esquemas de relaciones de esas clases, que el desarrollador crea....

Entonces, ¿por qué poner el código de todos los indicadores en el material del artículo? Me refiero a esta sección - "Una lista completa de todas las clases herederas de la clase base del indicador multiperiodo multisímbolo". Miré cuántas líneas de código hay.

Aquí está el principio:

Y aquí está el final:


Casi 2 mil. ¡Vaya!