インディケータ: Bollinger Squeeze Basic MT5

 

Bollinger Squeeze Basic MT5:

ボリンジャー・スクイーズ・ベーシックMetaTraderインディケータは、モメンタム、ボリンジャーバンド、ケルトナーチャネルに基づく複雑なインディケータです。このインディケータは、現在のボリンジャーバンドとケルトナー チャネルの値の関係を示すモメンタムヒストグラムとドットの範囲 として、チャートの別ウィンドウに描画されます。このインディケータは、取引プラットフォームのMT4とMT5の両バージョンで利用可能です。

Bollinger Squeeze Basic MT5

Author: Tuan Nguyen Van

 
トレンドと確認が同じ指標のように聞こえる!
 

SqeezeMomentum Indicatorを Trading Viewから変換してみました。この件についてご意見をお聞かせください!ありがとうございました。


//+------------------------------------------------------------------------+
//|SqueezeMomentumIndicator.mq5
//|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"

//--- 入力パラメータ
input int    LengthBB = 20;         // BBの長さ
input double MultBB = 2.0;          // BBマルチファクター
input int    LengthKC = 20;         // KCの長さ
input double MultKC = 1.5;          // KCマルチファクター
input bool   UseTrueRange = true;   // トゥルーレンジ(KC)を使用

//--- インジケータ・バッファ
double MomentumBuffer[];       // モメンタム値
double MomentumColorBuffer[];  // モメンタムカラー
double SqueezeBuffer[];        // 値を絞る
double SqueezeColorBuffer[];   // スクイーズ・カラー

//+------------------------------------------------------------------+
//| カスタムインジケータ初期化関数|
//+------------------------------------------------------------------+
int OnInit()
{
   //--- インジケータ・バッファのマッピング
   SetIndexBuffer(0, MomentumBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, MomentumColorBuffer, INDICATOR_COLOR_INDEX);
   SetIndexBuffer(2, SqueezeBuffer, INDICATOR_DATA);
   SetIndexBuffer(3, SqueezeColorBuffer, INDICATOR_COLOR_INDEX);
   
   //--- カラーインデックスを設定する
   PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 4); // ヒストグラム用の4色
   PlotIndexSetInteger(1, PLOT_COLOR_INDEXES, 3); // ラインは3色
   
   //--- インジケータ名を設定する
   IndicatorSetString(INDICATOR_SHORTNAME, "SQZMOM_LB [LazyBear]");
   
   //--- 精度の設定
   IndicatorSetInteger(INDICATOR_DIGITS, 5);
   
   //--- 配列をシリーズとして設定する
   ArraySetAsSeries(MomentumBuffer, true);
   ArraySetAsSeries(MomentumColorBuffer, true);
   ArraySetAsSeries(SqueezeBuffer, true);
   ArraySetAsSeries(SqueezeColorBuffer, true);
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 単純移動平均|
//+------------------------------------------------------------------+
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;
}

//+------------------------------------------------------------------+
//| 標準偏差|
//+------------------------------------------------------------------+
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);
}

//+------------------------------------------------------------------+
| 線形回帰|
//+------------------------------------------------------------------+
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;
}

//+------------------------------------------------------------------+
//| カスタム・インジケータ反復関数|
//+------------------------------------------------------------------+
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 min_bars = MathMax(LengthBB, LengthKC) + 1;
   if(rates_total < min_bars) return(0);
   
   // 適切なインデックス付けのために、配列をシリーズとして設定する
   ArraySetAsSeries(high, true);
   ArraySetAsSeries(low, true);
   ArraySetAsSeries(close, true);
   
   // 開始点を計算する
   int limit;
   if(prev_calculated == 0)
      limit = rates_total - min_bars;
   else
      limit = rates_total - prev_calculated;
   
   limit = MathMin(limit, rates_total - min_bars);
   
   // ソース計算のために配列を準備する
   double source[];
   ArrayResize(source, rates_total);
   ArraySetAsSeries(source, true);
   
   // メインの計算ループ
   for(int i = limit; i >= 0; i--)
   {
      // ボリンジャーバンドの計算
      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;
      
      // ケルトナー・チャンネルの計算
      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;
      
      // スクイズ条件を計算する
      bool sqzOn = (lowerBB > lowerKC) && (upperBB < upperKC);
      bool sqzOff = (lowerBB < lowerKC) && (upperBB > upperKC);
      bool noSqz = !sqzOn && !sqzOff;
      
      // 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];
      }
      
      // 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;
      }
      
      // 線形回帰で運動量を計算する
      MomentumBuffer[i] = LinReg(source, LengthKC, i);
      
      // スクイズラインの値を設定する(常に0)
      SqueezeBuffer[i] = 0;
      
      // パインスクリプトとまったく同じように、条件に基づいて色を設定する。
      // bcolor = iff(val > 0, iff(val > nz(val[1]), ライム, グリーン), iff(val < nz(val[1]), レッド, マルーン))
      if(i < rates_total - 1)
      {
         if(MomentumBuffer[i] > 0)
         {
            if(MomentumBuffer[i] > MomentumBuffer[i+1])
               MomentumColorBuffer[i] = 0; // ライム
            else
               MomentumColorBuffer[i] = 1; // グリーン
         }
         else
         {
            if(MomentumBuffer[i] < MomentumBuffer[i+1])
               MomentumColorBuffer[i] = 2; // 赤
            else
               MomentumColorBuffer[i] = 3; // マルーン
         }
      }
      else
      {
         // 最初の小節
         MomentumColorBuffer[i] = (MomentumBuffer[i] > 0) ? 0 : 2; // ライムまたはレッド
      }
      
      // scolor = noSqz ? blue : sqzOn ? black : gray
      if(noSqz)
         SqueezeColorBuffer[i] = 0; // ブルー
      else if(sqzOn)
         SqueezeColorBuffer[i] = 1; // ブラック
      else
         SqueezeColorBuffer[i] = 2; // グレー
   }
   
   return(rates_total);
}
//+------------------------------------------------------------------+



ファイル: