トップ  >  自作してみる >  MQL4未経験者向け(インジケータ作成の基本)  >  メインウインドウ  >  M2.トレンド系インジケータ作成(移動平均線)
M2.トレンド系インジケータ作成(移動平均線)



mq4ファイルを複製する


移動平均のカスタムインジケータを作成するのですが、
以前紹介したMQLウィザードは使用しません。

前回作成した終値ラインのカスタムインジケータのソースコードを複製して、それをベースにします。

まずはメタエディターのメニューから

ファイル ⇒ データフォルダを開く

を選択します。
インジケータ移動平均

データフォルダが開かれますので、MQL4フォルダを開きます。
インジケータ移動平均

MQL4フォルダを開いたらIndicatorsフォルダを開きます。
インジケータ移動平均

Indicatorsフォルダの下に前回作成したTestCloseLine.mq4ファイルがありますので、これをコピー&ペーストして複製します。


インジケータ移動平均

TestCloseLine.mq4ファイルを複製したら、TestMALine.mq4に名前を変更します。


インジケータ移動平均

メタエディターのナビゲータにTestMALine.mq4ファイルが追加されます。
単純にコピーしただけなので、ソースコード内のコメントは直しておきましょう
(コメントは変更しなくても問題ありませんが、動作に影響しない部分なのでうっかり直し忘れる事があります)。

移動平均線インジケータを表示する


終値ラインを表示するインジケータのソースコードを基に作成するので、これを移動平均線に変更するのは非常に簡単です。

インジケータ1表示用動的配列に終値を設定していた行をコメントアウトし、
代わりに移動平均の価格を設定します。

移動平均の価格はMQL4で事前に用意されているテクニカルインジケータ関数iMA関数を使用して算出します。

ソースコード:
    for( int icount = 0 ; icount < end_index ; icount++ ) {
        double get_ma = iMA (               // 移動平均算出
                             Symbol(),      // 通貨ペア
                             Period(),      // 時間軸
                             25,             // MAの平均期間
                             0,              // MAシフト
                             MODE_SMA,     // MAの平均化メソッド
                             PRICE_CLOSE,  // 適用価格
                             icount          // シフト
                        );

        //_IndBuffer1[icount] = Close[icount];   // インジケータ1に終値を設定
        _IndBuffer1[icount] = get_ma;       // インジケータ1に移動平均を設定

    }


コンパイルしTestMALine.ex4ファイルをチャートに適用すると

インジケータ移動平均

25MAのチャートが表示されます。

テクニカルインジケータ関数

先程使用したテクニカルインジケータ関数iMA関数の引数について説明しましょう。

プログラミング未経験者の人は、引数の多い関数を見ると挫折しそうになりますが、
一つずつ説明するので投げ出さずに読んで下さい。


まず、MQL4で事前に用意されている関数は、その関数毎に戻り値や引数がある為、必ずリファレンスを確認する必要があります。
このリファレンス確認の作業は一生続きます。
勿論、頻繁に使用する関数で覚えてしまっているものはリファレンスを確認する必要はありません。

プログラミング未経験者はリファレンスを確認せずに「XXXの関数のパラメータに何を設定すればいいですか?」という類の問い合わせをしてくる事が多い(MQL4に限らずIT企業に入社した社員や外注プログラマーもリファレンスやマニュアルを見ずに似たような質問をして来ます)です。

このページではプログラミング未経験者にも分かるように細かく説明していますが、他テクニカルインジケータ関数を使用する際には自身でテクニカルインジケータ関数のリファレンスを調べる必要があります。

◆iMAの第1引数
    Symbol(),      // 通貨ペア

iMA関数 の第1引数には、移動平均を算出する通貨ペアを設定する必要があります。
ここではSymbol()を指定します、 Symbol()は現在の通貨ペアの値を返します。

もし違う通貨ペアを指定した場合、指定した通貨ペアの移動平均を算出する事になります。


◆iMAの第2引数
    Period(),      // 時間軸

iMA関数 の第2引数には、移動平均を算出する時間軸を設定する必要があります。
ここではPeriod()を指定します、 Period()は現在の時間軸の値を返します。

もし違う時間軸を指定した場合、指定した時間軸の移動平均を算出する事になります。
違う時間軸を指定したい場合はENUM_TIMEFRAMES列挙の値を使用します。


◆iMAの第3引数
    25,             // MAの平均期間

iMA関数 の第3引数には、移動平均を算出する期間を設定する必要があります。
ここでは25を指定していますので、過去25本の移動平均を算出する事になります。
まさか「移動平均って何?」という人はいないと思いますが(昔現場で外注プログラマーが「移動平均って何?」と聞いてきた人がいました)、そもそも移動平均が分からないという人はWikipediaで調べて下さい。


◆iMAの第4引数
    0,              // MAシフト

iMA関数 の第4引数には、移動平均を算出するインデックスのオフセット設定します。
ちょっとややこしいのですが、算出するインデックスでは無く、インデックスのオフセットである事に注意して下さい。
オフセットする必要が無い場合は0を指定します。
理解するのが難しかったら0固定で指定して下さい。

ちなみにオフセット1を指定した場合
インジケータ移動平均

水色の移動平均線が1オフセット指定したインジケータです。
このように指定したインデックス+1オフセットした移動平均が算出されます。


◆iMAの第5引数
    MODE_SMA,     // MAの平均化メソッド

iMA関数 の第5引数には、移動平均の算出方法(単純移動平均や指数移動平均等)を指定します。
MQL4で用意されている移動平均メソッド用インジケータ定数リストのENUM_MA_METHODを使って設定します。
ここではMODE_SMAを指定していますので、単純移動平均が算出されます。


◆iMAの第6引数
    PRICE_CLOSE,  // 適用価格

iMA関数 の第6引数には、どの価格を基に移動平均を算出するかを指定します。
MQL4で用意されている価格定数用インジケータ定数リストのENUM_APPLIED_PRICEを使って設定します。
ここではPRICE_CLOSEを指定していますので、終値を基に移動平均を算出します。


◆iMAの第7引数
    icount          // シフト

iMA関数 の第7引数には、どのバーの移動平均を算出するかを指定します。
ここではforループカウンターのicountを指定していますので、バーインデックスが指定されます。
このバーインデックスを起点に過去25本のバーから移動平均が算出される事になります。


これら全ての引数の設定値から、
現在表示されているチャートの通貨ペアと時間軸で、終値を基に25本の単純移動平均が算出される事が分かります。


インプットパラメータ設定(input変数)

移動平均線は終値ラインと違って算出期間等のパラメータで使用用途を広げられるので、
input変数を追加してこのインジケータにパラメータを追加します。

input変数は、関数の外で宣言した変数にinput修飾子を付けます。

ソースコード:
// インプットパラメータ
input int  _InputMAPeriod      = 25;               // 移動平均期間

関数の外に、_InputMAPeriodというint型の変数を宣言して、先頭にinput修飾子をつけます。

インジケータ移動平均

インジケータのプロパティを確認すると、"パラメータの入力タグ"に"移動平均期間"という変数が追加されています。

当然ですが、未だこのinput変数は宣言しただけなので、 この値を変更しても何も変わりません。
何故かこのインプットパラメータを追加しただけで勝手に機能が追加されると思い込む人がいるのですが、最初に説明した通りコンピュータは賢くないので1~10まで全て指示しなければなりません。
つまりこのインプットパラメータに対して何をさせたいのか?という事を全て指示する必要があります。

iMA関数の引数に25というマジックナンバーを使用していたので、マジックナンバーの代わりにこのinput変数の_InputMAPeriodを使用するように変更しましょう。

ソースコード:
double get_ma = iMA (               // 移動平均算出
                     Symbol(),      // 通貨ペア
                     Period(),      // 時間軸
                     _InputMAPeriod, // MAの平均期間
                     0,              // MAシフト
                     MODE_SMA,     // MAの平均化メソッド
                     PRICE_CLOSE,  // 適用価格
                     icount          // シフト
                );


コンパイルして、パラメータの移動平均期間を5に変更してみましょう。
インジケータ移動平均

5本の単純移動平均が表示されました。
インジケータ移動平均


完成したサンプルソースコード


最後に出来上がったソースコードをまとめると、

ソースコード:
//+------------------------------------------------------------------+
//|                                                   TestMALine.mq4 |
//|                                                             yuki |
//|                                      https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict // strictは絶対に削除しない事
#property indicator_chart_window // カスタムインジケータをチャートウインドウに表示する

// インジケータプロパティ設定
#property  indicator_buffers    1               // カスタムインジケータのバッファ数
#property  indicator_color1     clrWhite      // インジケータ1の色
#property  indicator_width1     2               // インジケータ1の太さ

// マクロ定義
#define    IND_MIN_INDEX         2               // 最小バー数

// インジケータ表示用動的配列
double     _IndBuffer1[];                          // インジケータ1表示用動的配列

// インプットパラメータ
input int  _InputMAPeriod      = 25;               // 移動平均期間

//+------------------------------------------------------------------+
//| OnInit(初期化)イベント
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer( 0, _IndBuffer1 );     // インジケータ1表示用動的配列をインジケータ1にバインドする

   return( INIT_SUCCEEDED );      // 戻り値:初期化成功
}

//+------------------------------------------------------------------+
//| OnCalculate(tick受信)イベント
//| カスタムインジケータ専用のイベント関数
//+------------------------------------------------------------------+
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[],   // Tick出来高
                const long     &volume[],        // Real出来高
                const int      &spread[])        // スプレッド
{
    int end_index = Bars - prev_calculated;  // バー数取得(未計算分)
    if ( end_index <= IND_MIN_INDEX ) {    // 直近数本は常時更新
        end_index = IND_MIN_INDEX;
    }

    if ( Bars <= IND_MIN_INDEX ) {         // ヒストリカルデータ不足時
        return 0;                            // 全て再計算が必要なので、計算済みバー数を0にして終了する
    }

    for( int icount = 0 ; icount < end_index ; icount++ ) {
        double get_ma = iMA (               // 移動平均算出
                             Symbol(),      // 通貨ペア
                             Period(),      // 時間軸
                             _InputMAPeriod, // MAの平均期間
                             0,              // MAシフト
                             MODE_SMA,     // MAの平均化メソッド
                             PRICE_CLOSE,  // 適用価格
                             icount          // シフト
                        );

        _IndBuffer1[icount] = get_ma;       // インジケータ1に移動平均を設定

    }

   return( rates_total ); // 戻り値設定:次回OnCalculate関数が呼ばれた時のprev_calculatedの値に渡される
}



コメントアウトしていた終値ラインの行は削除しました。
iMA関数の引数を分かり易いように複数行で書きましたが、あれは1行でも書けるので、
実質変更したソースコードは4行だけです。

iMA関数を使っている部分を他のテクニカルインジケータ関数に変える事で、
簡単に他インジケータを作る事が出来ます。

課題


上記サンプルソースコード変更して、指数移動平均(EMA)のカスタムインジケータを作成して下さい。

■ヒント
ENUM_MA_METHOD




スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
スポンサーリンク


Copyright ©2015 MT4でEA自作しちゃお~ All Rights Reserved.


Top

inserted by FC2 system