【MQL5】ボタンから±1σ~±3σのボリンジャーバンドを表示させるコード

ボタンからボリンジャーバンド

【MQL5】ボタンから±1σ~±3σのボリンジャーバンドを表示させるコードを公開しています。ボリンジャーバンドの表示方法からボタン処理によりON・OFFのやり方まで丸わかりです。

ボタンから±1σ~±3σのボリンジャーバンドを表示させるコード


//+------------------------------------------------------------------+
//| BB Full (±1σ, ±2σ, ±3σ) Happy Colors                        |
//+------------------------------------------------------------------+
#property strict
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots   7

//--- ±3σ
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrMediumSpringGreen
#property indicator_width1 1
#property indicator_label1 "+3σ"

#property indicator_type2 DRAW_LINE
#property indicator_color2 clrMediumSpringGreen
#property indicator_width2 1
#property indicator_label2 "-3σ"

//--- ±2σ
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrDodgerBlue
#property indicator_width3 1
#property indicator_label3 "+2σ"

#property indicator_type4 DRAW_LINE
#property indicator_color4 clrDodgerBlue
#property indicator_width4 1
#property indicator_label4 "-2σ"

//--- ±1σ
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrTomato
#property indicator_width5 1
#property indicator_label5 "+1σ"

#property indicator_type6 DRAW_LINE
#property indicator_color6 clrTomato
#property indicator_width6 1
#property indicator_label6 "-1σ"

//--- Middle
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrDeepSkyBlue
#property indicator_width7 1
#property indicator_label7 "Middle"

//--- Buffers
double BBUpper3[], BBLower3[], BBUpper2[], BBLower2[];
double BBUpper1[], BBLower1[], BBMiddle[], close[];

string BtnBB = "BtnBB";
bool UseBBTouch = true;

int OnInit()
{
    SetIndexBuffer(0, BBUpper3, INDICATOR_DATA);
    SetIndexBuffer(1, BBLower3, INDICATOR_DATA);
    SetIndexBuffer(2, BBUpper2, INDICATOR_DATA);
    SetIndexBuffer(3, BBLower2, INDICATOR_DATA);
    SetIndexBuffer(4, BBUpper1, INDICATOR_DATA);
    SetIndexBuffer(5, BBLower1, INDICATOR_DATA);
    SetIndexBuffer(6, BBMiddle, INDICATOR_DATA);

    CreateBBButton();
    ChartSetInteger(0, CHART_EVENT_MOUSE_MOVE, true);
    return INIT_SUCCEEDED;
}

int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[])
{
    if (rates_total < 20) return rates_total;
    if (!CopyClose(_Symbol, _Period, 0, rates_total, close))
        return rates_total;

    if (UseBBTouch)
        CalculateBB(rates_total);

    return rates_total;
}

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
    if (id == CHARTEVENT_OBJECT_CLICK && sparam == BtnBB)
    {
        UseBBTouch = !UseBBTouch;
        UpdateBBButton();

        // 強制的にBB再計算&描画(ティックがなくても対応)
        if (!CopyClose(_Symbol, _Period, 0, Bars(_Symbol, _Period), close))
            return;

        CalculateBB(Bars(_Symbol, _Period));
        ChartRedraw();
    }
}

void CalculateBB(int total)
{
    int period = 20;
    int start = period - 1;

    ArrayInitialize(BBUpper3, EMPTY_VALUE);
    ArrayInitialize(BBLower3, EMPTY_VALUE);
    ArrayInitialize(BBUpper2, EMPTY_VALUE);
    ArrayInitialize(BBLower2, EMPTY_VALUE);
    ArrayInitialize(BBUpper1, EMPTY_VALUE);
    ArrayInitialize(BBLower1, EMPTY_VALUE);
    ArrayInitialize(BBMiddle, EMPTY_VALUE);

    if (!UseBBTouch) return;

    for (int i = start; i < total; i++)
    {
        double sum = 0.0, sumsq = 0.0;
        for (int j = i - period + 1; j <= i; j++)
        {
            sum += close[j];
            sumsq += close[j] * close[j];
        }
        double mean = sum / period;
        double variance = (sumsq - sum * mean) / period;
        double stddev = MathSqrt(MathMax(variance, 0.0));

        BBMiddle[i]  = mean;
        BBUpper1[i] = mean + stddev;
        BBLower1[i] = mean - stddev;
        BBUpper2[i] = mean + 2 * stddev;
        BBLower2[i] = mean - 2 * stddev;
        BBUpper3[i] = mean + 3 * stddev;
        BBLower3[i] = mean - 3 * stddev;
    }
}

void CreateBBButton()
{
    ObjectCreate(0, BtnBB, OBJ_BUTTON, 0, 0, 0);
    ObjectSetInteger(0, BtnBB, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    ObjectSetInteger(0, BtnBB, OBJPROP_XDISTANCE, 10);
    ObjectSetInteger(0, BtnBB, OBJPROP_YDISTANCE, 10);
    ObjectSetInteger(0, BtnBB, OBJPROP_XSIZE, 120);
    ObjectSetInteger(0, BtnBB, OBJPROP_YSIZE, 30);
    ObjectSetInteger(0, BtnBB, OBJPROP_COLOR, clrBlack);
    ObjectSetInteger(0, BtnBB, OBJPROP_BGCOLOR, clrWhite);
    ObjectSetInteger(0, BtnBB, OBJPROP_FONTSIZE, 10);
    UpdateBBButton();
}

void UpdateBBButton()
{
    ObjectSetString(0, BtnBB, OBJPROP_TEXT, UseBBTouch ? "☑BB表示ON" : "BB表示OFF");
}


#propertyの設定

プロパティ 内容
indicator_chart_window メインチャート上にラインを表示
indicator_buffers 7 7本のライン(±3σ, ±2σ, ±1σ, 中央線)を描画
indicator_colorX 各σラインに視認性の高いカラーを指定
indicator_labelX 各ラインにラベル名を設定(+1σなど)

バッファの定義

変数名 内容
BBUpper3[], BBLower3[] ±3σライン
BBUpper2[], BBLower2[] ±2σライン
BBUpper1[], BBLower1[] ±1σライン
BBMiddle[] 移動平均(中央線)

OnInit() の処理

処理内容 説明
SetIndexBuffer() 各バッファをインジケーター描画用として登録
CreateBBButton() 表示ON/OFFボタンをチャート上に作成
ChartSetInteger(…MOUSE_MOVE) マウスイベント検出を有効にする

OnCalculate() の処理

処理 内容
CopyClose() 終値配列(close[])を取得
CalculateBB() UseBBTouchがtrueのときのみ、ボリンジャーバンドを再計算
rates_total < 20 データ不足時は計算をスキップ

CalculateBB() のロジック

ステップ 処理内容
20期間の終値を集計
平均値 mean を算出
分散 → 標準偏差 stddev を計算
±1~±3σの各ラインを算出してバッファに代入

ボタン処理とイベント

関数・変数 役割
OnChartEvent() ボタンが押されたときに呼ばれ、表示のON/OFFを切替
UseBBTouch 表示切り替えフラグ(trueなら表示)
UpdateBBButton() ボタンのテキスト表示を更新(ON/OFF切替)

チャート停止時の再描画処理

処理 内容
CopyClose() 現在の終値を強制取得
CalculateBB() 取得した終値からバンドを再計算
ChartRedraw() チャート更新を手動でトリガー(ティックなし対応)