ChartNavigate pendant l'initialisation

 

J'ai rencontré un problème avec la fonction ChartNavigate. Je fais quelque chose de mal ou il y a vraiment un problème avec la fonction. Répondez si vous l'avez utilisé assez souvent.

Voici donc le nœud du problème : ChartNavigate ne déplace pas le graphique. Lors du démarrage du terminal si la fonction est appelée dans OnInit(). J'ai volontairement lu la documentation plusieurs fois. Il n'est dit nulle part que la fonction ne peut pas être appelée pendant l'initialisation.

Code indicateur pour la lecture :

#property indicator_chart_window 
int OnInit()
{
   if (ChartNavigate(0, CHART_END, -1000))
      Alert("Успешно");
   else
      Alert("Ошибка №", GetLastError());

   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   return(rates_total);
}

Étapes pour jouer :

  1. Désactiver la lecture automatique des graphiques.
  2. Fixez l'indicateur au tableau. ChartNavigate se déclenchera en déplaçant le graphique à la position souhaitée.
  3. Déchargez le terminal.
  4. Chargez le terminal. ChartNavigate ne fonctionnera pas en affichant le graphique sans décalage.
OK, si la fonction donnait une erreur. Mais ce n'est pas le cas. Tous les appels sont réussis, mais c'est lorsque le terminal est rechargé que le décalage du graphique ne se produit pas.

 
Vous appliquez une fonction qui fonctionne avec le graphique. Pour un indicateur, la garantie de création du graphique est la première entrée dans OnCalculate, pour un EA c'est la première entrée dans OnTick(). Mais pas avant.
 
Vladimir Karputov:
Vous appliquez une fonction qui fonctionne avec le graphique. Pour l'indicateur, la garantie de la création du graphique est la première entrée dans OnCalculate, pour l'Expert Advisor - la première entrée dans OnTick(). Mais pas avant.

Pas de problème. S'il n'y a pas encore de graphique, la fonction renvoie false et le code d'erreur correspondant. Mais ce n'est pas le cas, la fonction signale fièrement une exécution réussie. Notez que la documentation ne dit pas qu'il s'agit d'une indication de la réussite de l'envoi du message au graphique. Il est clairement indiqué : exécution réussie de la fonction.

C'est aussi un code pour la lecture. En fait, avant même l'appel au ChartNavigate, j'ai un appel à la timeseries. Et ils sont tous remplis correctement, comme il s'avère. C'est-à-dire qu'il y a déjà un graphique, il y a ses données. En outre, il est possible de lire sur le graphique les objets graphiques qui y ont été placés avant la fermeture du terminal.

Ainsi, selon toutes les indications, la carte existe déjà.

 

C'est bizarre. Il fonctionne pour moi sans aucun problème.

Et une note supplémentaire : Vous devez désactiver son décalage automatique CHART_AUTOSCROLL avant de décaler le graphique.

 
Ihor Herasko:

Pas de problème. S'il n'y a pas encore de graphique, la fonction renvoie false et le code d'erreur correspondant. Mais ce n'est pas le cas, la fonction signale fièrement une exécution réussie. Notez que la documentation ne dit pas que c'est un signe de réussite de l'envoi du message au graphe. Il est clairement indiqué : exécution réussie de la fonction.

C'est aussi un code pour la lecture. En fait, avant même l'appel au ChartNavigate, j'ai un appel à la timeseries. Et ils sont tous remplis correctement, comme il s'avère. C'est-à-dire qu'il y a déjà un graphique, il y a ses données. En outre, il est possible de lire sur le graphique les objets graphiques qui y ont été placés avant la fermeture du terminal.

Ainsi, selon toutes les indications, la carte existe déjà.

Graphique et données sont deux grandes différences.

Toutes les fonctions se référant à des graphiques sont asynchrones, c'est-à-dire à sens unique - tirées et oubliées. Et dans ce cas, "vrai" signifie simplement que vous avez rempli correctement les champs de cette fonction, rien de plus.

Le signe lorsque toutes les données sont prêtes et que les graphiques sont tracés est la première entrée de Oncalculate/OnTick.

 
Vladimir Karputov:

Un graphique et des données sont deux choses bien différentes.

Toutes les fonctions d'accès au graphe sont asynchrones, c'est-à-dire qu'il s'agit d'un voyage à sens unique - tiré et oublié. Dans ce cas, vrai signifie uniquement que vous avez correctement rempli les champs de cette fonction, rien de plus.

Le signe lorsque toutes les données sont prêtes et que les graphiques sont tracés est la première entrée de Oncalculate/OnTick.

Alors comment expliquez-vous le fait qu'il fonctionne parfaitement pour moi ? Dans OnInit(), exactement comme dans le premier message du fil de discussion... Pourquoi inventez-vous des bêtises ?

 
Alexey Viktorov:

C'est bizarre. Il fonctionne pour moi sans aucun problème.

Quel est votre modèle ? J'ai 1861.

Et une note supplémentaire : Vous devez désactiver le décalage automatique CHART_AUTOSCROLL avant de décaler le graphique.

Oui, je l'ai signalé dans la première étape pour la lecture.

 
Ihor Herasko:

Quelle est votre construction ? J'ai 1861.

Oui, c'est ce que j'ai indiqué dans la première étape pour le replay.

J'ai aussi 1861. Je n'ai réussi à le reproduire qu'une seule fois. Toutes les autres tentatives ont bien fonctionné.

 
Vladimir Karputov:

Un graphique et des données sont deux choses bien différentes.

Toutes les fonctions d'accès au graphe sont asynchrones, c'est-à-dire qu'il s'agit d'un voyage à sens unique - tiré et oublié.

Non, pas tous. Celles qui le font sont spécifiquement commentées. Par exemple, le même ChartApplyTemplate.

Dans ce cas, vrai signifie uniquement que vous avez correctement rempli les champs de cette fonction, rien de plus.

Comment la fonction a-t-elle déterminé que l'ID du graphique est correct, si le graphique lui-même n'existe pas encore ?

Le signe lorsque toutes les données sont prêtes et que les graphiques sont tracés est la première entrée de Oncalculate/OnTick.

Malheureusement, non. Voici le code :

#property indicator_chart_window 
int OnInit()
{
   Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT));

   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT));
   return(rates_total);
}

Cela fonctionne comme suit :

16:01:31.765    Test (XBNUSD,M1)        OnInit, баров: 0
16:01:33.531    Test (XBNUSD,M1)        OnCalculate, баров: 37026
16:01:34.010    Test (XBNUSD,M1)        OnCalculate, баров: 46484

J'exécute l'indicateur sur un nouveau symbole dont le graphique n'a encore jamais été ouvert, c'est-à-dire qu'aucune donnée n'a encore été générée sur ce symbole.

Dans la première ligne (OnInit) il n'y a effectivement pas de données. Cependant, il y a l'ID du graphique et nous pouvons créer des objets dans OnInit() qui seront affichés avec succès sur le graphique.

La deuxième ligne contient déjà des données, mais elles sont incomplètes. Les données sont complètes à la troisième itération.

Il est raisonnable de conclure que le premier appel à OnCalculate ne garantit pas le chargement des données. Il s'agit simplement du premier tick sur le symbole après l'ouverture du graphique, qui peut survenir après une certaine quantité de données ou sans aucune autre donnée.

Pour en revenir au problème soulevé dans le sujet, nous obtenons que la fonction ChartNavigate() ne vérifie pas l'exactitude des paramètres. S'il n'y a pas encore de données dans OnInit() (0 barres), et que la valeur -1000 est passée à la fonction, alors comment pouvons-nous considérer cette valeur comme correcte, s'il n'y a pas de barres ? Après tout, toute autre fonction renverrait une erreur en accédant à la barre avec un index inexistant. Mais c'est un succès ici. Qu'est-ce qui est réussi exactement ?

 

Voici l'indicateur - spécialement mis un délai de neuf ticks, deux types de mouvement du graphique et le drapeau de redécoupage forcé (on/off).

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2012, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property indicator_chart_window 
#property indicator_plots 0
//--- input parameters
input bool redraw=true;
input ENUM_CHART_POSITION position=CHART_BEGIN;
//---
long count=0;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   count=0;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   Comment("");
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
   count++;
   Comment(count);
   if(count==9)
     {
      ResetLastError();
      if(position==CHART_BEGIN)
        {
         if(ChartNavigate(0,CHART_BEGIN,100))
            Print("Успешно. redraw ",redraw,". position ",EnumToString(position));
         else
            Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position));
        }
      if(position==CHART_END)
        {
         if(ChartNavigate(0,CHART_END,-100))
            Print("Успешно. redraw ",redraw,". position ",EnumToString(position));
         else
            Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position));
        }
      if(redraw)
         ChartRedraw();
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+


Préliminaire :CHART_BEGIN eststable.

Dossiers :
Test.mq5  6 kb
 
Vladimir Karputov:

Voici l'indicateur - spécialement mis un délai de neuf ticks, deux types de mouvement du graphique et le drapeau de redécoupage forcé (on/off)


Préliminaire :CHART_BEGIN fonctionne de manière régulière.

Mais que faire s'il n'y a pas de tiques, c'est le week-end ? Ensuite, il faudra connecter la minuterie.

Et il ne reste qu'une seule question à résoudre : comment déterminer si ChartNavigate a été exécuté avec succès ? Le fait qu'elle renvoie vrai, elle ne fait que "tic-tac", cela n'aide pas dans le travail réel.