//+------------------------------------------------------------------+ //| SuperTrend.mq5 | //| eATR + 2x Offset ver | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, FxGeek" #property link "http://www.mql5.com" #property version "1.06" #property indicator_chart_window // プロット: // 0 = Filling // 1 = SuperTrend // 2 = TrendFlag (データウィンドウ用) // 3 = SuperTrend Offset1 // 4 = SuperTrend Offset2 #property indicator_plots 5 // バッファ数 // Filling×2 + SuperTrend×2 + TrendFlag×1 + Offset1×1 + Offset2×1 + 計算用5 = 12 #property indicator_buffers 12 // Plot0: Filling #property indicator_label1 "Filling" #property indicator_type1 DRAW_FILLING #property indicator_color1 clrGray, clrGray // Plot1: SuperTrend (カラーライン) #property indicator_label2 "SuperTrend" #property indicator_type2 DRAW_COLOR_LINE #property indicator_color2 clrGreen, clrRed, clrNONE #property indicator_width2 2 // Plot2: TrendFlag(描画なし・データウィンドウ表示のみ) #property indicator_label3 "TrendFlag (Up=1,Down=0)" #property indicator_type3 DRAW_NONE #property indicator_color3 clrWhite #property indicator_width3 1 // Plot3: OffsetLine1(固定色ライン) #property indicator_label4 "SuperTrend Offset1" #property indicator_type4 DRAW_LINE #property indicator_style4 STYLE_DOT #property indicator_color4 clrDimGray #property indicator_width4 1 // Plot4: OffsetLine2(固定色ライン) #property indicator_label5 "SuperTrend Offset2" #property indicator_type5 DRAW_LINE #property indicator_style5 STYLE_DOT #property indicator_color5 clrSlateGray #property indicator_width5 1 // 中央値の計算方法 enum ENUM_MIDDLE_TYPE { MIDDLE_OPEN, // 始値 MIDDLE_HIGH, // 高値 MIDDLE_LOW, // 安値 MIDDLE_CLOSE, // 終値 MIDDLE_HL, // 高値+安値の平均 MIDDLE_HLC, // 高値+安値+終値の平均 MIDDLE_OHLC, // 始値+高値+安値+終値の平均 MIDDLE_HLCC // 高値+安値+終値x2の平均 }; input int Periode = 10; input double Multiplier = 2.0; input bool Show_Filling = false; // DRAW_FILLINGのON/OFF input ENUM_MIDDLE_TYPE MiddleType = MIDDLE_HLCC; // 中央値の計算方法 // オフセット設定(2本分) input double offsetpips1 = 80.0; // オフセット1(pips). 0以下なら Offset1 非表示 input bool offset1_reverse = true; // true: 方向を逆にする(買い=上, 売り=下 など) input double offsetpips2 = 120.0; // オフセット2(pips). 0以下なら Offset2 非表示 input bool offset2_reverse = false; // true: 方向を逆にする //--- バッファ(プロット順に並べる) double Filled_a[]; // Plot0 buf#0 double Filled_b[]; // Plot0 buf#1 double SuperTrend[]; // Plot1 buf#2 (data) double ColorBuffer[]; // Plot1 buf#3 (color index) double TrendFlag[]; // Plot2 buf#4 (Up=1/Down=0) double OffsetLine1[]; // Plot3 buf#5 (data) double OffsetLine2[]; // Plot4 buf#6 (data) // 計算用(データウィンドウ非表示) double Atr[]; // buf#7 ← eATR(EMA ATR) double Up[]; // buf#8 double Down[]; // buf#9 double Middle[]; // buf#10 double trend[]; // buf#11 int changeOfTrend; int flag; int flagh; //+------------------------------------------------------------------+ //| 1pip の価格差を返すヘルパ | //+------------------------------------------------------------------+ double PipPoint(string Currency) { // GOLD(XAUUSDなど)の場合は必要に応じて調整 if (Currency == "XAUUSD" || Currency == "GOLD") { return (0.1); } int SymbolDigits = (int)SymbolInfoInteger(Currency, SYMBOL_DIGITS); switch (SymbolDigits) { case 2: return (0.01); case 3: return (0.01); case 4: return (0.0001); case 5: return (0.0001); } return (0.0); // 不明な場合 } //+------------------------------------------------------------------+ //| OnInit | //+------------------------------------------------------------------+ int OnInit() { // プロット用バッファ SetIndexBuffer(0, Filled_a, INDICATOR_DATA); // Plot0 SetIndexBuffer(1, Filled_b, INDICATOR_DATA); // Plot0 SetIndexBuffer(2, SuperTrend, INDICATOR_DATA); // Plot1 data SetIndexBuffer(3, ColorBuffer, INDICATOR_COLOR_INDEX); // Plot1 color SetIndexBuffer(4, TrendFlag, INDICATOR_DATA); // Plot2 SetIndexBuffer(5, OffsetLine1, INDICATOR_DATA); // Plot3 SetIndexBuffer(6, OffsetLine2, INDICATOR_DATA); // Plot4 // 計算用バッファ SetIndexBuffer(7, Atr, INDICATOR_CALCULATIONS); SetIndexBuffer(8, Up, INDICATOR_CALCULATIONS); SetIndexBuffer(9, Down, INDICATOR_CALCULATIONS); SetIndexBuffer(10, Middle, INDICATOR_CALCULATIONS); SetIndexBuffer(11, trend, INDICATOR_CALCULATIONS); return (INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| OnCalculate | //+------------------------------------------------------------------+ 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 (rates_total <= Periode + 2) return (prev_calculated); // バッファ不足時は何もしない //================================================================= // (1) eATR を内部計算(True Range → EMA) //================================================================= double alpha = 2.0 / (Periode + 1.0); // EMA係数 // series配列(0=最新, rates_total-1=最古) for (int i = rates_total - 1; i >= 0; i--) { double tr; if (i == rates_total - 1) { // 一番古いバー: 前日終値がないので High-Low のみ tr = high[i] - low[i]; Atr[i] = tr; // 初期値 } else { double range1 = high[i] - low[i]; double range2 = MathAbs(high[i] - close[i + 1]); double range3 = MathAbs(low[i] - close[i + 1]); tr = MathMax(range1, MathMax(range2, range3)); Atr[i] = alpha * tr + (1.0 - alpha) * Atr[i + 1]; } } //================================================================= // (2) SuperTrend 本体計算 //================================================================= int first; if (prev_calculated > rates_total || prev_calculated <= 0) { first = Periode; // 初期区間は未定義表示にしておく for (int k = 0; k < first && k < rates_total; ++k) { Filled_a[k] = EMPTY_VALUE; Filled_b[k] = EMPTY_VALUE; SuperTrend[k] = EMPTY_VALUE; TrendFlag[k] = EMPTY_VALUE; OffsetLine1[k] = EMPTY_VALUE; OffsetLine2[k] = EMPTY_VALUE; } } else { first = prev_calculated - 1; } const double pip = PipPoint(_Symbol); // 本体ループ for (int i = first; i < rates_total && !IsStopped(); i++) { // --- 中央値 ------------------------------------------------- switch (MiddleType) { case MIDDLE_OPEN: Middle[i] = open[i]; break; case MIDDLE_HIGH: Middle[i] = high[i]; break; case MIDDLE_LOW: Middle[i] = low[i]; break; case MIDDLE_CLOSE: Middle[i] = close[i]; break; case MIDDLE_HL: Middle[i] = (high[i] + low[i]) / 2.0; break; case MIDDLE_HLC: Middle[i] = (high[i] + low[i] + close[i]) / 3.0; break; case MIDDLE_OHLC: Middle[i] = (open[i] + high[i] + low[i] + close[i]) / 4.0; break; case MIDDLE_HLCC: Middle[i] = (high[i] + low[i] + 2.0 * close[i]) / 4.0; break; } // --- eATR を使用した Up/Down バンド ------------------------ Up[i] = Middle[i] + (Multiplier * Atr[i]); Down[i] = Middle[i] - (Multiplier * Atr[i]); // --- トレンド判定 ------------------------------------------ if (close[i] > Up[i - 1]) { trend[i] = 1; if (trend[i - 1] == -1) changeOfTrend = 1; } else if (close[i] < Down[i - 1]) { trend[i] = -1; if (trend[i - 1] == 1) changeOfTrend = 1; } else if (trend[i - 1] == 1) { trend[i] = 1; changeOfTrend = 0; } else if (trend[i - 1] == -1) { trend[i] = -1; changeOfTrend = 0; } // --- 交差フラグ -------------------------------------------- flag = (trend[i] < 0 && trend[i - 1] > 0) ? 1 : 0; flagh = (trend[i] > 0 && trend[i - 1] < 0) ? 1 : 0; // --- バンドの継続補正 -------------------------------------- if (trend[i] > 0 && Down[i] < Down[i - 1]) Down[i] = Down[i - 1]; if (trend[i] < 0 && Up[i] > Up[i - 1]) Up[i] = Up[i - 1]; if (flag == 1) Up[i] = Middle[i] - (-Multiplier * Atr[i]); // = Middle + Multiplier*ATR if (flagh == 1) Down[i] = Middle[i] + (-Multiplier * Atr[i]); // = Middle - Multiplier*ATR // --- SuperTrend と色 ---------------------------------------- if (trend[i] == 1) { SuperTrend[i] = Down[i]; if (changeOfTrend == 1) { SuperTrend[i - 1] = SuperTrend[i - 2]; OffsetLine1[i - 1] = OffsetLine1[i - 2]; OffsetLine2[i - 1] = OffsetLine2[i - 2]; changeOfTrend = 0; ColorBuffer[i] = 2.0; // 無色 ColorBuffer[i - 1] = 2.0; // 無色 } else { ColorBuffer[i] = 0.0; // Green } } else // trend[i] == -1 { SuperTrend[i] = Up[i]; if (changeOfTrend == 1) { SuperTrend[i - 1] = SuperTrend[i - 2]; OffsetLine1[i - 1] = OffsetLine1[i - 2]; OffsetLine2[i - 1] = OffsetLine2[i - 2]; changeOfTrend = 0; ColorBuffer[i] = 2.0; // 無色 ColorBuffer[i - 1] = 2.0; // 無色 } else { ColorBuffer[i] = 1.0; // Red } } // --- TrendFlag: Up=1 / Down=0 ------------------------------ TrendFlag[i] = (trend[i] == 1) ? 1.0 : 0.0; // --- OffsetLine1(offsetpips1<=0なら非表示) --------------- if (offsetpips1 > 0.0) { double dir1; if (trend[i] == 1) // 買いトレンド dir1 = offset1_reverse ? 1.0 : -1.0; else // 売りトレンド dir1 = offset1_reverse ? -1.0 : 1.0; OffsetLine1[i] = SuperTrend[i] + dir1 * offsetpips1 * pip; } else { OffsetLine1[i] = EMPTY_VALUE; } // --- OffsetLine2(offsetpips2<=0なら非表示) --------------- if (offsetpips2 > 0.0) { double dir2; if (trend[i] == 1) // 買いトレンド dir2 = offset2_reverse ? 1.0 : -1.0; else // 売りトレンド dir2 = offset2_reverse ? -1.0 : 1.0; OffsetLine2[i] = SuperTrend[i] + dir2 * offsetpips2 * pip; } else { OffsetLine2[i] = EMPTY_VALUE; } // --- Filling の可否 ---------------------------------------- if (Show_Filling) { Filled_a[i] = SuperTrend[i]; Filled_b[i] = close[i]; } else { Filled_a[i] = EMPTY_VALUE; Filled_b[i] = EMPTY_VALUE; } } return (rates_total); } //+------------------------------------------------------------------+