2015年5月7日木曜日

シンプルだけど効果あり!MT4でDrawSimpleLineインジケータを作ってみた。

DSL.PNG

分かりやすくて効果がありそうなインジケータということで、DrawSimpleLineを実装してみました。主にグラフが交差したところで売買するインジケータとなります。

DrawSimpleLineとは短い期間同士の移動平均と、長い期間同士の移動平均の差を描画します。移動平均の収束と拡散を判断するオシレータです。考え方はMACDと似ていますが、MACDは二つの移動平均差から算出しますが、こちらは4つの移動平均の収束拡散を示しています。コードはかなり単純で、移動平均の差をそれぞれ算出するだけです。

//------------------------------------------------------------------
// Draw Simple Line

#property copyright "Copyright 2015,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_separate_window

//バッファーを指定する。
#property indicator_buffers 2

//プロット数を指定する。
#property indicator_plots   2

// MA1-MA2
#property indicator_label1  "LINE1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

// MA3-MA4
#property indicator_label2  "LINE2"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrIndianRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

// 入力パラメータ 移動平均1期間
input int Ma1Period = 5;
// 入力パラメータ 移動平均2期間
input int Ma2Period = 10;
// 入力パラメータ 移動平均3期間
input int Ma3Period = 7;
// 入力パラメータ 移動平均4期間
input int Ma4Period = 13;

//入力パラメータ 移動平均種別
input ENUM_MA_METHOD MaMethod = MODE_SMA;

//入力パラメータ 適用価格
input ENUM_APPLIED_PRICE MaPrice = PRICE_CLOSE;

// バッファー
double diff1Buffer[];
double diff2Buffer[];

//------------------------------------------------------------------
//初期化
int OnInit()
{
// 短縮名を設定
string shortName = "DSL (";
shortName += IntegerToString(Ma1Period) + "-" + IntegerToString(Ma2Period) + ",";
shortName += IntegerToString(Ma3Period) + "-" + IntegerToString(Ma4Period) + ")";
IndicatorShortName(shortName);

SetIndexBuffer(0, diff1Buffer);
SetIndexBuffer(1, diff2Buffer);

SetIndexDrawBegin(0, Ma2Period);
SetIndexDrawBegin(1, Ma4Period);

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; i-- )
{
diff1Buffer[i] = iMA(NULL, PERIOD_CURRENT, Ma1Period, 0, MaMethod, MaPrice, i) - iMA(NULL, PERIOD_CURRENT, Ma2Period, 0, MaMethod, MaPrice, i);
diff2Buffer[i] = iMA(NULL, PERIOD_CURRENT, Ma3Period, 0, MaMethod, MaPrice, i) - iMA(NULL, PERIOD_CURRENT, Ma4Period, 0, MaMethod, MaPrice, i);
}

return(rates_total - 1);
}


一方的な相場ではだましのシグナルも発生しますが、その場合は再度クロスしたところで早めに損切してクロスした方向へ再度ポジションをとるという戦略がよさそうです。あと小さな値動きですと、何回もクロスしますのである程度の振幅が発生した場合だけ取引するというのが有効に思われます。