#property description "L'indicateur met en lumière les bougies qui sont des "
#property description "plus hauts et des plus bas locaux. La longueur de l'intervalle pour trouver"
#property description "les valeurs extrêmes est disponible dans les paramètres d'entrée."
//--- paramètres de l'indicateur
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//---- éléments dessinés
#property indicator_label1 "Extremums"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrLightSteelBlue,clrRed,clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- constantes prédéfinies
#define INDICATOR_EMPTY_VALUE 0.0
//--- paramètres d'entrée
input int InpNum=4; // Longueur d'une moitié d'intervalle
//--- buffers de l'indicateur
double ExtOpen[];
double ExtHigh[];
double ExtLow[];
double ExtClose[];
double ExtColor[];
//--- variables globales
int ExtStart=0; // indice de la première bougier qui n'est pas un extrême
int ExtCount=0; // nombre de non-extrêmes dans l'intervalle
//+------------------------------------------------------------------+
//| Remplissage des bougies non-extrêmes |
//+------------------------------------------------------------------+
void FillCandles(const double &open[],const double &high[],
const double &low[],const double &close[])
{
//--- remplit les bougies
ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount);
ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount);
}
//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé |
//+------------------------------------------------------------------+
int OnInit()
{
//--- mapping des buffers de l'indicateur
SetIndexBuffer(0,ExtOpen);
SetIndexBuffer(1,ExtHigh);
SetIndexBuffer(2,ExtLow);
SetIndexBuffer(3,ExtClose);
SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX);
//--- spécifie la valeur, qui n'est pas affichée
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE);
//--- spécifie les noms des buffers de l'indicateur pour les afficher dans la fenêtre des données
PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close");
//---
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[])
{
//--- définit l'indexation des timeseries
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
//--- variable du départ du calcul de la barre
int start=prev_calculated;
//--- le calcul n'est pas effectué pour les InpNum*2 premières barres
if(start==0)
{
start+=InpNum*2;
ExtStart=0;
ExtCount=0;
}
//--- si la barre vient juste de se former, vérifie l'extrême potentiel suivant
if(rates_total-start==1)
start--;
//--- indice de barre à vérifier pour l'extrême
int ext;
//--- boucle de calcul des valeurs de l'indicateur
for(int i=start;i<rates_total-1;i++)
{
//--- initialement sur une barre i sans dessin
ExtOpen[i]=0;
ExtHigh[i]=0;
ExtLow[i]=0;
ExtClose[i]=0;
//--- indice d'extrême pour vérification
ext=i-InpNum;
//--- vérifie le maximum local
if(IsMax(high,ext))
{
//--- met en avant la bougie d'extrême
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=1;
//--- met en avant les autres bougies jusqu'à l'extrême avec une couleur neutre
FillCandles(open,high,low,close);
//--- change les couleurs de la variable
ExtStart=ext+1;
ExtCount=0;
//--- passe à l'itération suivante
continue;
}
//--- vérifie le minimum local
if(IsMin(low,ext))
{
//--- met en avant la bougie d'extrême
ExtOpen[ext]=open[ext];
ExtHigh[ext]=high[ext];
ExtLow[ext]=low[ext];
ExtClose[ext]=close[ext];
ExtColor[ext]=2;
//--- met en avant les autres bougies jusqu'à l'extrême avec une couleur neutre
FillCandles(open,high,low,close);
//--- change les valeurs de la variable
ExtStart=ext+1;
ExtCount=0;
//--- passe à l'itération suivante
continue;
}
//--- augmente le nombre de non-extrêmes dans l'intervalle
ExtCount++;
}
//--- retourne la valeur de prev_calculated pour le prochain appel
return(rates_total);
}
//+------------------------------------------------------------------+
//| Vérifie si l'élément actuel du tableau est un plus haut local |
//+------------------------------------------------------------------+
bool IsMax(const double &price[],const int ind)
{
//--- variable de début de l'intervalle
int i=ind-InpNum;
//--- période de fin de l'intervalle
int finish=ind+InpNum+1;
//--- vérifie la première moitié de l'intervalle
for(;i<ind;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- vérifie la deuxième moitié de l'intervalle
for(i=ind+1;i<finish;i++)
{
if(price[ind]<=price[i])
return(false);
}
//--- c'est un extrême
return(true);
}
//+------------------------------------------------------------------+
//| Vérifie si l'élément actuel du tableau est un plus bas local |
//+------------------------------------------------------------------+
bool IsMin(const double &price[],const int ind)
{
//--- variable de début de l'intervalle
int i=ind-InpNum;
//--- variable de fin de l'intervalle
int finish=ind+InpNum+1;
//--- vérifie la première moitié de l'intervalle
for(;i<ind;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- vérifie la deuxième moitié de l'intervalle
for(i=ind+1;i<finish;i++)
{
if(price[ind]>=price[i])
return(false);
}
//--- c'est un extrême
return(true);
}
|