パラメーターで任意の時間軸を選択し、MTFの移動平均線を表示する
以前はたまにしかMTF(MultiTimeFrame)の移動平均線をチャートに表示していなかったので、必要になったら、その都度、移動平均線を描画するインディケーターを作っていました。
しかし、最近MTFの移動平均線をチャートに入れてあれこれ調べることが増えました。こうなると、その都度作るのが面倒になってきたため、パラメーターで任意の時間軸(MTF)を選ぶ方式のコードを書きました。
コード
//---------------------------------------------------------------------------- // FileName : MyMA_Multi.mq4 // Feature : MTFのMAを表示するインディケーター //---------------------------------------------------------------------------- #property copyright "Copyright 2020. PHILOJUAN" #property link "https://uhoho.hatenablog.jp/" #property version "1.00" #property indicator_chart_window #property strict #property indicator_buffers 1 enum OnOff {OFF, ON}; input ENUM_TIMEFRAMES maTF = PERIOD_CURRENT; // MAの時間軸(MultiTimeFrame) input int maPeriod = 20; // MAの期間 input ENUM_MA_METHOD method = MODE_SMA; // 計算方法(SMA, EMA等) input ENUM_APPLIED_PRICE price = PRICE_CLOSE; // 適用価格(デフォルトは終値) input int maWidth = 2; // MAの太さ input color maColor = clrLightPink; // MAの色 input OnOff repaint = ON; // リペイント int chartTF = 0; // チャートのTimeFrameを格納する変数 int BarsToRecalculate = 0; // リペイントの対象となるローソク足の本数 // MA用バッファ double MultiMA[]; int OnInit() { // ラベル名を作成 string label = ChangeTimeFrameExp(maTF) + "_" + IntegerToString(maPeriod) + "_" + ChangeMAmodeExp(method); SetIndexStyle (0, DRAW_LINE, STYLE_SOLID, maWidth, maColor); SetIndexBuffer(0, MultiMA); SetIndexLabel (0, label); chartTF = Period(); // MAをリペイントするーソク足の本数を計算 // → MAの時間軸(分) ÷ チャートの時間軸(分) = リペイント本数 if(repaint && (maTF > chartTF)) { if((maTF % chartTF) == 0) BarsToRecalculate = maTF / chartTF; else BarsToRecalculate = maTF / chartTF + 1; } return(0); } int start() { int counted_bars = IndicatorCounted(); if(!counted_bars) // counted_barsが 0 のとき { // 計算対象から除外するローソク足の本数を計算 if((maTF * maPeriod % chartTF) == 0) counted_bars = maTF * maPeriod / chartTF; else counted_bars = maTF * maPeriod / chartTF + 1; } else if(repaint) // counted_barsが 0 ではなく、かつ、repaintがONのとき { // リペイントするローソク足の本数を counted_bars から差し引く。 counted_bars = counted_bars - BarsToRecalculate; } // limitは計算対象となるローソク足の本数 int limit = Bars - counted_bars; for(int i = limit - 1; i >= 0; i--) { MultiMA[i] = EMPTY_VALUE; int shift_Multi = iBarShift(NULL, maTF, iTime(NULL, 0, i), false); MultiMA[i] = iMA(NULL, maTF, maPeriod, 0, method, price, shift_Multi); } return(0); } // MAの計算方法の表現を「SMA」等に変換する関数 // → 「MODE_SMA」等は整数値。これを「SMA」等の文字列にして返す。 string ChangeMAmodeExp(ENUM_MA_METHOD original) { string res = ""; switch(original) { case 0: // MODE_SMA res = "SMA"; break; case 1: // MODE_EMA res = "EMA"; break; case 2: // MODE_SMMA res = "SMMA"; break; case 3: // MODE_LWMA res = "LWMA"; break; default: res = "ERROR"; break; } return res; } // 時間軸の表現を「M1」等に変換する関数 // → 「PERIOD_M5」等は整数値。これを「M5」等の文字列にして返す。 string ChangeTimeFrameExp(ENUM_TIMEFRAMES tf) { string res = ""; // 戻り値を格納する変数 // 通常は、引数で受け取った時間軸を使用 int frame = tf; // 引数が PERIOD_CURRENTの場合、チャートの時間軸を使用 if(!tf) frame = Period(); // 変換処理 if(frame < 60) res = "M" + IntegerToString(frame); else if(frame < 1440) // D1は1440分 res = "H" + IntegerToString(frame / 60); else if(frame == 1440) res = "D1"; else if(frame == 10080) res = "W1"; else if(frame == 43200) res = "MN1"; else res = "ERROR"; return res; }