//+------------------------------------------------------------------+
//|                                                   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);
}
//+------------------------------------------------------------------+
