2016年4月12日火曜日

[MT4インジケータ]値動きが一定を超えたら矢印を出す

staplaさん、いつもブログにコメントありがとうございます。

[MT4プログラミング]MT4のチャート上に矢印を表示する。
にてコメントをいただきました。
http://mt4program.blogspot.jp/2015/10/mt4mt4_8.html?showComment=1460093397701#c5006228500137749190

ちょっと、開発中のインジケータをEAで試すのに手一杯で時間が取れなかったのですが、煮詰まったので一息がてらに作ってみました。

■ATR幅を超えた値動きをした場合、矢印を出すインジケータ


画像は、EURUSD1Hにおいて、前の足の(高値+安値+始値+終値)/ 4を基準位置として100本ATR幅を超えた場合に矢印を出しています。パパッと見る限り、この設定ですと連続して矢印が出る事が多いように思われます。この設定では順張り向けですね。

インジケータとしては、自分の足の始値や前の足の終値など少し幅を持たせた設定ができるようにしてあります。このインジケータは基準位置をどこにするかがカギに思われます。

逆張り向けとしては、もう少し大きくATR幅を取ったほうが良いように思われますが、EURUSDにおいては上がると上がりっぱなしといった動きをすることが多々あるため、別の通貨のほうが良いように思われます。

あ、プログラム的には、「MT4のチャート上に矢印を出す」では、オブジェクトを使って矢印を出していますが、こちらは、バッファを使用しています。
ちゃちゃっとだすにはこちらの方が簡単です。

ポイントは、次の二つです。
#property indicator_type4   DRAW_ARROW
SetIndexArrow(3, TopArrowType);

indicator_typeをDRAW_ARROWにすることと、SetIndexArrowにて矢印の種別を指定することです。

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

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

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

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

プログラムはこちらから


//------------------------------------------------------------------
// 一定のATR幅を超えたら矢印を出す
#property copyright "Copyright 2016,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_chart_window

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

#property indicator_label1  "CENTER"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_DOT
#property indicator_width1  1

#property indicator_label2  "TOP"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrYellow
#property indicator_style2  STYLE_DOT
#property indicator_width2  1

#property indicator_label3  "BOTTOM"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrDarkOrange
#property indicator_style3  STYLE_DOT
#property indicator_width3  1

#property indicator_label4  "UPARROW"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrAqua
#property indicator_style4  STYLE_SOLID
#property indicator_width4  2

#property indicator_label5  "DOWNARROW"
#property indicator_type5   DRAW_ARROW
#property indicator_color5  clrDarkOrange
#property indicator_style5  STYLE_SOLID
#property indicator_width5  2

// 適用パラメータ 列挙値
enum ENUM_SATR_PRICE
{
   //終値
   SATR_PRICE_CLOSE,
   //始値
   SATR_PRICE_OPEN,
   //高値
   SATR_PRICE_HIGH,
   //安値
   SATR_PRICE_LOW,
   //(高値+安値)/2
   SATR_PRICE_MEDIAN,
   //(高値+安値+終値)/3
   SATR_PRICE_TYPICAL,
   //(高値+安値+終値+終値)/4
   SATR_PRICE_WEIGHTED,
   //(高値+安値+終値+始値)/4
   SATR_PRICE_OHLC,
};

input int AtrPeriod = 100;                               //ATR期間
input double ZoomRate = 1;                               //ATR倍率
input ENUM_SATR_PRICE StartPrice = SATR_PRICE_OHLC;     //開始価格
input int StartIndex = 1;           // 比較対象の基準インデックス、StartIndex 1で、StartPrice Closeなら一本前の終値を基準にする

input bool TargetIsClose = false;   // trueの場合Close値を対象とする。falseの場合高値安値を対象とする。

input int TopArrowType = 217;       // 上矢印タイポう
input int BottomArrowType = 218;    // 下矢印タイプ
input double OffsetPips = 5;        // 表示オフセット

// バッファ
double center[];
double top[];
double bottom[];
double upArrow[];
double downArrow[];

//------------------------------------------------------------------
//初期化
int OnInit()
{
   //インジケーターバッファを初期化する。
   int count = 0;
   SetIndexBuffer(count++,center);
   SetIndexBuffer(count++,top);
   SetIndexBuffer(count++,bottom);
   SetIndexBuffer(count++,upArrow);
   SetIndexBuffer(count++,downArrow);

   for( int i = 0; i < count; i++ )
   {
      SetIndexDrawBegin(i, AtrPeriod);
   }

   SetIndexArrow(3, TopArrowType);
   SetIndexArrow(4, BottomArrowType);

   string short_name = "ATRUPDOWN(" + IntegerToString(AtrPeriod) + ")";
   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 digit = (int)MarketInfo(Symbol(), MODE_DIGITS);
   double offset = (double)MarketInfo(Symbol(), MODE_POINT) * (digit == 3 || digit == 5 ? 10 : 1) * OffsetPips;

   for( int i = (rates_total - prev_calculated - 1); i >= 0 && !IsStopped(); i-- )
   {
      if( i >= rates_total - AtrPeriod - 1 ) continue;
      double atr = iATR(Symbol(), Period(), AtrPeriod, i) * ZoomRate;
     
      int base = i + StartIndex;

      center[i] = GetPrice(open[base], close[base], high[base], low[base], StartPrice);
      top[i] = center[i] + atr;
      bottom[i] = center[i] - atr;
      
      if( TargetIsClose )
      {
         if( close[i] > top[i] ) upArrow[i] = close[i] + offset;
         if( close[i] < bottom[i] ) downArrow[i] = close[i] - offset;
      }
      else
      {
         if( high[i] > top[i] ) upArrow[i] = high[i] + offset;
         if( low[i] < bottom[i] ) downArrow[i] = low[i] - offset;
      }
   }
   //元となる値を計算する。
   return rates_total - 1;
}
//+------------------------------------------------------------------+

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

   switch( maPrice )
   {
      case SATR_PRICE_CLOSE:
         price = close;
         break;
      case SATR_PRICE_OPEN:
         price = open;
         break;
      case SATR_PRICE_HIGH:
         price = high;
         break;
      case SATR_PRICE_LOW:
         price = low;
         break;
      case SATR_PRICE_MEDIAN:
         price = (high + low) / 2;
         break;
      case SATR_PRICE_TYPICAL:
         price = (high + low + close) / 3;
         break;
      case SATR_PRICE_WEIGHTED:
         price = (high + low + close + close) / 4;
         break;
      case SATR_PRICE_OHLC:
         price = (open + high + low +  close) / 4;
         break;
   }
   return price;
}