マルチタイムフレームの移動平均線がクロス(シフトしたMA)したら縦線を挿入するソースコードを教えてください。 - ページ 2 12 新しいコメント Shino Unada 2023.09.10 01:48 #11 下記のプログラムは私が以前に作成したもので、ここで取り扱った方法とは違います。 時間枠の指定は1つだけで、2つのMAに違う時間枠を割り当てることはできません。別々に指定するのは複雑過ぎて、恐らく無理です。 シフトはMA2だけに指定していますが、追加によりMA1にも割り当てることができます。 MAは完全に滑らかな曲線にはなりません。所々やや不自然な部分が出ますが元々そういう仕様です。 完全に滑らかな曲線が希望なら、MA本数を倍数指定(例えば5分足に1時間足を表示なら12倍)して疑似的なMTFを表示する方が楽です。 //+------------------------------------------------------------------+ //| MTF_Sample_4.mq4 | //| Naguisa Unada | //| https://www.mql5.com/en/users/unadajapon/news | //+------------------------------------------------------------------+ #property copyright "Naguisa Unada" #property link "https://www.mql5.com/en/users/unadajapon/news" #property version "1.00" #property strict #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 #define _mtfCall(_buff, _y) iCustom(NULL, TimeFrame, IndicatorFileName, PERIOD_CURRENT, MA1_Period, MA2_Period, MA_Method, MA_Price, Shift, _buff, _y) #define _interpolate(buff) buff[i + k] = buff[i] + (buff[i + n] - buff[i]) * k / n //--- plot MA #property indicator_label1 "Moving Average 1" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 2 //--- plot MA #property indicator_label2 "Moving Average 2" #property indicator_type2 DRAW_LINE #property indicator_color2 clrYellow #property indicator_style2 STYLE_SOLID #property indicator_width2 2 //--- plot Arrow #property indicator_label3 "Up Arrow" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrAqua #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- plot Arrow #property indicator_label4 "Down Arrow" #property indicator_type4 DRAW_ARROW #property indicator_color4 clrRed #property indicator_style4 STYLE_SOLID #property indicator_width4 1 //--- input parameters input ENUM_TIMEFRAMES TimeFrame = PERIOD_CURRENT; //時間枠 input int MA1_Period = 24; //計算本数1 input int MA2_Period = 48; //計算本数2 input ENUM_MA_METHOD MA_Method = MODE_SMA; //計算方式 input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; //適用価格 input int Shift = 0; //MA2 シフト input bool Interpolate = true; //ギザギザを修正 input bool Alert_ON = true; //アラートを許可 input int Alert_bar = 0; //アラートタイミング input bool Show_Arrow = true; //矢印を表示 //--- indicator buffers double MA1_Buffer[]; double MA2_Buffer[]; double ArrUp_Buffer[]; double ArrDn_Buffer[]; string IndicatorFileName; int tFrame; datetime Up_time = D'2000.01.01 00:00'; datetime Dn_time = D'2000.01.01 00:00'; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, MA1_Buffer); SetIndexBuffer(1, MA2_Buffer); SetIndexBuffer(2, ArrUp_Buffer); SetIndexBuffer(3, ArrDn_Buffer); SetIndexShift(1, Shift); SetIndexArrow(2, 233); SetIndexArrow(3, 234); //---- if (TimeFrame < Period()) tFrame = Period(); else tFrame = TimeFrame; string TimeFrameStr = GetTimeFrameString(tFrame); string short_name = "Moving Average(" + IntegerToString(MA1_Period) + "," + IntegerToString(MA2_Period) + ") " + TimeFrameStr; IndicatorShortName(short_name); IndicatorFileName = WindowExpertName(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //---- //---- } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ 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 i, y, n, k, j, limit; datetime ctime; double Total, Gap; if (prev_calculated < 0) return(-1); if (prev_calculated == 0) limit = rates_total - MathMax(MA1_Period, MA2_Period); else limit = rates_total - prev_calculated + 1; if (tFrame == Period()) { for (i = limit; i >= 0; i--) { MA1_Buffer[i] = iMA(NULL, PERIOD_CURRENT, MA1_Period, 0, MA_Method, MA_Price, i); MA2_Buffer[i] = iMA(NULL, PERIOD_CURRENT, MA2_Period, 0, MA_Method, MA_Price, i); } } else { limit = (int)MathMax(limit, MathMin(rates_total - MathMax(MA1_Period, MA2_Period), (limit + 1) * tFrame / Period())); for (i = limit; i >= 0; i--) { y = iBarShift(NULL, tFrame, time[i]); MA1_Buffer[i] = _mtfCall(0, y); MA2_Buffer[i] = _mtfCall(1, y); if (!Interpolate || (i > 0 && y == iBarShift(NULL, tFrame, time[i - 1]))) continue; ctime = iTime(NULL, tFrame, y); for (n = 1; (i + n) < rates_total && time[i + n] >= ctime; n++) continue; for (k = 1; k < n && (i + n) < rates_total && (i + k) < rates_total; k++) { _interpolate(MA1_Buffer); _interpolate(MA2_Buffer); } } } if (Show_Arrow) { for (i = limit; i >= 0; i--) { Total = 0.0; for (j = i; j < i + 10; j++) Total += high[j] - low[j]; Gap = Total / 10; if (MA1_Buffer[i] > MA2_Buffer[i] && MA1_Buffer[i + 1] < MA2_Buffer[i + 1]) ArrUp_Buffer[i] = MA1_Buffer[i] - Gap; else ArrUp_Buffer[i] = EMPTY_VALUE; if (MA1_Buffer[i] < MA2_Buffer[i] && MA1_Buffer[i + 1] > MA2_Buffer[i + 1]) ArrDn_Buffer[i] = MA1_Buffer[i] + Gap; else ArrDn_Buffer[i] = EMPTY_VALUE; } } if (Alert_ON) Do_Alert(Alert_bar); //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ string GetTimeFrameString(int timeFrame) { string TimeFrameStr; if (timeFrame == PERIOD_CURRENT) timeFrame = Period(); switch(timeFrame) { case PERIOD_M1 : TimeFrameStr = "M1"; break; case PERIOD_M5 : TimeFrameStr = "M5"; break; case PERIOD_M15 : TimeFrameStr = "M15"; break; case PERIOD_M30 : TimeFrameStr = "M30"; break; case PERIOD_H1 : TimeFrameStr = "H1"; break; case PERIOD_H4 : TimeFrameStr = "H4"; break; case PERIOD_D1 : TimeFrameStr = "D1"; break; case PERIOD_W1 : TimeFrameStr = "W1"; break; case PERIOD_MN1 : TimeFrameStr = "MN1"; break; } return(TimeFrameStr); } //+------------------------------------------------------------------+ void Do_Alert(int i) { if (Up_time != Time[i] && MA1_Buffer[i] > MA2_Buffer[i] && MA1_Buffer[i + 1] < MA2_Buffer[i + 1]) { Alert(StringSubstr(Symbol(), 0, 6) + " - " + GetTimeFrameString(tFrame) + " --- Up Trend"); Up_time = Time[i]; } if (Dn_time != Time[i] && MA1_Buffer[i] < MA2_Buffer[i] && MA1_Buffer[i + 1] > MA2_Buffer[i + 1]) { Alert(StringSubstr(Symbol(), 0, 6) + " - " + GetTimeFrameString(tFrame) + " --- Down Trend"); Dn_time = Time[i]; } } //+------------------------------------------------------------------+ 12 新しいコメント 取引の機会を逃しています。 無料取引アプリ 8千を超えるシグナルをコピー 金融ニュースで金融マーケットを探索 新規登録 ログイン スペースを含まないラテン文字 このメールにパスワードが送信されます エラーが発生しました Googleでログイン WebサイトポリシーおよびMQL5.COM利用規約に同意します。 新規登録 MQL5.com WebサイトへのログインにCookieの使用を許可します。 ログインするには、ブラウザで必要な設定を有効にしてください。 ログイン/パスワードをお忘れですか? Googleでログイン
下記のプログラムは私が以前に作成したもので、ここで取り扱った方法とは違います。
時間枠の指定は1つだけで、2つのMAに違う時間枠を割り当てることはできません。別々に指定するのは複雑過ぎて、恐らく無理です。
シフトはMA2だけに指定していますが、追加によりMA1にも割り当てることができます。
MAは完全に滑らかな曲線にはなりません。所々やや不自然な部分が出ますが元々そういう仕様です。
完全に滑らかな曲線が希望なら、MA本数を倍数指定(例えば5分足に1時間足を表示なら12倍)して疑似的なMTFを表示する方が楽です。