2017年8月14日月曜日

[MT4インジケータ]通貨の強弱を表示する。


■通貨の強弱推移の表示インジケータ

お盆休みです。
皆様休みの間もトレードしていますか?

私はこの時間を利用して溜まっていた宿題的な何かをしています。
今度のEAはマルチ通貨に対してトレードすることによりトレード機会を増やそうと思い強弱を判定するインジケータを作成しました。

移動平均の変化量の割合をみて強弱を判定します。
USDを基準に観測していますので、USD+その他通貨 という組み合わせが予めMT4のチック値に表示されている必要があるので注意してください。

具体的には
EURUSD
GBPUSD
AUDUSD
NZDUSD
USDCHF
USDJPY
USDCAD
の7つの組み合わせが必要です。

インジケータを表示するチャートの通貨ペアは、どれでもでも構いません。

基本的には弱い通貨を売って強い通貨を買うのが基本戦略となります。
ただしある程度のトレンドとして捉える為、割と長めの時間足で使おうかなと考えています。まぁざっくりいうと、弱い通貨の売りハモと強い通貨の買いハモだけトレードしてみよかな?といったことを考えています。

FX-ONのダウンロードはこちらから

ソースコードはこちらから




//------------------------------------------------------------------
// 通貨強弱インジケータ
#property copyright "Copyright 2017,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.01"
#property strict
#property indicator_separate_window

#include <Arrays/ArrayString.mqh>

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

input string sep00 = "";            //【通貨】
input string Currency1 = "EUR";     // 対象通貨1
input color Color1 = clrDodgerBlue; // 対象通貨1色

input string Currency2 = "GBP";     // 対象通貨2
input color Color2 = clrMagenta;    // 対象通貨2色

input string Currency3 = "AUD";     // 対象通貨3
input color Color3 = clrGreen ;     // 対象通貨3色

input string Currency4 = "NZD";     // 対象通貨4
input color Color4 = clrSilver;     // 対象通貨4色

input string Currency5 = "USD";     // 対象通貨5
input color Color5 = clrAqua;       // 対象通貨5色

input string Currency6 = "CAD";     // 対象通貨6
input color Color6 = clrPink;       // 対象通貨6色

input string Currency7 = "CHF";     // 対象通貨7
input color Color7 = clrPaleGreen;  // 対象通貨7色

input string Currency8 = "JPY";     // 対象通貨8
input color Color8 = clrRed;        // 対象通貨8色

input string sep10 = "";            //【計算設定】
input int MaPeirod = 45;            // 強弱判定単純移動平均期間
input int MaxDraw = 1000;           // 最大描画本数

input string sep20 = "";            //【その他】
input string CurrencyPrefix = "";   // 通貨ペア名の前に付く文字列
input string CurrencyPostfix = "";  // 通貨ペア名の後に付く文字列

//バッファ
double m_buffer1[];
double m_buffer2[];
double m_buffer3[];
double m_buffer4[];
double m_buffer5[];
double m_buffer6[];
double m_buffer7[];
double m_buffer8[];

//通貨一覧
CArrayString m_currencies;

//通貨ペア一覧
CArrayString m_currencyPairs;

//USDインデックス
int m_usdIndex = -1;

//オブジェクト名
#define OBJECT_NAME "OBJ_CURR_HL"

//色配列
color m_colors[8];

//------------------------------------------------------------------
// 初期化
int OnInit()
{
   ClearObjects();

   IndicatorBuffers(8);
   
   IndicatorSetDouble(INDICATOR_MAXIMUM, 9);
   IndicatorSetDouble(INDICATOR_MINIMUM, 0);

   int count = 0 ;
   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color1);
   SetIndexBuffer(count++, m_buffer1);
   
   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color2);
   SetIndexBuffer(count++, m_buffer2);

   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color3);
   SetIndexBuffer(count++, m_buffer3);

   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color4);
   SetIndexBuffer(count++, m_buffer4);

   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color5);
   SetIndexBuffer(count++, m_buffer5);

   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color6);
   SetIndexBuffer(count++, m_buffer6);

   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color7);
   SetIndexBuffer(count++, m_buffer7);

   SetIndexStyle(count, DRAW_LINE, STYLE_SOLID, 1, Color8);
   SetIndexBuffer(count++, m_buffer8);
   
   m_currencies.Add(Currency1);
   m_currencies.Add(Currency2);
   m_currencies.Add(Currency3);
   m_currencies.Add(Currency4);
   m_currencies.Add(Currency5);
   m_currencies.Add(Currency6);
   m_currencies.Add(Currency7);
   m_currencies.Add(Currency8);
   
   m_colors[0] = Color1;
   m_colors[1] = Color2;
   m_colors[2] = Color3;
   m_colors[3] = Color4;
   m_colors[4] = Color5;
   m_colors[5] = Color6;
   m_colors[6] = Color7;
   m_colors[7] = Color8;

   m_usdIndex = -1;
   for( int i = 0; i < m_currencies.Total(); i++)
   {
      if(m_currencies.At(i) == "USD")
      {
         m_usdIndex = i;
         break;
      }
   }
   if( m_usdIndex < 0 )
   {
      //USDが見つからない場合、パラメータ異常
      return INIT_PARAMETERS_INCORRECT;
   }

   //USDに対する通貨ペアを生成する。   
   for( int i = 0; i < m_currencies.Total(); i++)
   {
      if( m_currencies.At(i) == "" )
      {
         m_currencyPairs.Add("");
         continue;
      }
      
      if( i < m_usdIndex )
      {
         m_currencyPairs.Add(CurrencyPrefix + m_currencies.At(i) + "USD" + CurrencyPostfix);
      }
      else if( i > m_usdIndex )
      {
         m_currencyPairs.Add(CurrencyPrefix + "USD" + m_currencies.At(i) + CurrencyPostfix);
      }
      else
      {
         m_currencyPairs.Add("USDUSD");
      }
      //線のラベルを設定する。
      SetIndexLabel(i, m_currencies.At(i));
   }
   
   ChartSetInteger(0, CHART_SHIFT, true);
   ChartSetDouble(0, CHART_SHIFT_SIZE, 12);

   return(INIT_SUCCEEDED);
}

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

//------------------------------------------------------------------
//計算イベント
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(prev_calculated != rates_total - 1)
   {
      int index[8];
      double rates[8];
      ArrayInitialize(index, 0);
      ArrayInitialize(rates, 0);
      int total = m_currencyPairs.Total();
      for( int i = rates_total - prev_calculated - 1; i >= 1; i-- )
      {
         if( i >= rates_total - (MaPeirod * 2) || i &gt; MaxDraw) continue;
         
         for( int j = 0; j < total; j++)
         {
            index[j] = j;
            string pair = m_currencyPairs.At(j);
            if( pair == "" )
            {
               rates[j] = EMPTY_VALUE ;
               continue;
            }
            else if( pair == "USDUSD" )
            {
               rates[j] = 1;
            }
            else  
            {
               double ma1 = iMA(pair, Period(), MaPeirod, 0, MODE_SMA, PRICE_CLOSE, i);
               double ma2 = iMA(pair, Period(), MaPeirod, 0, MODE_SMA, PRICE_CLOSE, i + MaPeirod);
               if( j &lt m_usdIndex )
                  rates[j] = ma2 > 0 ? ma1 / ma2 : 0;
               else
                  rates[j] = ma1 > 0 ? ma2 / ma1 : 0;
            }
         }
         
         //ソート行う。
         //とりあえずバブルソート
         for( int b = 1 ; b < total; b++ )
         {
            for( int j = 0; j < total - b; j++ )
            {
               if( rates[j] > rates[j + 1]  )
               {
                  double work = rates[j + 1];
                  rates[j + 1] = rates[j];
                  rates[j] = work;
                  
                  int indexWork = index[j + 1];
                  index[j + 1] = index[j];
                  index[j] = indexWork;
               }
            }
         }

         for( int j = 0; j < total; j++)
         {
            if( rates[j] != EMPTY_VALUE )
            {
               SetValue(index[j], j + 1, i);
            }
         }
      }
      
      //通貨ラベルを更新する。
      ClearObjects();

      for( int j = 0; j < total; j++)
      {
         //描画対象通貨(インデックス)
         int currencyIndex = (int)index[j];
      
         //価格テキストを追加する。
         string objectName = StringFormat("%s_TXT_%d", OBJECT_NAME, j);
      
         if( ObjectCreate(0, objectName, OBJ_TEXT, WindowOnDropped(), time[0], j + 1) )
         {
            // 表示文字列
            ObjectSetString(0, objectName, OBJPROP_TEXT, m_currencies.At(currencyIndex));
            
            // アンカー
            ObjectSetInteger(0, objectName, OBJPROP_ANCHOR, ANCHOR_BOTTOM);
            
            ObjectSetInteger(0, objectName, OBJPROP_COLOR, m_colors[currencyIndex]);
         }
      }
   }

   return rates_total - 1;
}

//------------------------------------------------------------------
//値を設定する。
void SetValue(
   int i,         //配列番号0~7
   int value,     //値
   int shift)     //シフト
{
   switch(i)
   {
      case 0:
         m_buffer1[shift] = value;
         break;
      case 1:
         m_buffer2[shift] = value;
         break;
      case 2:
         m_buffer3[shift] = value;
         break;
      case 3:
         m_buffer4[shift] = value;
         break;
      case 4:
         m_buffer5[shift] = value;
         break;
      case 5:
         m_buffer6[shift] = value;
         break;
      case 6:
         m_buffer7[shift] = value;
         break;
      case 7:
         m_buffer8[shift] = value;
         break;
   }
}

//------------------------------------------------------------------
//オブジェクトをすべて削除する。
void ClearObjects()
{
   long chartId = ChartID();   
   int total = ObjectsTotal( chartId );
   //生成したオブジェクトを削除する。
   //0から削除するとインデックス位置がずれて
   //正しく削除できないため、後ろから削除するようにする。
   for( int i = total - 1; i >= 0 ; i--)
   {
      string name = ObjectName( chartId, i );
      
      // 先頭文字列がRangeRectangleNameと一致する場合、削除する。
      if ( StringFind( name, OBJECT_NAME ) == 0 )
      {
         ObjectDelete( chartId, name );
      }
   }
}



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

Twitterもよろしくお願いします。
https://twitter.com/mt4program
Trading View プロフィール

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ FX テクニカルトレード派へ
にほんブログ村

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

2 件のコメント:

  1. はじめまして!
    インジケーター使用させて頂いているものです。
    ありがとうございます。

    この通貨の強弱推移の表示インジケータですが、ティック更新で変化するように(形が分かるように)して頂けないでしょうか?

    返信削除
  2. もっと細かく知りたい場合は、Ku-Chartなどをご利用されてはいかがでしょうか?

    ちなみにこのインジケータは確定足しか描画していませんが、最新足を描画するのは
    for( int i = rates_total - prev_calculated - 1; i >= 1; i-- )
    のi>=1をi>=0に変更すれば最新足まで見るようになるかと思います。

    なお、私は現在通貨強弱をトレンド情報の一種と捉えていますので、このインジは瞬間的な値動きはノイズとしてを除外する設計のインジケータとなっています。(その為単純移動平均を計算のベースとして利用しています)

    返信削除