Indicateurs: Nouveau gestionnaire d'événements "bar" pour les indicateurs

 

Nouveau gestionnaire d'événements "bar" pour les indicateurs:

Contrairement à OnCalculate(), l'indicateur n'est calculé que lorsqu'une nouvelle barre apparaît sur le graphique.

Author: Konstantin Gruzdev

 
datetime new_time=TimeCurrent()/period_seconds*period_seconds; // Heure d'ouverture de la barre sur le graphique actuel

Il y a une erreur ici. Si la période est une semaine ou un mois.

Si la période est une semaine, le début de la semaine est mercredi, car 1970.01.01 est jeudi.

Si la période est un mois et que le mois en cours n'a pas 30 jours, le décompte est également incorrect, car period_seconds correspond à 30 jours.

 
Maratori:

Il y a une erreur ici. Si la période est d'une semaine ou d'un mois.

Si la période est une semaine, le début de la semaine est mercredi, puisque 1970.01.01 est un jeudi.

Si la période est un mois, et que le mois en cours n'a pas 30 jours, il compte mal aussi, puisque period_seconds correspond à 30 jours.

Nous sommes d'accord. Vous pouvez utiliser ceci dans OnNewBarCalculate.mqh pour ces périodes :

//+------------------------------------------------------------------+
//| Fonction d'itération de l'indicateur personnalisée
//+------------------------------------------------------------------+
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[])
  {
//---
   // Lorsqu'une nouvelle barre apparaît, exécuter le gestionnaire d'événement NewBar
   if(current_chart.isNewBar()>0) 
      OnNewBarCalculate(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread);
   return(rates_total);
  }
 

Un peu à d'autres fins, mais j'utilise une fonction comme celle-ci pour l'instant :

datetime getHTFTime(datetime time, ENUM_TIMEFRAMES highTimeFrame) {
  int periodSeconds = PeriodSeconds(highTimeFrame);
  if(periodSeconds <= 60*60*24) return datetime(time/periodSeconds*periodSeconds);
  
  MqlDateTime sTime;
  TimeToStruct(time, sTime);
  
  if(highTimeFrame == PERIOD_W1) {
    TimeToStruct(time - datetime(sTime.day_of_week * 24 * 60 * 60), sTime);
    sTime.hour = 0;
    sTime.min = 0;
    sTime.sec = 0;
  } else if(highTimeFrame == PERIOD_MN1) {
      sTime.day = 1;
      sTime.hour = 0;
      sTime.min = 0;
      sTime.sec = 0;
    }
  return StructToTime(sTime);
}

Une date/heure et une période sont données en entrée. En sortie, nous obtenons l'heure de début de la barre sur ce timeframe, qui contient cette heure.

Si vous avez des suggestions pour optimiser le code, je serai heureux de les écouter.

Bien sûr, vous pouvez procéder de cette manière :

datetime timeOut[1];
CopyTime(_Symbol, highTimeFrame, timeIn, 1, timeOut);

Mais dans ce cas, j'ai rencontré un problème de synchronisation. En d'autres termes, il faut attendre que l'historique se charge.

 

Merci pour votre indicateur personnalisé mais lorsque je l'utilise, je n'ai qu'une seule alerte et j'arrête le débogage ! Merci de m'aider !

Si j'utilise OnTick à la place (et que je supprime les fonctions OnInit et OnCaculate) comme dans cet article https://www.mql5.com/fr/articles/159 il fonctionne bien mais l'indicateur ne s'affiche pas dans les fenêtres du navigateur. Et il ne fonctionne pas lorsque j'ajoute les fonctions OnInit et OnCaculate. Si j'ajoute les fonctions OnInit et OnCaculate, l'indicateur s'affiche dans les fenêtres du navigateur ?

Merci de votre compréhension.