MQL5 自訂指標進階:緩衝區顏色切換與子視窗繪製
📌 本文重點
深入 MQL5 自訂指標開發:多緩衝區管理、動態顏色切換(紅/藍)、子視窗振盪器繪製、彩色直方圖,以及從 EA 呼叫自訂指標。
深入 MQL5 自訂指標開發:多緩衝區管理、動態顏色切換(紅/藍)、子視窗振盪器繪製、彩色直方圖,以及從 EA 呼叫自訂指標。
彩色線指標:價格在均線上方顯示藍色,下方顯示紅色
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_plots 2
// 繪圖 0:彩色均線
#property indicator_label1 "彩色均線"
#property indicator_type1 DRAW_COLOR_LINE
#property indicator_color1 clrDodgerBlue, clrRed, clrGray
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
// 繪圖 1:訊號箭頭
#property indicator_label2 "訊號"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrGold
#property indicator_width2 2
double g_maBuffer[];
double g_colorBuffer[]; // 顏色索引 0=藍 1=紅 2=灰
double g_signalBuffer[];
input int InpPeriod = 20;
input ENUM_MA_METHOD InpMethod = MODE_EMA;
int g_maHandle = INVALID_HANDLE;
int OnInit()
{
SetIndexBuffer(0, g_maBuffer, INDICATOR_DATA);
SetIndexBuffer(1, g_colorBuffer, INDICATOR_COLOR_INDEX);
SetIndexBuffer(2, g_signalBuffer, INDICATOR_DATA);
PlotIndexSetInteger(1, PLOT_ARROW, 233);
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, EMPTY_VALUE);
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, EMPTY_VALUE);
g_maHandle = iMA(_Symbol, _Period, InpPeriod, 0, InpMethod, PRICE_CLOSE);
IndicatorSetString(INDICATOR_SHORTNAME, "彩色MA("+IntegerToString(InpPeriod)+")");
return (g_maHandle != INVALID_HANDLE) ? INIT_SUCCEEDED : INIT_FAILED;
}
void OnDeinit(const int r) { IndicatorRelease(g_maHandle); }
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[])
{
int start = (prev_calculated == 0) ? InpPeriod : prev_calculated - 1;
if (rates_total < InpPeriod) return 0;
double maValues[];
ArraySetAsSeries(maValues, false);
if (CopyBuffer(g_maHandle, 0, 0, rates_total, maValues) <= 0) return prev_calculated;
for (int i = start; i < rates_total; i++)
{
g_maBuffer[i] = maValues[i];
g_signalBuffer[i] = EMPTY_VALUE;
// 根據價格與 MA 位置決定顏色
if (close[i] > maValues[i]) g_colorBuffer[i] = 0; // 藍
else if (close[i] < maValues[i]) g_colorBuffer[i] = 1; // 紅
else g_colorBuffer[i] = 2; // 灰
// 偵測穿越,繪製箭頭
if (i > 0 && maValues[i-1] != EMPTY_VALUE)
{
if (close[i-1] <= maValues[i-1] && close[i] > maValues[i])
g_signalBuffer[i] = low[i] - 5*_Point;
if (close[i-1] >= maValues[i-1] && close[i] < maValues[i])
g_signalBuffer[i] = high[i] + 5*_Point;
}
}
return rates_total;
}
子視窗彩色 MACD 直方圖
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots 2
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrMediumSeaGreen, clrCrimson
#property indicator_width1 2
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrSilver
#property indicator_style2 STYLE_DOT
double g_hist[], g_histColor[], g_zero[];
input int InpFast=12, InpSlow=26, InpSignal=9;
int g_macdHandle = INVALID_HANDLE;
int OnInit()
{
SetIndexBuffer(0, g_hist, INDICATOR_DATA);
SetIndexBuffer(1, g_histColor, INDICATOR_COLOR_INDEX);
SetIndexBuffer(2, g_zero, INDICATOR_DATA);
g_macdHandle = iMACD(_Symbol, _Period, InpFast, InpSlow, InpSignal, PRICE_CLOSE);
return (g_macdHandle != INVALID_HANDLE) ? INIT_SUCCEEDED : INIT_FAILED;
}
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[])
{
int start = (prev_calculated == 0) ? InpSlow+InpSignal : prev_calculated-1;
double macd[], sig[];
ArraySetAsSeries(macd,false); ArraySetAsSeries(sig,false);
if (CopyBuffer(g_macdHandle,0,0,rates_total,macd)<=0) return prev_calculated;
if (CopyBuffer(g_macdHandle,1,0,rates_total,sig)<=0) return prev_calculated;
for (int i=start; i<rates_total; i++)
{
double h = macd[i] - sig[i];
g_hist[i] = h;
g_histColor[i] = (h >= 0) ? 0 : 1;
g_zero[i] = 0.0;
}
return rates_total;
}
從 EA 呼叫自訂指標
// 假設指標檔名為 MyColorMA.ex5
int handle = iCustom(_Symbol, _Period, "MyColorMA", 20, MODE_EMA);
// 取得值(buffer 0)
double val[1]; ArraySetAsSeries(val,true);
if (CopyBuffer(handle, 0, 1, 1, val) >= 1)
Print("MA Value = ", val[0]);
// 取得顏色索引(buffer 1)
double col[1]; ArraySetAsSeries(col,true);
if (CopyBuffer(handle, 1, 1, 1, col) >= 1)
Print("Color Index = ", col[0]); // 0=藍, 1=紅, 2=灰
本文由 James Lee 撰寫。內容僅供教育目的,不構成投資建議。