Errori, bug, domande - pagina 2146

 
fxsaber:

OnCalculate - non viene eseguito su questo grafico. Avete creato una maniglia, è lì che vive.

Se non su questo - allora perché disegna normalmente (disegno del buffer) nella sottofinestra di destra?

 
A100:

Nell'indicatore.

::ChartWindowFind() restituisce -1 (in altre parole non funziona)


Finché l'indicatore non è inizializzato, non conosce il numero della sottofinestra in cui lavora. Si attacca alla finestra solo dopo un'inizializzazione riuscita

In altre parole, è inutile chiamare ChartWindowFind() nell'indicatore OnInit

 
Slava:
In altre parole, è inutile chiamare ChartWindowFind() nell'indicatore OnInit

Chiamare ChartWindowFind() nell'indicatore OnInit (stesso indicatore)

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

Risultato: 1:true:0
2:1:0

Tutto è ben rilevato, lasciate che vi ricordi il codice dell'indicatore OnInit

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

Se non lo è - perché disegna normalmente (disegno del buffer) nella sottofinestra richiesta?

Quindi il calcolo dell'indicatore e la sua parte di disegno sono cose diverse. ChartWindowFind è un riferimento al meccanismo responsabile del disegno dell'indicatore. Cioè non è nemmeno l'indicatore stesso.

 
Slava:

Finché l'indicatore non è inizializzato, non conosce il numero di sottofinestra in cui opera. Si attacca alla finestra solo dopo un'inizializzazione riuscita.

Chiamata diChartWindowFind() dopo OnInit (da 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;
}

Risultato: OnInit:fine
OnCalculate
3:-1:4113

In altre parole, l'indicatore conosce già il numero di sottofinestra in cui opera, ma non lo segnala
 
A100:

In altre parole, l'indicatore conosce già il numero della finestra in cui sta lavorando, ma non lo segnala

Conosce ChartID()?

 
fxsaber:

Conosce ChartID()?

Non è richiesto - funzione ChartWindowFind() senza parametri
 
A100:
Non è richiesto - funzione ChartWindowFind() senza parametri

Sono abbastanza sicuro che non conosce nemmeno ChartID() (nessun parametro).

 
fxsaber:

Sono abbastanza sicuro che non conosce nemmeno ChartID() (nessun parametro).

Questo è un difetto evidente, soprattutto perché l'inoperosità si verifica non solo se

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

ma se

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

Cioè, se aggiungo manualmente una finestra del grafico e vi collego l'indicatore, tutto è OK

Ma se lo faccio automaticamente, non funziona

Questo è contrario al concetto stesso di algotrading

 
A100:

Questo è un difetto clamoroso, soprattutto perché non solo non è operativo se

ma se

Cioè, se aggiungo manualmente una finestra del grafico e vi collego l'indicatore, tutto è OK

Ma se lo faccio automaticamente, non funziona

Questo è contrario al concetto stesso di algotrading

È bene che l'architettura degli indicatori sia diventata più chiara. È strano che ci siano così poche informazioni al riguardo nella documentazione.

La parte di calcolo dell'indicatore e la parte di disegno sono entità diverse. La maniglia è la parte di calcolo. Quello che calcola non sa nulla di quello che disegna e non dovrebbe.

Immaginate di aver creato una maniglia, ma di averla posizionata non su uno, ma su due grafici. Ovviamente, c'è un solo indicatore, ma è disegnato su due grafici con ChartID e SubWindow diversi. L'indicatore Handle non si preoccupa di questo, perché non sa dove questo indicatore è disegnato e se è disegnato affatto. Non è l'indicatore che è responsabile del rendering.

Quando si posiziona l'indicatore manualmente sul grafico o attraverso un modello, avviene un'azione molto diversa. Una maniglia viene creata insieme alla parte del disegno. Se lanci manualmente l'indicatore con gli stessi parametri di input su un altro grafico con lo stesso simbolo e periodo, verrà creato un altro handle con la parte di disegno.

Questo non è il caso di MQL. Se si crea un indicatore e poi un altro, non si crea più nulla. La parte di calcolo è lasciata intatta.

L'unico modo per eseguire l'indicatore in MQL, nello stesso modo in cui lo si esegue a mano, per esempio, su un nuovo grafico o OBJ_CHART, è LoadTemplate.