Ne riez pas, je débute !

 

Bonjour à tous,

J’ai souhaité commencer par la création d’un indicateur. Je ne mets en œuvre aucune stratégie... Je cherche juste à recopier l’allure du signal du prix de clôture dans une fenêtre séparée, sous le graphique. C'est tout bête et mon but est purement pédagogique. Cela dit, j’ai réussi à rédiger un code sans erreur ! Pour moi, c’est une première victoire.

Ma méthode :

Je dimensionne la fenêtre d’affichage de l’indicateur, séparée du graphique, entre un seuil bas situé à 0 et un seuil haut situé à 100.

Je donne le nom de IndicateurBuffer[] au graphe de mon indicateur.

Je récupère l’historique des prix (dans HistoBuffer[]) et je transfère vers un tableau uniquement le prix de la cloture (ClotureBuffer[]).

Je recherche le minimum (Mini1) et le maximum (Maxi1) de ClotureBuffer[] de manière à pouvoir régler le minimum sur 0 et le maximum sur 100.

Je complète le tableau IndicateurBuffer[] avec les ordonnées de mon indicateur.

En prime (pour comprendre), je « print » ces deux paramètres :

  • rates_total,
  • prev_calculated.

Problèmes :

J’ai compris que rates_total correspond au nombre de bougies du graphique... Ce paramètre est le même que celui qu’on précise dans MT5 en cliquant sur Outils/Options/Graphiques/Nb barres max. Pour info, j’ai réglé Nb de barres max à 50000. Cependant, après l’exécution du programme dans MT5, rates_total affiche 50006 !

J’ai beau lire toute la documentation déjà présente sur le site MQL5, je ne parviens toujours pas à comprendre à quoi sert prev_calculated, ni comment l’utiliser dans un programme…

J’obtiens un message délivré par MT5 : « array out of range i, ‘Essais01.mq5’ (74,38) ».

J’ai 4 questions :

Q1 : Pourquoi MT5 m’indique que rates_total est de 50006 alors que j’ai réglé le nombre max de bougies à 50000 ?

Q2 : Avez-vous 2 ou 3 tuyaux pour m’aider à comprendre l’utilité de prev_calculated et comment l’utiliser dans un programme ?

Q3 : Pourquoi MT5 m’indique, après l’exécution : « array out of range i, ‘Essais01.mq5’ (74,38) » alors qu’en compilant tout se passe bien ?

Q4 : Avez-vous des conseils à me donner pour m’aider à améliorer mon code ?

Merci d'avance...

Voici mon code :

//+------------------------------------------------------------------+
//|                                                        Essai.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 1
#property indicator_plots   1

//--- plot Hausse
#property indicator_label1  "Cloture"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrLime
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- indicator buffers
double    IndicateurBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,IndicateurBuffer,INDICATOR_DATA);
//--- set maximum and minimum for subwindow
   IndicatorSetDouble(INDICATOR_MINIMUM,0);
   IndicatorSetDouble(INDICATOR_MAXIMUM,100);
//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"Cloture");
   PlotIndexSetString(0,PLOT_LABEL,"Cloture");
  
   return(INIT_SUCCEEDED);
  }
 
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   int bars = 0;
   if(prev_calculated > 0)
      {
      bars = rates_total - (prev_calculated - 1);
      }
   else
      {
      bars = rates_total - 1;
      }
  
   MqlRates HistoBuffer[];
   ArraySetAsSeries(HistoBuffer, true);
   CopyRates(_Symbol, PERIOD_CURRENT, 0, bars, HistoBuffer);
  
   double ClotureBuffer[1000];
   ArrayInitialize(ClotureBuffer,0);
  
   for(int i = 0; i <= 999 ; i++)
      {
      ClotureBuffer[i] = HistoBuffer[i].close;
      }
  
   double Maxi1 = 0;
   double Mini1 = 0;
   Maxi1 = ClotureBuffer[0];
   Mini1 = ClotureBuffer[0];
  
   for(int i = 0 ; i <=999; i++)
      {
      if (ClotureBuffer[i] > Maxi1)
         {Maxi1 = ClotureBuffer[i];}
     
      if (ClotureBuffer[i] < Mini1)
         {Mini1 = ClotureBuffer[i];}
      }
  
   ArraySetAsSeries(IndicateurBuffer, true);
   for(int i = 0; i <= 999 ; i++)
      {
      IndicateurBuffer[i] = (ClotureBuffer[i] - Mini1) * (100 / (Maxi1 - Mini1));
      }
  
   Print("Rates Tot : " + (string)rates_total);
   Print("Prev Calc : " + (string)prev_calculated);
  
   return(rates_total);
  }
Découvrez de nouvelles opportunités MetaTrader 5 avec la communauté et les services MQL5
Découvrez de nouvelles opportunités MetaTrader 5 avec la communauté et les services MQL5
  • 2023.05.15
  • www.mql5.com
MQL5 : langage de stratégies de trading intégré à la plateforme de trading MetaTrader 5, permet d'écrire vos propres robots de trading, indicateurs techniques, scripts et bibliothèques de fonctions
 
niouininon:

J’ai 4 questions :

Q1 : Pourquoi MT5 m’indique que rates_total est de 50006 alors que j’ai réglé le nombre max de bougies à 50000 ?

C'est normal, le réglage n'a pas à une bougie près. Quand ce nombre atteint un certain seul 50099 par exemple, il va ensuite être ramené à 50000.

Q2 : Avez-vous 2 ou 3 tuyaux pour m’aider à comprendre l’utilité de prev_calculated et comment l’utiliser dans un programme ?

Lire la documentation et expérimenter.

prev_calculated a la valeur retournée du précédent appel à OnCalculate ("return(rates_total)"). Sauf si la plateforme envoie une "mise à zéro", alors la valeur sera 0, comme lorsque OnCalculate() est exécuté la première fois.

En comparant prev_calculated et rates_total, vous pouvez déterminer si vous avez une "remise à zéro", un simple tick dans la même bougie, ou une nouvelle bougie. Et donc ajuster les calculs nécessaires.

Q3 : Pourquoi MT5 m’indique, après l’exécution : « array out of range i, ‘Essais01.mq5’ (74,38) » alors qu’en compilant tout se passe bien ?

C'est une erreur "runtime", dépendant des valeurs à un instant X. Rien que le compilateur puisse détecter.

Cela arrive parce que vous utilisez un indice pour accéder à votre tableau (array).

for(int i = 0; i <= 999 ; i++)
      {
      ClotureBuffer[i] = HistoBuffer[i].close;
      }

Etes-vous certain que HistoryBuffer[] a toujours 1000 éléments, ayant pour indice 0 à 999 ?

Q4 : Avez-vous des conseils à me donner pour m’aider à améliorer mon code ?

Continuer à étudier et expérimenter. Lire et comprendre le code de programmeurs expérimentés. Lire et comprendre la documentation.

 
Alain Verleyen #:
Etes-vous certain que HistoryBuffer[] a toujours 1000 éléments, ayant pour indice 0 à 999 ?

Merci Alain pour votre retour. J'y vois plus clair sur certains aspects et je commence à comprendre l'utilité de prev_calculted. Il faut que je mouline encore un peu...

Vous écrivez : " Etes-vous certain que HistoryBuffer[] a toujours 1000 éléments, ayant pour indice 0 à 999 ? ".

Il faudrait donc que je teste toujours la taille de mes tableaux avant de les parcourir avec un indice ?

 
niouininon #:

Merci Alain pour votre retour. J'y vois plus clair sur certains aspects et je commence à comprendre l'utilité de prev_calculted. Il faut que je mouline encore un peu...

Vous écrivez : " Etes-vous certain que HistoryBuffer[] a toujours 1000 éléments, ayant pour indice 0 à 999 ? ".

Il faudrait donc que je teste toujours la taille de mes tableaux avant de les parcourir avec un indice ?

Oui si la taille peut varier, ce qui est clairement le cas pour HistoryBuffer.

Notez bien, que vous n'avez même pas besoin de HistoryBuffer dans ce cas précis :

   MqlRates HistoBuffer[];
   ArraySetAsSeries(HistoBuffer, true);
   CopyRates(_Symbol, PERIOD_CURRENT, 0, bars, HistoBuffer);

Vous l'utilisez pour récupérer des données sur le symbol et le timeframe courant. Mais vous avez déjà accès à ces même données via OnCalculate.

                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[])
 
Alain Verleyen #:
Merci Alain.