Files
EA_with_Python/Indicators/SuperTrend_CustomWithOffset.mq5
T

363 lines
21 KiB
Plaintext
Raw 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.03"
#property indicator_chart_window
// プロット:
// 0 = Filling
// 1 = SuperTrend
// 2 = TrendFlag (データウィンドウ用)
// 3 = SuperTrend Offset
#property indicator_plots 4
// バッファ数
// Filling×2 + SuperTrend×2 + TrendFlag×1 + Offset×1 + 計算用5 = 11
#property indicator_buffers 11
// 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: OffsetLine(固定色ライン)
#property indicator_label4 "SuperTrend Offset"
#property indicator_type4 DRAW_LINE
#property indicator_style4 STYLE_DOT
#property indicator_color4 clrDimGray
#property indicator_width4 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; // 中央値の計算方法
// 追加: オフセット設定
input double offsetpips = 80.0; // オフセット(pips). 0以下なら OffsetLine 非表示
input bool offset_reverse = true; // 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 OffsetLine[]; // Plot3 buf#5 (data)
// 計算用(データウィンドウ非表示)
double Atr[]; // buf#6
double Up[]; // buf#7
double Down[]; // buf#8
double Middle[]; // buf#9
double trend[]; // buf#10
int atrHandle;
int changeOfTrend;
int flag;
int flagh;
//+------------------------------------------------------------------+
//| 1pip の価格差を返すヘルパ |
//+------------------------------------------------------------------+
double PipPoint(string Currency)
{
// GOLD(XAUUSDなど)の場合は特別な計算を適用
if (Currency == "XAUUSD" || Currency == "GOLD")
{
// GOLDの場合の特別な計算
return (0.1); // ここでGOLDに適した値に変更
}
// MQL5ではSymbolInfoIntegerを使用して桁数を取得
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); // 桁数が一致しない場合は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, OffsetLine, INDICATOR_DATA); // Plot3
// 計算用バッファ
SetIndexBuffer(6, Atr, INDICATOR_CALCULATIONS);
SetIndexBuffer(7, Up, INDICATOR_CALCULATIONS);
SetIndexBuffer(8, Down, INDICATOR_CALCULATIONS);
SetIndexBuffer(9, Middle, INDICATOR_CALCULATIONS);
SetIndexBuffer(10, trend, INDICATOR_CALCULATIONS);
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;
OffsetLine[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;
}
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];
// OffsetLine も一つ前をつなげてギャップを抑える
OffsetLine[i - 1] = OffsetLine[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];
OffsetLine[i - 1] = OffsetLine[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;
// OffsetLineoffsetpips<=0なら非表示)
if (offsetpips > 0.0)
{
// 買い/売りごとに、offset_reverse で方向を切り替え
double dir;
if (trend[i] == 1) // 買いトレンド
{
// 通常: 下側 / 逆方向: 上側
dir = offset_reverse ? 1.0 : -1.0;
}
else // 売りトレンド
{
// 通常: 上側 / 逆方向: 下側
dir = offset_reverse ? -1.0 : 1.0;
}
OffsetLine[i] = SuperTrend[i] + dir * offsetpips * pip;
}
else
{
OffsetLine[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);
}
//+------------------------------------------------------------------+