#property description "L'indicateur analyse les données du dernier mois et dessine toutes les bougies avec de faibles " #property description "et de gros volumes de ticks. Le tableau du volume des ticks est trié" #property description "pour déterminer ces bougies. Les bougies ayant un volume inférieur au premier pourcentage de" #property description "InpSmallVolume du tableau sont considérés comme faibles. Les bougies ayant un volume de ticks supérieurs au dernier" #property description "pourcent de InpBigVolume du tableau sont considérés comme gros." //--- paramètres de l'indicateur #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 1 //--- plot #property indicator_label1 "VolumeFactor" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrDodgerBlue,clrOrange #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- constantes prédéfinies #define INDICATOR_EMPTY_VALUE 0.0 //--- paramètres d'entrée input int InpSmallVolume=15; // Valeur en pourcentage des volumes faibles (<50) input int InpBigVolume=20; // Valeur en pourcentage des gros volumes (<50) //--- heure de début d'analyse (sera décalée) datetime ExtStartTime; //--- buffers de l'indicateur double ExtOpenBuff[]; double ExtHighBuff[]; double ExtLowBuff[]; double ExtCloseBuff[]; double ExtColorBuff[]; //--- valeurs limites de volume pour l'affichage des bougies long ExtLeftBorder=0; long ExtRightBorder=0; //+------------------------------------------------------------------+ //| Retourne les volumes des bordures pour les volumes de ticks | //+------------------------------------------------------------------+ bool GetVolumeBorders(void) { //--- variables datetime stop_time; // copie de l'heure de fin long buff[]; // buffer pour la copie //--- l'heure de fin est l'heure actuelle stop_time=TimeCurrent(); //--- l'heure de début est 1 mois plus tôt que l'heure actuelle ExtStartTime=GetStartTime(stop_time); //--- récupère les valeurs des volumes des ticks ResetLastError(); if(CopyTickVolume(Symbol(),Period(),ExtStartTime,stop_time,buff)==-1) { //--- échec de récupération des données, retourne false pour lancer la commande de calcul PrintFormat("Echec de récupération des valeurs de volume des ticks. Code d'erreur = %d",GetLastError()); return(false); } //--- calcule la taille du tableau int size=ArraySize(buff); //--- trie le tableau ArraySort(buff); //--- définit les valeurs des bordures gauches et droites pour les volumes des ticks ExtLeftBorder=buff[size*InpSmallVolume/100]; ExtRightBorder=buff[(size-1)*(100-InpBigVolume)/100]; //--- exécution réussie return(true); } //+------------------------------------------------------------------+ //| Récupère les données d'un mois auparavant | //+------------------------------------------------------------------+ datetime GetStartTime(const datetime stop_time) { //--- convertit l'heure de fin en une variable de type MqlDateTime MqlDateTime temp; TimeToStruct(stop_time,temp); //--- récupère les données d'un mois auparavant if(temp.mon>1) temp.mon-=1; // le mois courant n'est pas le premier de l'année, donc le numéro du mois précédent vaut 1 de moins else { temp.mon=12; // le mois courant est le premier de l'année, donc le numéro du mois précédent est 12, temp.year-=1; // et le numéro de l'année vaut 1 de moins } //--- le numéro du jour n'excédera pas 28 if(temp.day>28) temp.day=28; //--- retourne la date obtenue return(StructToTime(temp)); } //+------------------------------------------------------------------+ //| Fonction d'initialisation de l'indicateur personnalisé | //+------------------------------------------------------------------+ int OnInit() { //--- vérifie si les paramètres d'entrée satisfont les conditions if(InpSmallVolume<0 || InpSmallVolume>=50 || InpBigVolume<0 || InpBigVolume>=50) { Print("Paramètres d'entrée incorrects"); return(INIT_PARAMETERS_INCORRECT); } //--- mapping des buffers de l'indicateur SetIndexBuffer(0,ExtOpenBuff); SetIndexBuffer(1,ExtHighBuff); SetIndexBuffer(2,ExtLowBuff); SetIndexBuffer(3,ExtCloseBuff); SetIndexBuffer(4,ExtColorBuff,INDICATOR_COLOR_INDEX); //--- définit la valeur qui ne sera pas affichée PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE); //--- définit les étiquettes pour les buffers de l'indicateur 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[]) { //--- vérifie s'il y a toujours des barres non gérées if(prev_calculated<rates_total) { //--- récupère les nouvelles valeurs des bordures droite et gauche pour les volumes if(!GetVolumeBorders()) return(0); } //--- variable de départ pour le calcul de la barre int start=prev_calculated; //--- travaille sur la dernière barre si les valeurs de l'indicateur ont déjà été calculées sur le tick précédent if(start>0) start--; //--- définit l'indexation directe des timeseries ArraySetAsSeries(time,false); ArraySetAsSeries(open,false); ArraySetAsSeries(high,false); ArraySetAsSeries(low,false); ArraySetAsSeries(close,false); ArraySetAsSeries(tick_volume,false); //--- boucle de calcul des valeurs de l'indicateur for(int i=start;i<rates_total;i++) { //--- remplit les bougies commençant à la date initiale if(ExtStartTime<=time[i]) { //--- si la valeur n'est pas inférieure à la bordure droite, remplit la bougie if(tick_volume[i]>=ExtRightBorder) { //--- détermine les données pour dessiner la bougie ExtOpenBuff[i]=open[i]; ExtHighBuff[i]=high[i]; ExtLowBuff[i]=low[i]; ExtCloseBuff[i]=close[i]; //--- DodgerBlue color ExtColorBuff[i]=0; //--- continue la boucle continue; } //--- remplit les bougies si les valeurs ne sont pas supérieures à la bordure gauche if(tick_volume[i]<=ExtLeftBorder) { //--- détermine les données pour dessiner la bougie ExtOpenBuff[i]=open[i]; ExtHighBuff[i]=high[i]; ExtLowBuff[i]=low[i]; ExtCloseBuff[i]=close[i]; //--- couleur orange ExtColorBuff[i]=1; //--- continue la boucle continue; } } //--- définit les valeurs vides des barres n'ayant pas été incluses dans le calcul ExtOpenBuff[i]=INDICATOR_EMPTY_VALUE; ExtHighBuff[i]=INDICATOR_EMPTY_VALUE; ExtLowBuff[i]=INDICATOR_EMPTY_VALUE; ExtCloseBuff[i]=INDICATOR_EMPTY_VALUE; } //--- retourne la valeur de prev_calculated pour le prochain appel return(rates_total); } |