//+------------------------------------------------------------------+ //| SuperTrend.mq5 | //| Copyright 2011, FxGeek | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2011, FxGeek" #property link "http://www.mql5.com" #property version "1.02" #property indicator_chart_window // プロット: 0=Filling, 1=SuperTrend, 2=TrendFlag (データウィンドウ用) #property indicator_plots 3 // バッファ数(Filling×2 + SuperTrend×2 + TrendFlag×1 + 計算用5) #property indicator_buffers 10 // 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 // 中央値の計算方法 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; // 中央値の計算方法 //--- バッファ 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 Atr[]; // buf#5 double Up[]; // buf#61 double Down[]; // buf#7 double Middle[]; // buf#8 double trend[]; // buf#9 int atrHandle; int changeOfTrend; int flag; int flagh; //+------------------------------------------------------------------+ //| 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, Atr, INDICATOR_CALCULATIONS); SetIndexBuffer(6, Up, INDICATOR_CALCULATIONS); SetIndexBuffer(7, Down, INDICATOR_CALCULATIONS); SetIndexBuffer(8, Middle, INDICATOR_CALCULATIONS); SetIndexBuffer(9, trend, INDICATOR_CALCULATIONS); // 価格桁数を変えたい場合はインジ全体設定(任意/通常は不要) // IndicatorSetInteger(INDICATOR_DIGITS, _Digits); atrHandle = iATR(_Symbol, _Period, Periode); if (atrHandle == INVALID_HANDLE) { Print(__FUNCTION__, ": iATR handle error. err=", GetLastError()); return (INIT_FAILED); } 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); // バッファ不足時は何もしない // ATR コピー本数の算定 int to_copy; if (prev_calculated > rates_total || prev_calculated < 0) to_copy = rates_total; else { to_copy = rates_total - prev_calculated; if (prev_calculated > 0) to_copy++; } if (IsStopped()) return (prev_calculated); if (CopyBuffer(atrHandle, 0, 0, to_copy, Atr) <= 0) { Print("Getting ATR failed. err=", GetLastError()); return (prev_calculated); } // 計算開始インデックス 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; } } else { first = prev_calculated - 1; } // 本体ループ 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; } 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]; 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]; 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; // 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); } //+------------------------------------------------------------------+