で作成した、マルチタイムフレーム機能付き、色が変わるボリンジャーバンドですが、マルチタイムで表示した際、過去の足に対して、現在形成中の足の値が表示されるのはよくないなということで、確定足だけ表示するようにしていました。
例えば、15分足で、1時間足のボリンジャーバンドを表示した際、
15分足 9:00足に1時間足の9:00の値をそのまま出してしまうと、9:15以降、確定しているはずの9:00の足の値は、まだ確定していない1時間足のボリンジャーバンドを確定値として表示してしまいます。
作った当初は、これはよくないなーと思い、確定した1時間足の8:00の値を表示していました。
コメントでご指摘いただいて、改めて思うと、表示シフトで、使用者が選べた方が良い気がします。
ということで、修正版です。
マルチタイムの際は、未確定となっている足すべての値を変更しに行きます。
(15分足9:00~9:45までの足は、9時台は常に更新される形です。)
■カラフルBBと、通常のBB(赤線) 旧バージョン
■カラフルBBと、通常のBB(赤線) 新バージョン
表示シフトのパラメータがありますので、従来通り確定足を表示することも可能です。
FX-ONからのダウンロードはこちらから。ソースコードは記事の最後に記載しています。
カラフルで、上位時間足のボリンジャーバンドが表示できます。
「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧
Twitterもよろしくお願いします。
https://twitter.com/mt4program
ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 |
お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。
ソースコードはこちらから
//------------------------------------------------------------------
// 色が変わるボリンジャーバンド 上位時間足版 アラート機能付き
#property copyright "Copyright 2015, Daisuke"
#property link "http://mt4program.blogspot.jp/"
#property version "2.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 clrDodgerBlue
#property indicator_style2 STYLE_SOLID
#property indicator_width2 1
#property indicator_label3 "HIGH2UP"
#property indicator_type3 DRAW_LINE
#property indicator_color3 clrDodgerBlue
#property indicator_style3 STYLE_SOLID
#property indicator_width3 1
#property indicator_label4 "LOW1UP"
#property indicator_type4 DRAW_LINE
#property indicator_color4 clrDodgerBlue
#property indicator_style4 STYLE_SOLID
#property indicator_width4 1
#property indicator_label5 "LOW2UP"
#property indicator_type5 DRAW_LINE
#property indicator_color5 clrDodgerBlue
#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
input ENUM_TIMEFRAMES TargetPeriod = PERIOD_CURRENT;// 対象タイムフレーム
input int MaPeriod = 21;//移動平均期間
input int MaShift = 0;//表示移動
input ENUM_MA_METHOD MaMethod = MODE_EMA;//移動平均種別
input ENUM_APPLIED_PRICE MaPrice = PRICE_MEDIAN;//適用価格
input int StdPeriod = 21;//標準偏差期間
input ENUM_MA_METHOD StdMethod = MODE_SMA;//標準偏差算出方法
input double Sigma1 = 1;//σ1
input double Sigma2 = 2;//σ2
input bool IsAlertSound = true;//条件に一致した場合、サウンドを鳴らす。
input string SoundFileName = "alert.wav";//再生サウンド名
input bool IsAlertMail = true;//条件に一致した場合、メールを送信する。
input double AlertSigma = 1;//終値が次シグマを超えた場合アラートを鳴らす
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[]) //スプレット
{
int targetPeriod = TargetPeriod;
if( targetPeriod == PERIOD_CURRENT) targetPeriod = Period();
if( Period() > targetPeriod ) return rates_total ;
for( int i = (rates_total - prev_calculated - 1); i >= 0 && !IsStopped(); i-- )
{
if( i >= rates_total - 2 ) continue;
int shift1 = iBarShift(NULL, targetPeriod, time[i], false);
if( iBars(NULL, targetPeriod) <= shift1 + 1) continue;
double ma1 = iMA(NULL, targetPeriod, MaPeriod, MaShift, MaMethod, MaPrice, shift1);
double ma2 = iMA(NULL, targetPeriod, MaPeriod, MaShift, MaMethod, MaPrice, shift1 + 1);
double std1 = iStdDev(NULL, targetPeriod, StdPeriod, MaShift, StdMethod, MaPrice, shift1);
double std2 = iStdDev(NULL, targetPeriod, StdPeriod, MaShift, StdMethod, MaPrice, shift1 + 1);
int j = 0;
for( j = i; j < rates_total && iBarShift(NULL, targetPeriod, time[j]) == shift1; j++)
{
//いったんEMPTY_VALUでクリア
centerDown[j] = EMPTY_VALUE;
centerUp[j] = EMPTY_VALUE;
high1Down[j] = EMPTY_VALUE;
high2Down[j] = EMPTY_VALUE;
low1Down[j] = EMPTY_VALUE;
low2Down[j] = EMPTY_VALUE;
high1Up[j] = EMPTY_VALUE;
high2Up[j] = EMPTY_VALUE;
low1Up[j] = EMPTY_VALUE;
low2Up[j] = EMPTY_VALUE;
// 移動平均の方向によって値を設定するバッファーを変更する。
if( ma1 < ma2 )
{
centerDown[j] = ma1;
}
else
{
centerUp[j] = ma1;
}
// 標準偏差の大きさによって値を入れるバッファを切り替える。
if( std1 < std2 )
{
high1Down[j] = ma1 + std1 * Sigma1;
high2Down[j] = ma1 + std1 * Sigma2;
low1Down[j] = ma1 - std1 * Sigma1;
low2Down[j] = ma1 - std1 * Sigma2;
}
else
{
high1Up[j] = ma1 + std1 * Sigma1;
high2Up[j] = ma1 + std1 * Sigma2;
low1Up[j] = ma1 - std1 * Sigma1;
low2Up[j] = ma1 - std1 * Sigma2;
}
}
if( j < rates_total )
{
//虫食い穴埋め
if( centerDown[j] == EMPTY_VALUE && centerDown[j - 1] != EMPTY_VALUE )
{
centerDown[j] = centerUp[j];
}
if( centerUp[j] == EMPTY_VALUE && centerUp[j - 1] != EMPTY_VALUE )
{
centerUp[j] = centerDown[j];
}
//虫食い穴埋め
if( high1Down[j] == EMPTY_VALUE && high1Down[j - 1] != EMPTY_VALUE )
{
high1Down[j] = high1Up[j];
high2Down[j] = high2Up[j];
low1Down[j] = low1Up[j];
low2Down[j] = low2Up[j];
}
if( high1Up[j] == EMPTY_VALUE && high1Up[j - 1] != EMPTY_VALUE )
{
high1Up[j] = high1Down[j];
high2Up[j] = high2Down[j];
low1Up[j] = low1Down[j];
low2Up[j] = low2Down[j];
}
}
// 最終アラート発生時刻
static datetime lastAlertTime = 0;
// 前回がアラートシグマ未満で、今回がアラートシグマ以上なら音をならしてメールを送信する。
// 過去データの計算でアラートが発生するのを防止するため、iが1の時のみ。
if( i == 1 && (IsAlertMail || IsAlertSound ) && lastAlertTime != time[i] )
{
double alertStd1 = std1 * AlertSigma;
double alertStd2 = std2 * AlertSigma;
if( (close[i + 1] < (ma2 + alertStd2) && close[i] >= (ma1 + alertStd1))
|| (close[i + 1] > (ma2 - alertStd2) && close[i] <= (ma1 - alertStd1)))
{
if( IsAlertSound )
{
PlaySound(SoundFileName);
}
if( IsAlertMail )
{
//タイトル
string subject = StringFormat("ColorfulMTBB アラート %s[%d] %s", Symbol(), Period(), TimeToStr(time[i]) );
//本文
string message = "ColorfulMTBBの設定によりアラートメールを送信しました。\r\n";
StringAdd(message, StringFormat("MA:%f\r\n", ma1));
StringAdd(message, StringFormat("LowerStd:%f\r\n", ma1 - alertStd1));
StringAdd(message, StringFormat("UpperStd:%f\r\n", ma1 + alertStd1));
StringAdd(message, StringFormat("Close:%f\r\n", close[i]));
SendMail(subject, message);
}
lastAlertTime = time[i];
}
}
}
return(rates_total - 1);
}