2015年10月7日水曜日

[MT4インジケータ&プログラミング]なめらか&追従よく トリプルEMA

TEMA.PNG

世界中の人たちがなめらかにかつ追従よいMAを考えているわけですが、その中でも1990年代に開発されたTEMAは有名です。

・移動平均遅延を利用するシリーズ
http://mt4program.blogspot.jp/2015/10/blog-post_71.html

で書いたように、移動平均に移動平均を重ねることで遅延分を利用することを書きましたが、TEMAは遅延分を逆に足しこむことで、遅延をなく追従することを目指したEMAです。考え方としてはZEMAに似ています。あちらがモメンタムとして単純な価格の差分から求めているのに対して、TEMAはEMAとEMAEMAの差分を使用しています。

EMAEMAのEMAをとると、EMAEMAに含まれる遅延分も含めて遅延します。それをキャンセルするためにEMAとEMAEMAの差分の3倍を予測値として加えているという形です。

TEMAは、これにより平滑化効果と高追従性の両立を図っています。

さて、TEMAは有名ですので、MT4のインジケータにもたくさんあるかと思います。じゃぁあえてなんで?というと・・昨日の記事からの流れで・・・・。

FX-ONブログランキングにご協力よろしくお願いいたしますm(_ _ )m




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

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

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

#property indicator_label1  "TEMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrIndianRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#property indicator_label2  "EMA"
#property indicator_type2   DRAW_NONE
#property indicator_color2  clrNONE

#property indicator_label3  "EMAEMA"
#property indicator_type3   DRAW_NONE
#property indicator_color3  clrNONE

#property indicator_label4  "EMAEMAEMA"
#property indicator_type4   DRAW_NONE
#property indicator_color4  clrNONE

//入力パラメータ 指数係数
extern double Alfa = 0.1;

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

// TEMA
double tema[];

// EMA
double ema1[];

// EMA EMA
double ema2[];

// EMA EMA EMA
double ema3[];

//------------------------------------------------------------------
//初期化
int OnInit()
{
//インジケーターバッファを初期化する。
SetIndexBuffer(0,tema);
SetIndexBuffer(1,ema1);
SetIndexBuffer(2,ema2);
SetIndexBuffer(3,ema3);

if( Alfa <= 0 || Alfa >= 1 ) return INIT_PARAMETERS_INCORRECT;

string short_name = "TEMA(" + DoubleToStr(Alfa) + ")";
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-- )
{
double price = GetPrice(open[i], close[i], high[i], low[i], MaPrice);
if( i == (rates_total - 1) )
{
ema1[i] = price;
ema2[i] = price;
ema3[i] = price;
tema[i] = price;
continue;
}
ema1[i] = Alfa * price + ( 1 - Alfa ) * ema1[i + 1];
ema2[i] = Alfa * ema1[i] + ( 1 - Alfa ) * ema2[i + 1];
ema3[i] = Alfa * ema2[i] + ( 1 - Alfa ) * ema3[i + 1];
tema[i] = ema1[i] * 3 - ema2[i] * 3 + ema3[i];
}
//元となる値を計算する。
return(rates_total - 1);
}


//------------------------------------------------------------------
// 価格を計算する。
// return 対象価格
double GetPrice(
double open,   // オープン値
double close,  // クローズ値
double high,   // 高値
double low,    // 安値
ENUM_APPLIED_PRICE maPrice    //取得価格
)
{
double price = 0;

switch( maPrice )
{
case PRICE_CLOSE:
price = close;
break;
case PRICE_OPEN:
price = open;
break;
case PRICE_HIGH:
price = high;
break;
case PRICE_LOW:
price = low;
break;
case PRICE_MEDIAN:
price = (high + low) / 2;
break;
case PRICE_TYPICAL:
price = (high + low + close) / 3;
break;
case PRICE_WEIGHTED:
price = (high + low + close + close) / 4;
break;
}
return price;
}