Erros, bugs, perguntas - página 2146

 
fxsaber:

OnCalculate - não funciona nesta tabela. Criou uma pega, é lá que ela vive.

Se não neste - então porque é que desenha normalmente (desenho tampão) na sub-janela direita?

 
A100:

No indicador.

::ChartWindowFind() retorna -1 (por outras palavras, não funciona)


Até que o indicador seja inicializado, não sabe o número da subjanela em que trabalha. Só se liga à janela depois de uma inicialização bem sucedida

Por outras palavras, é inútil chamar ChartWindowFind() no indicador OnInit

 
Slava:
Por outras palavras, é inútil chamar ChartWindowFind() no indicador OnInit

Calling ChartWindowFind() no indicador OnInit (mesmo indicador)

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

Resultado: 1:verdadeiro:0
2:1:0

Tudo está bem detectado, deixem-me lembrar-vos do código do indicador OnInit

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

Se não está - porque desenha normalmente (desenho tampão) na sub-janela necessária?

Assim, o cálculo do indicador e a sua parte de desenho são coisas diferentes. ChartWindowFind é uma referência ao mecanismo que é responsável pelo desenho do indicador. Ou seja, nem sequer é o próprio indicador.

 
Slava:

Até o indicador ser rubricado, não sabe o número da subjanela em que opera. Só se liga à janela depois de uma inicialização bem sucedida.

Chamada deChartWindowFind() após OnInit (de 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:fim
OnCalculate
3:-1:4113

Por outras palavras, o indicador já conhece o número da subjanela em que opera, mas não o comunica
 
A100:

Por outras palavras, o indicador já sabe o número da janela em que está a trabalhar, mas não o comunica

Conhece ChartID()?

 
fxsaber:

Conhece ChartID()?

Não é necessário - Função ChartWindowFind() sem parâmetros
 
A100:
Não é necessário - Função ChartWindowFind() sem parâmetros

Só tenho a certeza de que também não conhece ChartID() (sem parâmetros).

 
fxsaber:

Tenho a certeza que também não conhece ChartID() (sem parâmetros).

Esta é uma falha óbvia, especialmente porque a inoperabilidade não ocorre apenas se

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

mas se

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

Isto é, se eu adicionar manualmente uma janela gráfica e lhe anexar o indicador, está tudo bem

Mas se eu o fizer automaticamente, não funciona

Isto é contrário ao próprio conceito de algotrading

 
A100:

Esta é uma falha gritante, especialmente porque não é apenas inoperante se

mas se

Isto é, se eu adicionar manualmente uma janela gráfica e lhe anexar o indicador - tudo está bem

Mas se eu o fizer automaticamente, não funciona

Isto é contrário ao próprio conceito de algotrading

É bom que a arquitectura dos indicadores se tenha tornado mais clara. É estranho que haja tão pouca informação sobre o assunto na documentação.

A parte de cálculo do indicador e a parte do desenho são entidades diferentes. A pega é a parte de cálculo. O calculista não sabe nada sobre o desenho e não deve saber.

Imagine que criou um cabo, mas que o colocou não num, mas em dois gráficos. Obviamente, existe um indicador, mas é desenhado em dois gráficos com ChartID e SubWindow diferentes. O Indicador de Punho não quer saber disto, porque não sabe onde este indicador é desenhado e se é de todo desenhado. Não é o indicador que é responsável pela renderização.

Quando se coloca o indicador manualmente no gráfico ou através de um modelo, acontece uma acção bastante diferente. É criada uma pega juntamente com a parte do desenho. Se lançar manualmente o indicador com os mesmos parâmetros de entrada num outro gráfico com o mesmo símbolo e período, será criada outra pega com a parte do desenho.

Este não é o caso da MQL. Se se criar um indicador e depois outro, nada é criado novamente. A parte de cálculo é deixada intocada.

A única forma de executar o indicador em MQL, da mesma forma que se o executa à mão, por exemplo num novo gráfico ou OBJ_CHART, é LoadTemplate.