2015年10月9日金曜日

[販売中インジケータ]TEMA平均足にT2TEMA平均足を追加しました。

TEMA平均足ですが、好評販売中です。
ご購入いただきました皆様ありがとうございます。

好評につき、おまけのインジケータをTEMA平均足に追加しました。
TEMA平均足は平均足の始値にα=0.1のTEMAを採用した平均足となります。

T2TEMA平均足は、終値にもTEMAを採用した平均足です。
TEMAは小さな値動きには鈍く反応して大きな値動きには素早く反応する性質があります。平均足CLOSE値は最新足のみを見て位置関係を判断することで素早く反応させていますが、その分足の形成中のだましや細かい値動きによるモードの反転が発生してしまいます。

そこで、終値側にもTEMAによる平滑化を行うことで、細かい値動きによるシグナル転換を防止することを目的にしています。

下記は、昨日のEURUSDによる比較です。上がTEMA平均足/下T2TEMA平均足となります。
シグナルの転換が少し遅れて発生していることがわかるかと思います。

■TEMA平均足とT2TEMA平均足の比較

このようにポジションのオープンにより慎重になりたい方向けのおまけインジケータです。

コメントでお約束した通り、10本売れましたらアラート機能をアップデートいたします^^
割引価格での販売は残り6本となっておりますので、ご購入はお早めに~。


ご購入はこちらから。10/15まで割引価格で販売いたします。
平均足のOPEN値にTEMAを適用したカスタム平均足
TEMA平均足
TEMA平均足 | fx-on.com

なお、機能のT2TEMAはこんな感じでした。画像が大きいですが、左からEURUSDの15分足、30分足、60分足です。



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

2015年10月8日木曜日

[販売中インジケータ]T2TEMA平均足の追加

わーい。さっそく2本売れました。
ご購入いただきありがとうございます。

平均足はやっぱり人気のインジケータですね。

詳しくは明日の記事で書きますが、TEMA平均足にT2TEMA平均足を追加しました。
うれしくなったため、アイデアがあったインジケータを急ぎ作成しちゃいました^^;;;

これは、平均足のClose側にもTEMAを適用したものです。おまけですが、同じ考え方のインジケータですので役立つかと思われます。

680円での販売は、2015/10/8 16:52時点で、残り8名様となっております。


平均足のOPEN値にTEMAを適用したカスタム平均足
TEMA平均足


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

ブログを引っ越ししました。

seesaaブログから、Bloggerへブログを引っ越ししました。

今後ともよろしくお願いいたします。

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

[販売中インジケータ]TEMA平均足の販売開始!

平均足におけるだましのシグナルを少なくするために改良した平均足です。
平均足のわかりやすさは、そのままに転換時のだましを減らす工夫をしました。

平均足を使用する場合、転換時のだましの判断が難しい問題があります。これは0.5EMAというかなり追従性の高い移動平均をもとに平均足が描画されているためです。

■TEMA平均足と平均足の比較
TEMAHeikinAshi.PNG
※上MT4付属の平均足/下TEMA平均足

下記にて記載した通り、平均足は四本値平均に対して0.5EMAを始値として比較描画したグラフです。
参考記事
[MT4インジケータ&プログラミング]平均足をマルチタイムフレームで。http://mt4program.blogspot.jp/2015/10/mt4_32.html

同様にEMAを使用した高追従移動平均として1990年代に開発されたTEMAがあります。
参考記事
[MT4インジケータ&プログラミング]なめらか&追従よく トリプルEMAhttp://mt4program.blogspot.jp/2015/10/mt4_38.html

ということで、平均足の比較元をEMAからTEMAに変更すると、高追従と平滑化を両立した平均足になるのではないか?と思い作成しました。

見方は平均足と同様ですので使われている方は戸惑うことはあまりないかとと思います。
パラメータは下記の3つです。

■入力パラメータ 指数係数
Alfa = 0.1;
EMAで使用する指数係数です。変更は不要かと思います。

■入力パラメータ 平均足OPEN TEMA対象価格
MaPrice = TEMA_PRICE_WEIGHTED;
平均足の始値で使用するTEMAの計算元となる価格です。

■入力パラメータ 平均足CLOSE 対象価格
HeikinPrice = TEMA_PRICE_WEIGHTED;
平均足の終値で使用する価格です。

TEMA対象価格と対象価格には次の値を指定できます。
TEMA_PRICE_CLOSE //終値
TEMA_PRICE_OPEN //始値
TEMA_PRICE_HIGH //高値
TEMA_PRICE_LOW //安値
TEMA_PRICE_MEDIAN //(高値+安値)/2
TEMA_PRICE_TYPICAL //(高値+安値+終値)/3
TEMA_PRICE_WEIGHTED//(高値+安値+終値+終値)/4
TEMA_PRICE_OHLC //(高値+安値+終値+始値)/4

■TEMAに対する、標準偏差バンドを表示するかどうか
IsShowBB = true;

■TEMAに対する、平均足Close値の標準偏差期間
StdPeriod = 21;

■描画する標準偏差バンド幅
StdAlfa = 0.5;

CLOSE値を重視したほうがよいという考え方から、平均足で使用されるTEMA_PRICE_OHLCではなく、TEMA_PRICE_WEIGHTEDをデフォルトとしています。ご使用になる通貨によって特徴が異なるかと思いますので、ご自由に選択ください。

正直、今週アップした記事のプログラムが理解できる方なら自力での実装も可能かと思いますが、ブログの運営費用を寄付していただけるぐらいの気持ちで購入していただけると幸いです。

売れ行きが良ければ、今後アラート機能なども追加していきます。

ご購入はこちらから。10/15まで割引価格で販売いたします。
平均足のOPEN値にTEMAを適用したカスタム平均足
TEMA平均足
TEMA平均足 | fx-on.com

■2015/10/07 EURUSD15M TEMA平均足
TEMA20151008.PNG

ちなみに2015/10/18のTEMAHeikinAshiはこんな感じです。1時間足でもよいのですが、昨日は15分足のほうがわかりやすく出ていたため、15分足の画像を貼り付けます。転換点はほぼとらえているかと。
ただし、足が完全に形成されてからだと、エントリーや損切の判断が遅くなります。そこでTEMAに対するTEMA平均足クローズ値の標準偏差バンドも合わせて表示しています。TEMA平均足のクローズ値がエントリーと逆方向に標準偏差バンドを超えてきた場合はポジションクローズの判断の一つになるかとなります。


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

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


2015年10月6日火曜日

[MT4インジケータ&プログラミング]平均足をマルチタイムフレームで。

※このプログラムは未来の情報を見ている不具合があります。

heikinasi.PNG

数あるインジケータの中でも平均足というのは面白いです。

高値安値の平均値を結んでいったときに上昇しているか下降しているかを表しています。

ろうそく足のように見えますが、実質は指数移動平均の仲間のようです。
平均足open = (前回平均足Close + 前回平均足Open) / 2
に対して下記の値がどの位置にいるかを示しています。
平均足close = (open + high + low + close) / 4
※(open + high + low + close) / 4 は以下OHLC/4と省略します。

平均足openは下記のように分解できますので、結局のところ前回OHLC/4に対するα=0.5 EMAとなります。
平均足open = (前回平均足Close + 前回平均足Open) / 2
      = (前回OHLC/4 + 前回平均足Open) / 2
      = (1/2) * 前回OHLC/4 + (1/2) * 前回平均足Open
      = 0.5 * 前回OHLC/4 + (1 - 0.5) * 前回平均足Open

平均足は、前回OHLC/4のEMAに対して今回のOHLC/4が高いか低いかでトレンドを判断する指標となります。

ということは、四本値の平均をとって平滑化効果を出し、それをさらにEMA遅延させています。
平均足もEMAの遅延効果を使ったインジケータといえるかと思います。

さておき、平滑化効果を四本値の平均で出しているので、時間足の選択が重要になってきます。
そこで、マルチタイムフレームに対応した平均足の表示にチャレンジしてみたいと思います。

試しに作ってみたのですが、現状とても遅いため、MT4のツール→オプション→チャートのチャートバー数を5000本程度にしてお試しください。設定後はMT4の再起動が必要です。

両ひげが歩かないかで色が変わります。サブウィンドウの下から月足→1分足までと描画しますが、現在チャートに表示している時間までの表示となります。

今回各時間の平均足を求めるのにMT4に標準でついてくるHeikin Ashi.mq4をiCustomを利用して呼び出しています。これが原因でとても遅いですが、まぁとりあえずの横着版ってことで^^;;;
ここを改善したコードも書けますが、ちゃちゃっと作るレベルではないので、いったん、ここまでにしたいと思います。

また、平均足はEMAを利用した値比較ですが、比較対象とするMAをいろいろ切り替えて平均足っぽい描画ができるのではないかなぁ?とか考えちゃいますよね?、また時間があるときにいろいろ試してみたいと思います。


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

//------------------------------------------------------------------
// マルチタイムフレーム平均足
#property copyright "Copyright 2015,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_maximum   90
#property indicator_minimum   0

//オブジェクト名
#define HEIKIN_OBJECT_NAME "HEIKIN"

//チャート名
#define HEIKIN_SHORT_NAME "HeikinMT"

//タイムフレーム数
#define TIMEFRAME_COUNT 9

// 上ひげ 上げ平均足色
extern color UpUpcolor = C'0,0,255';
// 両ひげ 上げ平均足色
extern color UpDualColor = C'128,128,255';
// 両ひげ 下げ平均足色
extern color DownDualColor = C'255,128,128';
// 下ひげ 下げ平均足色
extern color DownDownColor = C'255,0,0';

// 最小表示タイムフレーム
extern ENUM_TIMEFRAMES MinTimeframe = PERIOD_M5;

// 最大表示タイムフレーム
extern ENUM_TIMEFRAMES MaxTimeframe = PERIOD_MN1;

// タイムフレーム一覧
ENUM_TIMEFRAMES timeframes[];

string shortName;

//------------------------------------------------------------------
//初期化
int OnInit()
{
ArrayResize(timeframes, TIMEFRAME_COUNT);
timeframes[0] = PERIOD_M1;
timeframes[1] = PERIOD_M5;
timeframes[2] = PERIOD_M15;
timeframes[3] = PERIOD_M30;
timeframes[4] = PERIOD_H1;
timeframes[5] = PERIOD_H4;
timeframes[6] = PERIOD_D1;
timeframes[7] = PERIOD_W1;
timeframes[8] = PERIOD_MN1;

// 短縮名を設定
shortName = "HeikinMT" + TimeToStr(TimeCurrent());

IndicatorShortName(shortName);

return(INIT_SUCCEEDED);
}

//------------------------------------------------------------------
//終了処理
void OnDeinit(const int reason)
{
//オブジェクトを作成する。
long chartId = ChartID();

int total = ObjectsTotal(chartId);
//生成したオブジェクトを削除する。
//0から削除するとインデックス位置がずれて
//正しく削除できないため、後ろから削除するようにする。
for( int i = total - 1; i >= 0 ; i--)
{
string name = ObjectName(chartId, i);

// 先頭文字列がHEIKIN_OBJECT_NAMEと一致する場合、削除する。
if( StringFind(name, HEIKIN_OBJECT_NAME) == 0 )
{
ObjectDelete(chartId, name);
}
}
}
//------------------------------------------------------------------
//計算イベント
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[])            //スプレット
{
if( GetCountTimeFrame() == 0 ) return rates_total ;

int subWindowIndex = WindowFind(shortName);
int currentPeriod = Period();

//処理済み時間
datetime calculatedTime[TIMEFRAME_COUNT];
ArrayFill(calculatedTime, 0, TIMEFRAME_COUNT, 0);

for( int i = rates_total - prev_calculated - 1 ; i >= 0; i-- )
{
for( int timeIndex = 0 ; timeIndex < TIMEFRAME_COUNT; timeIndex++)
{
// 対象のタイムフレームを取得する。
ENUM_TIMEFRAMES target = timeframes[timeIndex];
if( target < MinTimeframe || target > MaxTimeframe) continue;
if( target < currentPeriod) continue;
int shift = iBarShift(NULL, target, time[i], false);
if( shift < 0 ) continue;

datetime startTime = iTime(NULL, target, shift);

//iCustomの呼び出しが遅いので、なるべく呼び出し回数を減らすようにする。
if( i > 1 && startTime == calculatedTime[timeIndex] ) continue;
calculatedTime[timeIndex] = startTime;

datetime endTime;

if( shift > 0 )
{
endTime =  iTime(NULL, target, shift - 1);
}
else
{
endTime = startTime + PeriodSeconds(target);
}

// 標準の平均足を利用する。
double beforeOpen = iCustom(NULL, target, "Heiken Ashi", Red, White, Red, White, 2, shift + 1);
double beforeClose = iCustom(NULL, target, "Heiken Ashi", Red, White, Red, White, 2, shift + 1);

if( beforeOpen == 0 || beforeClose == 0 )
{
continue;
}

double haOpen = (beforeOpen + beforeClose) / 2;
double haHigh = iHigh(NULL, target, shift);
double haLow = iLow(NULL, target, shift);
double haClose = (iOpen(NULL, target, shift) + iClose(NULL, target, shift) + haHigh + haLow) / 4;

haHigh = MathMax(haHigh, MathMax(haOpen, haClose));
haLow = MathMin(haLow, MathMin(haOpen, haClose));

// 最新値が更新される場合は、オブジェクトを再描画する。
if( i <= 1 )
{
DeleteRectangleObject(startTime, target);
}

color backColor;
if( haOpen < haClose)
{
//下髭出ている場合UpDualColor、それ以外UpUpcolor
// haOpen < haClose において haClose < haHighが成り立つので上髭は見なくてもよい。
backColor = haLow < haOpen ? UpDualColor : UpUpcolor;
}
else
{
//上髭出ている場合UpDualColor、それ以外UpUpcolor
// haOpen > haClose において haClose > haLowが成り立つので下髭は見なくてもよい。
backColor =  haHigh > haOpen ? DownDualColor : DownDownColor;
}

CreateRectangleObject(startTime, endTime, target, backColor, subWindowIndex);
}

}

return(rates_total - 1);
}

//------------------------------------------------------------------
//売買シグナルを矩形で描画する。
bool CreateRectangleObject(
datetime startTime,  //表示時間(横軸)
datetime endTime,    //表示時間(横軸)
ENUM_TIMEFRAMES period,          //対象ピリオド
color backColor,     //背景色
int subWindowIndex   //サブウィンドウインデックス
)
{
//オブジェクトを作成する。
long chartId = ChartID();

string name = GetObjectName(startTime, period);
int index = GetTimeFrameIndex(period);
if( index < 0 ) return true;
if( ObjectFind(chartId, name) >= 0 ) return true;


//チャート縦幅いっぱいに表示する。
double min = ChartGetDouble(chartId, CHART_FIXED_MIN, subWindowIndex);
double max = ChartGetDouble(chartId, CHART_FIXED_MAX, subWindowIndex);
double oneBlockSize = (max - min) / TIMEFRAME_COUNT;

double top = oneBlockSize * (TIMEFRAME_COUNT - index);
double bottom = oneBlockSize * (TIMEFRAME_COUNT - index - 1);

if( !ObjectCreate(chartId, name, OBJ_RECTANGLE, subWindowIndex, startTime, top, endTime, bottom) )
{
return false;
}
ObjectSetInteger(chartId, name, OBJPROP_COLOR, backColor);
ObjectSetInteger(chartId, name, OBJPROP_READONLY, true);
ObjectSetInteger(chartId, name, OBJPROP_SELECTABLE, false);

return true;
}


//------------------------------------------------------------------
//オブジェクトを削除する。
bool DeleteRectangleObject(
datetime startTime,  //開始時間
ENUM_TIMEFRAMES period)          //対象ピリオド
{
//オブジェクトを作成する。
long chartId = ChartID();
string name = GetObjectName(startTime, period);

if( ObjectDelete(chartId, name) )
{
#ifdef DEBUG
Print("Ojbect Deleted " + name);
#endif
}

return true;
}

//------------------------------------------------------------------
//オブジェクト名を取得する。
string GetObjectName(
datetime startTime,  //開始時間
ENUM_TIMEFRAMES period)          //対象ピリオド
{
return StringFormat("%s_%s_%d",HEIKIN_OBJECT_NAME, TimeToStr(startTime), period);
}

//------------------------------------------------------------------
//対象となるタイムフレーム数を取得する。
int GetCountTimeFrame()
{
int count = 0 ;
int currentPeriod = Period();
for( int i = 0; i < TIMEFRAME_COUNT; i++)
{
if( timeframes[i] >= MinTimeframe
&& timeframes[i] >= currentPeriod
&& timeframes[i] <= MaxTimeframe)
{
count++;
}
}
return count;
}

//------------------------------------------------------------------
//対象となるタイムフレームのインデックスを取得する。
int GetTimeFrameIndex(ENUM_TIMEFRAMES timeframe)
{
int index = -1 ;
if( timeframe < MinTimeframe || timeframe > MaxTimeframe) return -1;

for( int i = 0; i < TIMEFRAME_COUNT; i++)
{
if( timeframe == timeframes[i] ) return i;
}
return index;
}