Erreurs, bugs, questions - page 2146

 
A100:

Dans l'indicateur.

::ChartWindowFind() renvoie -1 (en d'autres termes, ne fonctionne pas)


Tant que l'indicateur n'est pas initialisé, il ne connaît pas le numéro de la sous-fenêtre dans laquelle il travaille. Il ne s'attache à la fenêtre qu'après une initialisation réussie.

En d'autres termes, il est inutile d'appeler ChartWindowFind() dans le OnInit de l'indicateur.

 
Slava:
En d'autres termes, il est inutile d'appeler ChartWindowFind() dans le OnInit de l'indicateur.

Appel de ChartWindowFind() dans l'indicateur OnInit (même indicateur)

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

Résultat : 1:vrai:0
2:1:0

Tout est bien détecté, laissez-moi vous rappeler le code de l'indicateur OnInit

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

Si ce n'est pas le cas, pourquoi dessine-t-il normalement (dessin en tampon) dans la sous-fenêtre requise ?

Le calcul de l'indicateur et sa partie dessin sont donc des choses différentes. ChartWindowFind est une référence au mécanisme qui est responsable du dessin de l'indicateur. C'est-à-dire qu'il ne s'agit pas de l'indicateur lui-même.

 
Slava:

Tant que l'indicateur n'est pas initialisé, il ne connaît pas le numéro de la sous-fenêtre dans laquelle il opère. Il ne s'attache à la fenêtre qu'après une initialisation réussie.

Appel deChartWindowFind() après OnInit (depuis 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;
}

Résultat : OnInit :fin
OnCalculate
3 :-1:4113

En d'autres termes, l'indicateur connaît déjà le numéro de la sous-fenêtre dans laquelle il opère, mais ne le communique pas.
 
A100:

En d'autres termes, l'indicateur connaît déjà le numéro de la fenêtre dans laquelle il travaille, mais ne le communique pas.

Connaît-il ChartID()?

 
fxsaber:

Connaît-il ChartID() ?

Il n'est pas nécessaire - Fonction ChartWindowFind() sans paramètres
 
A100:
Il n'est pas nécessaire - Fonction ChartWindowFind() sans paramètres

Je suis presque sûr qu'il ne connaît pas non plus ChartID() (pas de paramètres).

 
fxsaber:

Je suis presque sûr qu'il ne connaît pas non plus ChartID() (pas de paramètres).

Il s'agit d'un défaut évident, d'autant plus que l'inopérabilité ne se produit pas seulement si

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

mais si

        long chart_id = ChartOpen( NULL, PERIOD_CURRENT );

Par exemple, si j'ajoute manuellement une fenêtre graphique et que j'y associe l'indicateur, tout est correct.

Mais si je le fais automatiquement, cela ne fonctionne pas.

Ceci est contraire au concept même de l'algotrading.

 
A100:

Il s'agit là d'un défaut flagrant, d'autant plus qu'il est non seulement inopérant si

mais si

Par exemple, si j'ajoute manuellement une fenêtre graphique et que j'y associe l'indicateur, tout est OK.

Mais si je le fais automatiquement, cela ne fonctionne pas.

Ceci est contraire au concept même de l'algotrading.

C'est une bonne chose que l'architecture des indicateurs soit devenue plus claire. Il est étrange qu'il y ait si peu d'informations à ce sujet dans la documentation.

La partie calcul de l'indicateur et la partie dessin sont des entités différentes. La poignée est la pièce de calcul. Celui qui calcule ne sait rien de celui qui dessine et il ne devrait pas.

Imaginez que vous avez créé une poignée, mais que vous l'avez placée sur non pas un, mais deux graphiques. Évidemment, il y a un seul indicateur, mais il est dessiné sur deux graphiques avec des ChartID et SubWindow différents. L'indicateur de poignée ne se soucie pas de cela, car il ne sait pas où cet indicateur est dessiné et s'il est dessiné tout court. Ce n'est pas l'indicateur qui est responsable du rendu.

Lorsque vous placez l'indicateur manuellement sur le graphique ou par le biais d'un modèle, une action tout à fait différente se produit. Une poignée est créée en même temps que la partie dessin. Si vous lancez manuellement l'indicateur avec les mêmes paramètres d'entrée sur un autre graphique avec le même symbole et la même période, une autre poignée sera créée avec la partie dessin.

Ce n'est pas le cas avec MQL. Si vous créez un indicateur, puis un autre, rien n'est créé à nouveau. La partie calcul n'est pas touchée.

La seule façon d'exécuter l'indicateur dans MQL, de la même façon que vous l'exécutez à la main, par exemple sur un nouveau graphique ou OBJ_CHART, est LoadTemplate.

 
fxsaber:
il est étrange que le fonctionnement de l'icustom dépende de l'appel. l'icustom imbriqué ne peut pas utiliser le timer. peut-être les evens (dunno)