Indicateurs: Bollinger Squeeze Basic MT5

 

Bollinger Squeeze Basic MT5:

L'indicateur Bollinger Squeeze Basic MetaTrader - est un indicateur complexe basé sur le Momentum, les bandes de Bollinger et le canal de Keltner. L'indicateur est dessiné dans une fenêtre séparée du graphique sous la forme d'un histogramme de Momentum et d'une gamme de points montrant la relation entre les valeurs actuelles des bandes de Bollinger et du canal de Keltner. Cet indicateur est disponible pour les versions MT4 et MT5 de la plateforme de trading.

Bollinger Squeeze Basic MT5

Author: Tuan Nguyen Van

 
On dirait une tendance et une confirmation dans le même indicateur. intéressant !
 

Bonjour Merci d'avoir partagé le code de votre indicateur, j'ai essayé de convertir l'indicateur Sqeeze Momentum de Trading View, voici le code que j'ai... c'est un peu différent... J'aimerais que vous me disiez ce que vous en pensez ! J'aimerais que vous me contactiez à ce sujet.


//+------------------------------------------------------------------------+
//|SqueezeMomentumIndicator.mq5 |
//|Converti à partir de Pine Script par LazyBear |
//||
//+------------------------------------------------------------------------+
#property copyright "Converted from Pine Script by LazyBear"
#property link      ""
#property version   "1.02"
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   2
#property indicator_type1   DRAW_COLOR_HISTOGRAM
#property indicator_color1  clrLime, clrGreen, clrRed, clrMaroon
#property indicator_style1  STYLE_SOLID
#property indicator_width1  4
#property indicator_label1  "Squeeze Momentum"
#property indicator_type2   DRAW_COLOR_LINE
#property indicator_color2  clrBlue, clrBlack, clrGray
#property indicator_style2  STYLE_SOLID
#property indicator_width2  2
#property indicator_label2  "Squeeze"

//--- paramètres d'entrée
input int    LengthBB = 20;         // Longueur BB
input double MultBB = 2.0;          // BB MultFactor
input int    LengthKC = 20;         // Longueur KC
input double MultKC = 1.5;          // KC MultFactor
input bool   UseTrueRange = true;   // Utiliser TrueRange (KC)

//--- tampons d'indicateurs
double MomentumBuffer[];       // Valeurs d'impulsion
double MomentumColorBuffer[];  // Couleurs de l'élan
double SqueezeBuffer[];        // Valeurs de compression
double SqueezeColorBuffer[];   // Presser les couleurs

//+------------------------------------------------------------------+
//| Fonction d'initialisation de l'indicateur personnalisé|
//+------------------------------------------------------------------+
int OnInit()
{
   //--- cartographie des tampons d'indicateurs
   SetIndexBuffer(0, MomentumBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, MomentumColorBuffer, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, SqueezeBuffer, INDICATOR_DATA);
   SetIndexBuffer(3, SqueezeColorBuffer, INDICATOR_COLOR_INDEX);
   
   //--- définir les indices de couleur
   PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 4); // 4 couleurs pour l'histogramme
   PlotIndexSetInteger(1, PLOT_COLOR_INDEXES, 3); // 3 couleurs pour la ligne
   
   //--- définir le nom de l'indicateur
   IndicatorSetString(INDICATOR_SHORTNAME, "SQZMOM_LB [LazyBear]");
   
   //--- fixer la précision
   IndicatorSetInteger(INDICATOR_DIGITS, 5);
   
   //--- définir les tableaux comme des séries
   ArraySetAsSeries(MomentumBuffer, true);
   ArraySetAsSeries(MomentumColorBuffer, true);
   ArraySetAsSeries(SqueezeBuffer, true);
   ArraySetAsSeries(SqueezeColorBuffer, true);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Moyenne mobile simple|
//+------------------------------------------------------------------+
double SimpleMA(const double &price[], int period, int shift)
{
   double sum = 0.0;
   for(int i = 0; i < period; i++)
   {
      sum += price[shift + i];
   }
   return sum / period;
}

//+------------------------------------------------------------------+
//| Écart-type|
//+------------------------------------------------------------------+
double StdDev(const double &price[], int period, int shift)
{
   double avg = SimpleMA(price, period, shift);
   double sum = 0.0;
   
   for(int i = 0; i < period; i++)
   {
      sum += MathPow(price[shift + i] - avg, 2);
   }
   
   return MathSqrt(sum / period);
}

//+------------------------------------------------------------------+
//| Régression linéaire|
//+------------------------------------------------------------------+
double LinReg(const double &price[], int period, int shift)
{
   double sum_x = 0.0;
   double sum_y = 0.0;
   double sum_xy = 0.0;
   double sum_x2 = 0.0;
   
   for(int i = 0; i < period; i++)
   {
      sum_x += i;
      sum_y += price[shift + i];
      sum_xy += i * price[shift + i];
      sum_x2 += i * i;
   }
   
   double m = period;
   double slope = (m * sum_xy - sum_x * sum_y) / (m * sum_x2 - sum_x * sum_x);
   double intercept = (sum_y - slope * sum_x) / m;
   
   return intercept;
}

//+------------------------------------------------------------------+
//| 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[])
{
   // Vérifier les données minimales
   int min_bars = MathMax(LengthBB, LengthKC) + 1;
   if(rates_total < min_bars) return(0);
   
   // Définir les tableaux comme des séries pour une indexation correcte
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);
   
   // Calculer le point de départ
   int limit;
   if(prev_calculated == 0)
      limit = rates_total - min_bars;
   else
      limit = rates_total - prev_calculated;
   
   limit = MathMin(limit, rates_total - min_bars);
   
   // Préparer les tableaux pour le calcul de la source
   double source[];
   ArrayResize(source, rates_total);
   ArraySetAsSeries(source, true);
   
   // Boucle de calcul principale
   for(int i = limit; i >= 0; i--)
   {
      // Calculer les bandes de Bollinger
      double basis = 0.0;
      for(int j = 0; j < LengthBB; j++)
         basis += close[i+j];
      basis /= LengthBB;
      
      double dev = 0.0;
      for(int j = 0; j < LengthBB; j++)
         dev += MathPow(close[i+j] - basis, 2);
      dev = MultBB * MathSqrt(dev / LengthBB);
      
      double upperBB = basis + dev;
      double lowerBB = basis - dev;
      
      // Calculer les canaux de Keltner
      double ma = 0.0;
      for(int j = 0; j < LengthKC; j++)
         ma += close[i+j];
      ma /= LengthKC;
      
      double range_sum = 0.0;
      for(int j = 0; j < LengthKC; j++)
      {
         double tr;
         if(UseTrueRange && i+j+1 < rates_total)
            tr = MathMax(high[i+j] - low[i+j], 
                 MathMax(MathAbs(high[i+j] - close[i+j+1]), 
                         MathAbs(low[i+j] - close[i+j+1])));
         else
            tr = high[i+j] - low[i+j];
         
         range_sum += tr;
      }
      double range_ma = range_sum / LengthKC;
      
      double upperKC = ma + MultKC * range_ma;
      double lowerKC = ma - MultKC * range_ma;
      
      // Calculer les conditions de compression
      bool sqzOn = (lowerBB > lowerKC) && (upperBB < upperKC);
      bool sqzOff = (lowerBB < lowerKC) && (upperBB > upperKC);
      bool noSqz = !sqzOn && !sqzOff;
      
      // Trouver le plus haut et le plus bas pour la période KC
      double highest = high[i];
      double lowest = low[i];
      
      for(int j = 1; j < LengthKC; j++)
      {
         if(i+j >= rates_total) break;
         if(high[i+j] > highest) highest = high[i+j];
         if(low[i+j] < lowest) lowest = low[i+j];
      }
      
      // Calculer la source pour linreg
      double avg_hl = (highest + lowest) / 2;
      double avg_val = (avg_hl + ma) / 2;
      
      for(int j = 0; j < LengthKC; j++)
      {
         if(i+j >= rates_total) break;
         source[i+j] = close[i+j] - avg_val;
      }
      
      // Calcul de l'élan par régression linéaire
      MomentumBuffer[i] = LinReg(source, LengthKC, i);
      
      // Fixe la valeur de la ligne de squeeze (toujours 0)
      SqueezeBuffer[i] = 0;
      
      // Définir les couleurs en fonction des conditions, exactement comme dans Pine Script
      // bcolor = iff(val > 0, iff(val > nz(val[1]), lime, green), iff(val < nz(val[1]), red, maroon))
      if(i < rates_total - 1)
      {
         if(MomentumBuffer[i] > 0)
         {
            if(MomentumBuffer[i] > MomentumBuffer[i+1])
               MomentumColorBuffer[i] = 0; // citron vert
            else
               MomentumColorBuffer[i] = 1; // vert
         }
         else
         {
            if(MomentumBuffer[i] < MomentumBuffer[i+1])
               MomentumColorBuffer[i] = 2; // rouge
            else
               MomentumColorBuffer[i] = 3; // marron
         }
      }
      else
      {
         // Pour la première barre
         MomentumColorBuffer[i] = (MomentumBuffer[i] > 0) ? 0 : 2; // citron vert ou rouge
      }
      
      // scolor = noSqz ? blue : sqzOn ? black : gray
      if(noSqz)
         SqueezeColorBuffer[i] = 0; // bleu
      else if(sqzOn)
         SqueezeColorBuffer[i] = 1; // noir
      else
         SqueezeColorBuffer[i] = 2; // gris
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+



Dossiers :