Errores, fallos, preguntas - página 2146

 
fxsaber:

OnCalculate - no se ejecuta en este gráfico. Has creado un mango, ahí es donde vive.

Si no es en esta - entonces ¿por qué se dibuja normalmente (dibujo en el buffer) en la subventana derecha?

 
A100:

En el indicador.

::ChartWindowFind() devuelve -1 (en otras palabras, no funciona)


Hasta que el indicador no se inicializa, no conoce el número de la subventana en la que trabaja. Se une a la ventana sólo después de la inicialización exitosa

En otras palabras, es inútil llamar a ChartWindowFind( ) en el OnInit del indicador

 
Slava:
En otras palabras, es inútil llamar a ChartWindowFind( ) en el OnInit del indicador

Llamada a ChartWindowFind() en el indicador OnInit (mismo indicador)

void OnStart()
{
        string name = "Test_i";
        int sub_window = 1;
        ChartIndicatorAdd( 0, sub_window, iCustom( NULL, PERIOD_CURRENT, name ));
}

Resultado: 1:verdadero:0
2:1:0

Todo está bien detectado, permítame recordarle el código del indicador OnInit

void OnInit()
{
//...
        ResetLastError();
        int sub_window = ChartWindowFind();
        Print( "2:", sub_window, ":", GetLastError());
}
 
A100:

Si no lo es, ¿por qué dibuja normalmente (dibujo en el buffer) en la subventana requerida?

Así que el cálculo del indicador y su parte de dibujo son cosas diferentes. ChartWindowFind es una referencia al mecanismo que se encarga de dibujar el indicador. Es decir, ni siquiera es el propio indicador.

 
Slava:

Hasta que el indicador no se inicializa, no conoce el número de subventana en la que opera. Se une a la ventana sólo después de la inicialización exitosa.

Llamada aChartWindowFind() después de OnInit (desde OnCalculate)

//Test.mq5//Скрипт
void OnStart()
{
        string name = "Test_i";
        ObjectCreate( 0, name, OBJ_CHART, 0, 0, 0 );
        long chart_id  = ObjectGetInteger( 0, name, OBJPROP_CHART_ID );
        int sub_window = 1;
        ChartIndicatorAdd( chart_id, sub_window, iCustom( NULL, PERIOD_CURRENT, name ));
}
//Test_i.mq5//Индикатор
void OnInit() { Print( __FUNCTION__, ":end" ); }
int OnCalculate( const int, const int, const int, const double& [] )
{
        Print( __FUNCTION__ );
        ResetLastError();
        int sub_window = ChartWindowFind();
        Print( "3:", sub_window, ":", GetLastError());
        return 0;
}

Resultado: OnInit:fin
OnCalculate
3:-1:4113

En otras palabras, el indicador ya conoce el número de subventana en el que opera, pero no lo comunica
 
A100:

En otras palabras, el indicador ya conoce el número de la ventana en la que está trabajando, pero no lo comunica

¿Conoce ChartID()?

 
fxsaber:

¿Conoce ChartID()?

No es necesario - Función ChartWindowFind() sin parámetros
 
A100:
No es necesario - Función ChartWindowFind() sin parámetros

Estoy bastante seguro de que tampoco conoce ChartID() (sin parámetros).

 
fxsaber:

Estoy bastante seguro de que tampoco conoce ChartID() (sin parámetros).

Se trata de un fallo evidente, sobre todo porque la inoperatividad se produce no sólo si

        ObjectCreate( 0, name, OBJ_CHART, 0, 0, 0 );
        long chart_id = ObjectGetInteger( 0, name, OBJPROP_CHART_ID );

pero si

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

Es decir, si añado manualmente una ventana de gráfico y adjunto el indicador a ella, todo está bien

Pero si lo hago automáticamente, no funciona

Esto es contrario al propio concepto de algotrading

 
A100:

Se trata de un fallo flagrante, sobre todo porque no sólo es inoperante si

pero si

Es decir, si añado manualmente una ventana de gráfico y adjunto el indicador a ella, todo está bien

Pero si lo hago automáticamente, no funciona

Esto es contrario al propio concepto de algotrading

Es bueno que la arquitectura de los indicadores se haya aclarado. Es extraño que haya tan poca información al respecto en la documentación.

La parte de cálculo del indicador y la parte de dibujo son entidades diferentes. El mango es la parte de cálculo. El que calcula no sabe nada del que dibuja y no debería.

Imagina que has creado un asa, pero la has colocado no en uno, sino en dos gráficos. Obviamente, hay un indicador, pero se dibuja en dos gráficos con diferentes ChartID y SubWindow. El indicador de manilla no se preocupa por esto, porque no sabe dónde se dibuja este indicador y si se dibuja en absoluto. No es el indicador el que se encarga de renderizar.

Cuando se coloca el indicador manualmente en el gráfico o a través de una plantilla, la acción es muy diferente. Se crea un asa junto con la pieza de dibujo. Si lanza manualmente el indicador con los mismos parámetros de entrada en otro gráfico con el mismo símbolo y periodo, se creará otro asa con la parte de dibujo.

Este no es el caso de MQL. Si se crea un indicador y luego otro, no se vuelve a crear nada. La parte del cálculo se deja sin tocar.

La única manera de ejecutar el indicador en MQL, de la misma manera que se ejecuta a mano, por ejemplo en un nuevo gráfico o OBJ_CHART, es LoadTemplate.