2016年4月6日水曜日

[MT4インジケータ]期間が変更可能なフラクタルでレンジ相場を判定したい。

Gewinn7や、今開発中のGewinn8の精度を高めるため、レンジ相場かどうかを判定したいなぁと四苦八苦しています。

レンジ相場かどうかの判定といえば、まず高値安値の観測から始まるのですが、MT4標準でついているFractalsは5本間の高値安値位置に矢印を描画するというインジケータです。

日足などでは問題ないのでしょうが、時間足など短い足だと、矢印がたくさん出てしまい、どれを観測すればよいのかわからなくなってしまいます。

そこで、5本ではなく7本など、観測期間を変更可能なフラクタルを作成しました。また、高値安値ではなくてクローズ値をベースに描画できるようにもしてあります。

■MT4標準フラクタル(上) カスタムフラクタル(下)


これでも、例えば画像の例だと、日本時間の値動きが少ない時間帯に矢印が出たりします。
そのため、もう一つTickVolumeと合わせて表示することで有効な矢印かどうかを判断しましょう。

■カスタムフラクタルと、TickVolume

TickVolumeにて平均値を下回っている個所の矢印は有効ではないと判断します。
ここからレンジ相場のレンジを判断していくのはまだ研究中です・・。


判定期間が変更可能なフラクタル
判定期間が変更可能なフラクタル
判定期間が変更可能なフラクタル | fx-on.com

「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。


ソースコードです。
//------------------------------------------------------------------
// カスタム フラクタル
#property copyright "Copyright 2016,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_chart_window

input int ArrowPeriod = 5;                  // 3以上の奇数。N本高値安値が中央値の場合矢印を描画する。

input bool TargetIsClose = false;      // trueの場合Close値を対象とする。falseの場合高値安値を対象とする。
input int TopArrowType = 217;          // 上矢印タイポう
input int BottomArrowType = 218;       // 下矢印タイプ
input double OffsetPips = 5;           // 表示オフセット


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

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

#property indicator_label1  "TOP"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrAqua
#property indicator_width1  2

#property indicator_label2  "BOTTOM"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrDarkOrange
#property indicator_width2  2

// バッファー
double topArrow[];
double bottomArrow[];

//------------------------------------------------------------------
//初期化
int OnInit()
{
   string short_name = "CustomFractals";
   
   if( ArrowPeriod % 2 == 0 || ArrowPeriod < 3) return INIT_PARAMETERS_INCORRECT;
   
   int count = 0;
   SetIndexBuffer(count++, topArrow);
   SetIndexBuffer(count++, bottomArrow);
   
   SetIndexArrow(0, TopArrowType);
   SetIndexArrow(1, BottomArrowType);

   return INIT_SUCCEEDED;
}

//------------------------------------------------------------------
//終了処理
void OnDeinit(const int reason)
{

}

//------------------------------------------------------------------
//計算イベント
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 offsetIndex = (ArrowPeriod - 1) / 2;
   
   int digit = (int)MarketInfo(Symbol(), MODE_DIGITS);
   double offsetPips = (double)MarketInfo(Symbol(), MODE_POINT) * (digit == 3 || digit == 5 ? 10 : 1) * OffsetPips;


   for( int i = offsetIndex; i < rates_total - prev_calculated && !IsStopped(); i++ )
   {
      if( iHighest(Symbol(), Period(), TargetIsClose ? MODE_CLOSE : MODE_HIGH, ArrowPeriod, i - offsetIndex) == i ) topArrow[i] = high[i] + offsetPips;
      if( iLowest(Symbol(), Period(), TargetIsClose ? MODE_CLOSE : MODE_LOW, ArrowPeriod, i - offsetIndex) == i ) bottomArrow[i] = low[i] - offsetPips;
   }
   
   //元となる値を計算する。unFix期間は計算し続ける。
   return rates_total - offsetIndex - 1;
}