これを応用すると、移動平均が上昇しているときは青、下降時は赤や、ボリンジャーバンドが狭まっている時とそうではないときで色を変えるといったプログラムが可能です。
さて、この特徴を生かし、色が変わるボリンジャーバンドを実装してみたいともいます。
こんな感じで、移動平均の上げ下げと、ボリンジャーバンドの拡大縮小によって線の色が変わります。
移動平均はさておき、ボリンジャーバンドだと、膨らんでいるように見えて実は収束を始めていたりします。色を変えるとこーいうところが分かりやすくなります。
プログラムは定義部分が長くなってしまいましたが、実際のコードは長くありません。状況に応じてバッファを切り替えています。
i+1にも値を設定しにいっているのは、バッファが切り替わる際(たとえば移動平均が上げから下げに変わるとき)線が途切れてしまうのを防止する為です。本当は切り替わり時しか必要ないのですが、ちょっと横着しました^^;;
//------------------------------------------------------------------
// 色が変わるボリンジャーバンド
#property copyright "Copyright 2015, Daisuke"
#property link "http://mt4program.blogspot.jp/"
#property version "1.00"
#property strict
#property indicator_chart_window
//バッファーを指定する。
#property indicator_buffers 10
//プロット数を指定する。
#property indicator_plots 10
#property indicator_label1 "CenterUp"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrAqua
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
#property indicator_label2 "HIGH1UP"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrSlateBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "HIGH2UP"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrSlateBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
#property indicator_label4 "LOW1UP"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrSlateBlue
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
#property indicator_label5 "LOW2UP"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrSlateBlue
#property indicator_style5 STYLE_SOLID
#property indicator_width5 1
#property indicator_label6 "CenterDown"
#property indicator_type6 DRAW_LINE
#property indicator_color6 clrIndianRed
#property indicator_style6 STYLE_SOLID
#property indicator_width6 1
#property indicator_label7 "HIGH1DOWN"
#property indicator_type7 DRAW_LINE
#property indicator_color7 clrWheat
#property indicator_style7 STYLE_SOLID
#property indicator_width7 1
#property indicator_label8 "HIGH2DOWN"
#property indicator_type8 DRAW_LINE
#property indicator_color8 clrWheat
#property indicator_style8 STYLE_SOLID
#property indicator_width8 1
#property indicator_label9 "LOW1DOWN"
#property indicator_type9 DRAW_LINE
#property indicator_color9 clrWheat
#property indicator_style9 STYLE_SOLID
#property indicator_width9 1
#property indicator_label10 "LOW2DOWN"
#property indicator_type10 DRAW_LINE
#property indicator_color10 clrWheat
#property indicator_style10 STYLE_SOLID
#property indicator_width10 1
// 入力パラメータ 移動平均期間
extern int MaPeriod = 21;
//入力パラメータ 表示移動
extern int MaShift = 0;
//入力パラメータ 移動平均種別
extern ENUM_MA_METHOD MaMethod = MODE_SMA;
//入力パラメータ 適用価格
extern ENUM_APPLIED_PRICE MaPrice = PRICE_MEDIAN;
//標準偏差期間
extern int StdPeriod = 21;
//標準偏差算出方法
extern ENUM_MA_METHOD StdMethod = MODE_SMA;
//σ1
extern double Sigma1 = 1;
//σ2
extern double Sigma2 = 2;
double centerUp[];
double high1Up[];
double high2Up[];
double low1Up[];
double low2Up[];
double centerDown[];
double high1Down[];
double high2Down[];
double low1Down[];
double low2Down[];
//------------------------------------------------------------------
//初期化
int OnInit()
{
//インジケーターバッファを初期化する。
SetIndexBuffer(0,centerUp);
SetIndexBuffer(1,high1Up);
SetIndexBuffer(2,high2Up);
SetIndexBuffer(3,low1Up);
SetIndexBuffer(4,low2Up);
SetIndexBuffer(5,centerDown);
SetIndexBuffer(6,high1Down);
SetIndexBuffer(7,high2Down);
SetIndexBuffer(8,low1Down);
SetIndexBuffer(9,low2Down);
SetIndexDrawBegin(0, MaPeriod);
SetIndexDrawBegin(1, MaPeriod);
SetIndexDrawBegin(2, MaPeriod);
SetIndexDrawBegin(3, MaPeriod);
SetIndexDrawBegin(4, MaPeriod);
SetIndexDrawBegin(5, MaPeriod);
SetIndexDrawBegin(6, MaPeriod);
SetIndexDrawBegin(7, MaPeriod);
SetIndexDrawBegin(8, MaPeriod);
SetIndexDrawBegin(9, MaPeriod);
string short_name = "ClBB(" + IntegerToString(MaPeriod) + ")";
IndicatorShortName(short_name);
return(INIT_SUCCEEDED);
}
//------------------------------------------------------------------
//計算イベント
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[]) //スプレット
{
for( int i = (rates_total - prev_calculated - 1); i >= 0 && !IsStopped(); i-- )
{
if( i >= rates_total - MaPeriod ) continue;
double ma1 = iMA(NULL, PERIOD_CURRENT, MaPeriod, 0, MaMethod, MaPrice, i);
double ma2 = iMA(NULL, PERIOD_CURRENT, MaPeriod, 0, MaMethod, MaPrice, i + 1);
// 移動平均の方向によって値を設定するバッファーを変更する。
if( ma1 < ma2 )
{
centerDown[i] = ma1;
centerDown[i + 1] = ma2;
}
else
{
centerUp[i] = ma1;
centerUp[i + 1] = ma2;
}
double std1 = iStdDev(NULL, PERIOD_CURRENT, StdPeriod, 0, StdMethod, MaPrice, i);
double std2 = iStdDev(NULL, PERIOD_CURRENT, StdPeriod, 0, StdMethod, MaPrice, i + 1);
// 標準偏差の大きさによって値を入れるバッファを切り替える。
if( std1 < std2 )
{
high1Down[i] = ma1 + std1 * Sigma1;
high2Down[i] = ma1 + std1 * Sigma2;
low1Down[i] = ma1 - std1 * Sigma1;
low2Down[i] = ma1 - std1 * Sigma2;
high1Down[i + 1] = ma2 + std2 * Sigma1;
high2Down[i + 1] = ma2 + std2 * Sigma2;
low1Down[i + 1] = ma2 - std2 * Sigma1;
low2Down[i + 1] = ma2 - std2 * Sigma2;
}
else
{
high1Up[i] = ma1 + std1 * Sigma1;
high2Up[i] = ma1 + std1 * Sigma2;
low1Up[i] = ma1 - std1 * Sigma1;
low2Up[i] = ma1 - std1 * Sigma2;
high1Up[i + 1] = ma2 + std2 * Sigma1;
high2Up[i + 1] = ma2 + std2 * Sigma2;
low1Up[i + 1] = ma2 - std2 * Sigma1;
low2Up[i + 1] = ma2 - std2 * Sigma2;
}
}
//元となる値を計算する。
return(rates_total - 1);
}