285 lines
17 KiB
Plaintext
285 lines
17 KiB
Plaintext
//+------------------------------------------------------------------+
|
||
//| 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);
|
||
}
|
||
//+------------------------------------------------------------------+
|