Files

285 lines
17 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+