ArrayMaximum

Recherche le plus grand élément dans la première dimension d'un tableau numérique à plusieurs dimensions.

int  ArrayMaximum(
   const void&   array[],             // tableau où effectuer la recherche
   int           start=0,             // indice de début de recherche
   int           count=WHOLE_ARRAY    // nombre d'éléments à vérifier
   );

Paramètres

array[]

[in]  Le tableau numérique dans lequel la recherche est faite.

start=0

[in]  Indice de début de la recherche.

count=WHOLE_ARRAY

[in]  Nombre d'éléments sur lesquels effectuer la recherche. Par défaut, la recherche s'effectue sur le tableau en entier (count=WHOLE_ARRAY).

Valeur de Retour

La fonction retourne l'indice de l'élément trouvé en tenant compte de la série du tableau. Encas d'échec, retourne -1.

Note

La valeur du flag AS_SERIES est prise en compte lors de la recherche du maximum.

Les fonctions ArrayMaximum et ArrayMinimum acceptent des tableaux de n'importe quelle dimension comme paramètre. Cependant, la recherche est toujours effectuée sur la première (zéro) dimension.

Exemple :

#property description "L'indicateur affiche les bougies d'une période supérieure sur les bougies actuelles."
//--- paramètres de l'indicateur
#property indicator_chart_window
#property indicator_buffers 16
#property indicator_plots   8
//---- plot 1
#property indicator_label1  "BearBody"
#property indicator_color1  clrSeaGreen,clrSeaGreen
//---- plot 2
#property indicator_label2  "BearBodyEnd"
#property indicator_color2  clrSeaGreen,clrSeaGreen
//---- plot 3
#property indicator_label3  "BearShadow"
#property indicator_color3  clrSalmon,clrSalmon
//---- plot 4
#property indicator_label4  "BearShadowEnd"
#property indicator_color4  clrSalmon,clrSalmon
//---- plot 5
#property indicator_label5  "BullBody"
#property indicator_color5  clrOlive,clrOlive
//---- plot 6
#property indicator_label6  "BullBodyEnd"
#property indicator_color6  clrOlive,clrOlive
//---- plot 7
#property indicator_label7  "BullShadow"
#property indicator_color7  clrSkyBlue,clrSkyBlue
//---- plot 8
#property indicator_label8  "BullShadowEnd"
#property indicator_color8  clrSkyBlue,clrSkyBlue
//--- constantes prédéfinies
#define INDICATOR_EMPTY_VALUE 0.0
//--- paramètres d'entrée
input ENUM_TIMEFRAMES InpPeriod=PERIOD_H4;              // Période de calcul de l'indicateur
input datetime        InpDateStart=D'2013.01.01 00:00'; // Date de début de l'analyse
//--- buffers de l'indicateur pour les bougies baissières
double   ExtBearBodyFirst[];
double   ExtBearBodySecond[];
double   ExtBearBodyEndFirst[];
double   ExtBearBodyEndSecond[];
double   ExtBearShadowFirst[];
double   ExtBearShadowSecond[];
double   ExtBearShadowEndFirst[];
double   ExtBearShadowEndSecond[];
//--- buffers de l'indicateur pour les bougies haussières
double   ExtBullBodyFirst[];
double   ExtBullBodySecond[];
double   ExtBullBodyEndFirst[];
double   ExtBullBodyEndSecond[];
double   ExtBullShadowFirst[];
double   ExtBullShadowSecond[];
double   ExtBullShadowEndFirst[];
double   ExtBullShadowEndSecond[];
//--- variables globales
datetime ExtTimeBuff[];      // buffer de la période supérieure
int      ExtSize=0;          // taille du buffer
int      ExtCount=0;         // indice dans le buffer
int      ExtStartPos=0;      // position initiale pour le calcul de l'indicateur
bool     ExtStartFlag=true;  // flag supplémentaire pour conserver la position initiale
datetime ExtCurrentTime[1];  // dernière heure de la génération de la barre de la période supérieure
datetime ExtLastTime;        // dernière heure de la période supérieure pour laquelle le calcul est effectué
bool     ExtBearFlag=true;   // flag pour définir l'ordre d'écriture des données dans les buffers baissiers de l'indicateur
bool     ExtBullFlag=true;   // flag pour définir l'ordre d'écriture des données dans les buffers haussiers de l'indicateur
int      ExtIndexMax=0;      // indice de l'élément maximum du tableau
int      ExtIndexMin=0;      // indice de l'élément minimum du tableau
int      ExtDirectionFlag=0; // direction du mouvement des prix pour la bougie courante
//--- décalage entre les prix open et close de la bougie pour un dessin correct
const double ExtEmptyBodySize=0.2*SymbolInfoDouble(Symbol(),SYMBOL_POINT);
//+------------------------------------------------------------------+
//| Remplissage de la partie basique de la bougie                    |
//+------------------------------------------------------------------+
void FillCandleMain(const double &open[],const double &close[],
                    const double &high[],const double &low[],
                    const int start,const int last,const int fill_index,
                    int &index_max,int &index_min)
  {
//--- trouve l'indice des éléments maximum et minimum des tableaux
   index_max=ArrayMaximum(high,ExtStartPos,last-start+1); // maximum des High
   index_min=ArrayMinimum(low,ExtStartPos,last-start+1);  // minimum des Low
//--- définit combien de barre de la période actuelle doivent être remplies
   int count=fill_index-start+1;
//--- si le prix de clôture de la première barre est supérieur à celui de la dernière barre, la bougie est baissière
   if(open[start]>close[last])
     {
      //--- si la bougie était haussière avant, efface les valeurs des buffers haussiers de l'indicateur
      if(ExtDirectionFlag!=-1)
         ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,start,count);
      //--- bougie baissière
      ExtDirectionFlag=-1;
      //--- génère la bougie
      FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open[start],
                     close[last],high[index_max],low[index_min],start,count,ExtBearFlag);
      //--- sort de la fonction
      return;
     }
//--- si le prix de clôture de la première barre est inférieur à celui de la dernière barre, la bougie est haussière
   if(open[start]<close[last])
     {
      //--- si la bougie était baissière avant, efface les valeurs des buffers baissiers de l'indicateur
      if(ExtDirectionFlag!=1)
         ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,start,count);
      //--- bougie haussière
      ExtDirectionFlag=1;
      //--- génère la bougie
      FormCandleMain(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,close[last],
                     open[start],high[index_max],low[index_min],start,count,ExtBullFlag);
      //--- sort de la fonction             
      return;
     }
//--- si vous arrivez dans cette partie de la fonction, le prix d'ouverture de la première barre est égal au
//--- prix de clôture de la dernière barre ; une telle bougie est considérée comme baissière
//--- si la bougie était haussière avant, efface les valeurs des buffers haussiers de l'indicateur
   if(ExtDirectionFlag!=-1)
      ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,start,count);
//--- bougie baissière
   ExtDirectionFlag=-1;
//--- si les prix de clôture et d'ouverture sont égaux, utilise le décalage pour un affichage correct
   if(high[index_max]!=low[index_min])
      FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,open[start],
                     open[start]-ExtEmptyBodySize,high[index_max],low[index_min],start,count,ExtBearFlag);
   else
      FormCandleMain(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,
                     open[start],open[start]-ExtEmptyBodySize,high[index_max],
                     high[index_max]-ExtEmptyBodySize,start,count,ExtBearFlag);
  }
//+------------------------------------------------------------------+
//| Remplit la fin de la bougie                                      |
//+------------------------------------------------------------------+
void FillCandleEnd(const double &open[],const double &close[],
                   const double &high[],const double &low[],
                   const int start,const int last,const int fill_index,
                   const int index_max,const int index_min)
  {
//--- ne dessine pas dans le cas d'une barre seule
   if(last-start==0)
      return;
//--- si le prix de clôture de la première barre est supérieur à celui de la dernière barre, la bougie est baissière
   if(open[start]>close[last])
     {
      //--- génère la fin de la bougie
      FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,
                    open[start],close[last],high[index_max],low[index_min],fill_index,ExtBearFlag);
      //--- sort de la fonction
      return;
     }
//--- si le prix de clôture de la première barre est inférieur à celui de la dernière barre, la bougie est haussière
   if(open[start]<close[last])
     {
      //--- génère la fin de la bougie
      FormCandleEnd(ExtBullBodyEndFirst,ExtBullBodyEndSecond,ExtBullShadowEndFirst,ExtBullShadowEndSecond,
                    close[last],open[start],high[index_max],low[index_min],fill_index,ExtBullFlag);
      //--- sort de la fonction
      return;
     }
//--- si vous arrivez dans cette partie de la fonction, le prix d'ouverture de la première barre est égal au
//--- prix de clôture de la dernière barre ; une telle bougie est considérée comme baissière
//--- génère la fin de la bougie
   if(high[index_max]!=low[index_min])
      FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,open[start],
                    open[start]-ExtEmptyBodySize,high[index_max],low[index_min],fill_index,ExtBearFlag);
   else
      FormCandleEnd(ExtBearBodyEndFirst,ExtBearBodyEndSecond,ExtBearShadowEndFirst,ExtBearShadowEndSecond,open[start],
                    open[start]-ExtEmptyBodySize,high[index_max],high[index_max]-ExtEmptyBodySize,fill_index,ExtBearFlag);
  }
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé           |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- vérifie la période de l'indicateur
   if(!CheckPeriod((int)Period(),(int)InpPeriod))
      return(INIT_PARAMETERS_INCORRECT);
//--- affiche les prix au premier plan
   ChartSetInteger(0,CHART_FOREGROUND,0,1);
//--- lie les buffers de l'indicateur
   SetIndexBuffer(0,ExtBearBodyFirst);
   SetIndexBuffer(1,ExtBearBodySecond);
   SetIndexBuffer(2,ExtBearBodyEndFirst);
   SetIndexBuffer(3,ExtBearBodyEndSecond);
   SetIndexBuffer(4,ExtBearShadowFirst);
   SetIndexBuffer(5,ExtBearShadowSecond);
   SetIndexBuffer(6,ExtBearShadowEndFirst);
   SetIndexBuffer(7,ExtBearShadowEndSecond);
   SetIndexBuffer(8,ExtBullBodyFirst);
   SetIndexBuffer(9,ExtBullBodySecond);
   SetIndexBuffer(10,ExtBullBodyEndFirst);
   SetIndexBuffer(11,ExtBullBodyEndSecond);
   SetIndexBuffer(12,ExtBullShadowFirst);
   SetIndexBuffer(13,ExtBullShadowSecond);
   SetIndexBuffer(14,ExtBullShadowEndFirst);
   SetIndexBuffer(15,ExtBullShadowEndSecond);
//--- définit certaines propriétés pour créer l'indicateur
   for(int i=0;i<8;i++)
     {
      PlotIndexSetInteger(i,PLOT_DRAW_TYPE,DRAW_FILLING); // type de construction graphique
      PlotIndexSetInteger(i,PLOT_LINE_STYLE,STYLE_SOLID); // style de ligne
      PlotIndexSetInteger(i,PLOT_LINE_WIDTH,1);           // largeur de ligne
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Fonction d'itération de l'indicateur personnalisé                |
//+------------------------------------------------------------------+
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[])
  {
//--- dans le cas où aucune barre n'est encore calculée
   if(prev_calculated==0)
     {
      //--- récupère l'heure d'arrivée de la barre de la plus grande période
      if(!GetTimeData())
         return(0);
     }
//--- définit l'indexation directe
   ArraySetAsSeries(time,false);
   ArraySetAsSeries(high,false);
   ArraySetAsSeries(low,false);
   ArraySetAsSeries(open,false);
   ArraySetAsSeries(close,false);
//--- variable de départ pour le calcul des barres
   int start=prev_calculated;
//--- si la barre est générée, recalcule la valeur de l'indicateur
   if(start!=0 && start==rates_total)
      start--;
//--- boucle de calcul des valeurs de l'indicateur
   for(int i=start;i<rates_total;i++)
     {
      //--- remplit i éléments des buffers de l'indicateur avec des valeurs vides
      FillIndicatorBuffers(i);
      //--- effectue le calcul des barres commençant à la date InpDateStart
      if(time[i]>=InpDateStart)
        {
         //--- définit la position à partir de laquelle les valeurs sont affichées pour la première fois
         if(ExtStartFlag)
           {
            //--- stocke le numéro de la barre initiale
            ExtStartPos=i;
            //--- définit la première date de la période supérieure excédant time[i]
            while(time[i]>=ExtTimeBuff[ExtCount])
               if(ExtCount<ExtSize-1)
                  ExtCount++;
            //--- change la valeur du flag afin de ne pas exécuter ce bloc à nouveau
            ExtStartFlag=false;
           }
         //--- vérifie s'il reste des éléments dans le tableau
         if(ExtCount<ExtSize)
           {
            //--- attend que la valeur time actuelle atteigne celle de la période supérieure
            if(time[i]>=ExtTimeBuff[ExtCount])
              {
               //--- dessine la partie principale de la bougie (sans remplir la zone entre les deux dernières barres)
               FillCandleMain(open,close,high,low,ExtStartPos,i-1,i-2,ExtIndexMax,ExtIndexMin);
               //--- remplit la fin de la bougie (la zone entre les deux dernières barres)
               FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
               //--- décale la position initiale pour dessiner la prochaine bougie
               ExtStartPos=i;
               //--- augmente le compteur du tableau
               ExtCount++;
              }
            else
               continue;
           }
         else
           {
            //--- réinitialise les valeurs du tableau
            ResetLastError();
            //--- récupère la dernière date depuis la période supérieure
            if(CopyTime(Symbol(),InpPeriod,0,1,ExtCurrentTime)==-1)
              {
               Print("Erreur de copie des données, code = ",GetLastError());
               return(0);
              }
            //--- si la nouvelle date est plus tard, stoppe la génération des bougies
            if(ExtCurrentTime[0]>ExtLastTime)
              {
               //--- efface la zone entre les deux dernières barres dans les buffers principaux de l'indicateur
               ClearEndOfBodyMain(i-1);
               //--- remplit la zone avec les buffers supplémentaires de l'indicateur
               FillCandleEnd(open,close,high,low,ExtStartPos,i-1,i-1,ExtIndexMax,ExtIndexMin);
               //--- décale la position initiale pour dessiner la prochaine bougie
               ExtStartPos=i;
               //--- réinitialise le flag de diraction du prix
               ExtDirectionFlag=0;
               //--- stocke la nouvelle dernière date
               ExtLastTime=ExtCurrentTime[0];
              }
            else
              {
               //--- génère la bougie
               FillCandleMain(open,close,high,low,ExtStartPos,i,i,ExtIndexMax,ExtIndexMin);
              }
           }
        }
     }
//--- retourne la valeur de prev_calculated pour le prochain appel
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Vérifie la validité de la période spécifiée de l'indicateur      |
//+------------------------------------------------------------------+
bool CheckPeriod(int current_period,int high_period)
  {
//--- la période de l'indicateur ne devrait pas être supérieure à la période du graphique sur lequel il est affiché
   if(current_period>=high_period)
     {
      Print("Erreur ! La valeur de la période de l'indicateur devrait excéder la valeur de la période actuelle !");
      return(false);
     }
//--- si la période de l'indicateur est une semaine ou un mois, la période est correcte
   if(high_period>32768)
      return(true);
//--- convertit les valeurs de la période en minutes
   if(high_period>30)
      high_period=(high_period-16384)*60;
   if(current_period>30)
      current_period=(current_period-16384)*60;
//--- la période de l'indicateur devrait être un multiple de la période sur laquelle il est affiché
   if(high_period%current_period!=0)
     {
      Print("Erreur ! La valeur de la période de l'indicateur devrait être un multiple de la valeur de la période actuelle !");
      return(false);
     }
//--- la période de l'indicateur devrait excéder la période sur laquelle il est affiché par 3 fois ou plus
   if(high_period/current_period<3)
     {
      Print("Erreur ! La période de l'indicateur devrait excéder la période actuelle par 3 fois ou plus !");
      return(false);
     }
//--- la période de l'indicateur est correcte pour la période actuelle
   return(true);
  }
//+------------------------------------------------------------------+
//| Récupère les données time de la période supérieure               |
//+------------------------------------------------------------------+
bool GetTimeData(void)
  {
//--- réinitialise la valeur d'erreur
   ResetLastError();
//--- copie toutes les données pour l'heure actuelle
   if(CopyTime(Symbol(),InpPeriod,InpDateStart,TimeCurrent(),ExtTimeBuff)==-1)
     {
      //--- récupère le code d'erreur
      int code=GetLastError();
      //--- affiche le message d'erreur
      PrintFormat("Erreur de copie des données ! %s",code==4401
                  ? "L'historique est toujours en cours de chargement !"
                  : "Code = "+IntegerToString(code));
      //--- retourne false pour effectuer une tentative répétée de téléchargement des données
      return(false);
     }
//--- récupère la taille du tableau
   ExtSize=ArraySize(ExtTimeBuff);
//--- définit l'indice de la boucle pour le tableau à zéro
   ExtCount=0;
//--- définit la position de la bougie actuelle à zéro
   ExtStartPos=0;
   ExtStartFlag=true;
//--- stocke la dernière valeur time de la période supérieure
   ExtLastTime=ExtTimeBuff[ExtSize-1];
//--- exécution réussie
   return(true);
  }
//+--------------------------------------------------------------------------+
//| La fonction forme la partie principale de la bougie. Suivant la valeur |
//| du flag, la fonction définit quelles données et quels tableaux seront    |
//| utilisés pour un affichage correct.                                      |
//+--------------------------------------------------------------------------+
void FormCandleMain(double &body_fst[],double &body_snd[],
                    double &shadow_fst[],double &shadow_snd[],
                    const double fst_value,const double snd_value,
                    const double fst_extremum,const double snd_extremum,
                    const int start,const int count,const bool flag)
  {
//--- vérifie la valeur du flag
   if(flag)
     {
      //--- génère le corps de la bougie
      FormMain(body_fst,body_snd,fst_value,snd_value,start,count);
      //--- génère l'ombre de la bougie
      FormMain(shadow_fst,shadow_snd,fst_extremum,snd_extremum,start,count);
     }
   else
     {
      //--- génère le corps de la bougie
      FormMain(body_fst,body_snd,snd_value,fst_value,start,count);
      //--- génère l'ombre de la bougie
      FormMain(shadow_fst,shadow_snd,snd_extremum,fst_extremum,start,count);
     }
  }
//+-------------------------------------------------------------------------------+
//| La fonction forme la fin de la bougie. Suivant la valeur du flag, |
//| la fonction définit quelles données et quels tableaux seront                 |
//| utilisés pour un affichage correct.                                               |
//+-------------------------------------------------------------------------------+
void FormCandleEnd(double &body_fst[],double &body_snd[],
                   double &shadow_fst[],double &shadow_snd[],
                   const double fst_value,const double snd_value,
                   const double fst_extremum,const double snd_extremum,
                   const int end,bool &flag)
  {
//--- vérifie la valeur du flag
   if(flag)
     {
      //--- génère la fin du corps de la bougie
      FormEnd(body_fst,body_snd,fst_value,snd_value,end);
      //--- génère la fin de l'ombre de la bougie
      FormEnd(shadow_fst,shadow_snd,fst_extremum,snd_extremum,end);
      //--- change la valeur du flag à son opposé
      flag=false;
     }
   else
     {
      //--- génère la fin du corps de la bougie
      FormEnd(body_fst,body_snd,snd_value,fst_value,end);
      //--- génère la fin de l'ombre de la bougie
      FormEnd(shadow_fst,shadow_snd,snd_extremum,fst_extremum,end);
      //--- change la valeur du flag à son opposé
      flag=true;
     }
  }
//+---------------------------------------------------------------------------------+
//| Efface la fin de la bougie (la zone entre les deux dernières                    |
//| barres)                                                                         |
//+---------------------------------------------------------------------------------+
void ClearEndOfBodyMain(const int ind)
  {
   ClearCandle(ExtBearBodyFirst,ExtBearBodySecond,ExtBearShadowFirst,ExtBearShadowSecond,ind,1);
   ClearCandle(ExtBullBodyFirst,ExtBullBodySecond,ExtBullShadowFirst,ExtBullShadowSecond,ind,1);
  }
//+--------------------------------------------------------------------------+
//| Efface la bougie                                                         |
//+--------------------------------------------------------------------------+
void ClearCandle(double &body_fst[],double &body_snd[],double &shadow_fst[],
                 double &shadow_snd[],const int start,const int count)
  {
//--- vérification
   if(count!=0)
     {
      //--- remplit les buffers de l'indicateur avec des valeurs vides
      ArrayFill(body_fst,start,count,INDICATOR_EMPTY_VALUE);
      ArrayFill(body_snd,start,count,INDICATOR_EMPTY_VALUE);
      ArrayFill(shadow_fst,start,count,INDICATOR_EMPTY_VALUE);
      ArrayFill(shadow_snd,start,count,INDICATOR_EMPTY_VALUE);
     }
  }
//+--------------------------------------------------------------------------+
//| Génère la partie principale de la bougie                                 |
//+--------------------------------------------------------------------------+
void FormMain(double &fst[],double &snd[],const double fst_value,
              const double snd_value,const int start,const int count)
  {
//--- vérification
   if(count!=0)
     {
      //--- remplit les buffers de l'indicateur avec les valeurs
      ArrayFill(fst,start,count,fst_value);
      ArrayFill(snd,start,count,snd_value);
     }
  }
//+-----------------------------------------------------------------------------+
//| Génère la fin de la bougie                                                  |
//+-----------------------------------------------------------------------------+
void FormEnd(double &fst[],double &snd[],const double fst_value,
             const double snd_value,const int last)
  {
//--- remplit les buffers de l'indicateur avec les valeurs
   ArrayFill(fst,last-1,2,fst_value);
   ArrayFill(snd,last-1,2,snd_value);
  }
//+------------------------------------------------------------------+
//| Remplit l'élément i des buffers avec des valeurs vides           |
//+------------------------------------------------------------------+
void FillIndicatorBuffers(const int i)
  {
//--- définit une valeur vide dans la cellule des buffers de l'indicateur
   ExtBearBodyFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBearBodySecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBearShadowFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBearShadowSecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBearBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBearBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBearShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBearShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBullBodyFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBullBodySecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBullShadowFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBullShadowSecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBullBodyEndFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBullBodyEndSecond[i]=INDICATOR_EMPTY_VALUE;
   ExtBullShadowEndFirst[i]=INDICATOR_EMPTY_VALUE;
   ExtBullShadowEndSecond[i]=INDICATOR_EMPTY_VALUE;
  }