在 MQL5 中创建多色彩指标(基础篇)
◍ 给 MT5 指标上多套颜色
MQL5 里画指标线不只能单调单色,用多色彩缓冲(color buffer)可以按条件给每一根柱子上不同颜色,视觉上直接区分状态。这套机制在 2013 年 10 月就有人实做过,原帖浏览量 4462、跟帖 13 条,说明老交易员早就在折腾这类可读性优化。 核心做法是声明多个颜色索引,并在 OnCalculate 里按数值区间给缓冲写颜色常量。下面这段是最小可跑骨架,去掉了具体判断逻辑,只保留多色缓冲注册方式。 [CODE] #property indicator_buffers 2 #property indicator_color1 clrGreen #property indicator_color2 clrRed double ExtBuffer1[]; double ExtBuffer2[]; int OnInit() { SetIndexBuffer(0, ExtBuffer1); SetIndexBuffer(1, ExtBuffer2); return(INIT_SUCCEEDED); } [/CODE] 逐行拆:前两句预编译指令告诉终端这条指标有 2 个缓冲、分别默认绿和红;两个 double 数组就是实际存值的容器;OnInit 里 SetIndexBuffer 把数组绑到 0 号和 1 号缓冲上。你开 MT5 新建指标把这段贴进模板,编译后拖到图表就能看到两条空线,之后往数组里填判断结果即可。 外汇和贵金属行情跳变快,多色线只是降低盯盘误读概率,不预示方向,实盘仍属高风险。
class="macro">#class="kw">property indicator_buffers class="num">2 class="macro">#class="kw">property indicator_color1 clrGreen class="macro">#class="kw">property indicator_color2 clrRed class="type">class="kw">double ExtBuffer1[]; class="type">class="kw">double ExtBuffer2[]; class="type">int OnInit() { SetIndexBuffer(class="num">0, ExtBuffer1); SetIndexBuffer(class="num">1, ExtBuffer2); class="kw">return(INIT_SUCCEEDED); }
「MQL5 给指标线逐段上色的底层能力」
MQL4 时代也能给指标行指定颜色,但整行只能是一种色,想做多色彩得靠多个指标缓冲区相互重叠来硬凑,维护起来很别扭。MT5 的 MQL5 直接把这件事做进了语言层:指标线可以按区段分别指定颜色,独立的柱、烛形、直方图、箭头也能逐个上色。 本文只挑两种绘制风格展开——DRAW_COLOR_LINE 和 DRAW_COLOR_CANDLES。其余彩色风格的差异基本只在于缓冲区数量,机制是同一套,搞懂这两个就能自行类推。 想跟着验证,建议先把 MQL5 参考里指标相关的数据结构过一遍,不然缓冲区和彩色索引缓冲区的对应关系容易看晕。外汇和贵金属市场杠杆高、滑点频发,任何指标着色方案都只是辅助观察,不构成方向判断依据。
彩色指标到底解决了什么
在 MT5 里把指标输出染色,不是图好看那么简单。最直接的价值是能在同一根烛形上叠出第二层信息:比如让 MACD 柱线的颜色受 RSI 数值驱动,超买区自动转红、超卖区转绿,一眼就能看出动能和摆荡位置是否共振。 比起灰阶线形,彩色编码能把'该看哪'直接标出来。重要信号(如穿越零轴且动量转强)用高饱和色突出,普通区用低明度灰,视觉权重立刻拉开,扫盘时漏读概率会降一截。 当然也有人只是拿配色统一客户端风格,这不算错,但外汇和贵金属杠杆高、跳空频繁,靠颜色偷懒代替规则验证反而容易吃亏。建议先把一套逻辑写进颜色条件,再谈美观。
◍ 自定义彩色指标的双缓冲骨架
MT5 指标的本质是拿输入数据算完往缓冲区填,客户端按绘制类型把缓冲区画出来。缓冲区是全局声明的双精度数组,一个绘图风格可能绑多个缓冲区,但图形(线、柱、箭头)和缓冲区不是一回事:图形是窗口里看到的,缓冲区只是装数据的数组,有些只供内部计算根本不画。 以最简彩色指标为例,#property indicator_buffers 2 定了两根缓冲区:一根装开盘价类数据,一根装颜色索引。indicator_plots 1 是说只画一个图形,绘图数可以小于等于缓冲数,差的那根往往拿去算中间量。带 COLOR 字样的风格都强制要颜色索引缓冲区,比如 DRAW_COLOR_HISTOGRAM 就吃一根数据缓冲加一根颜色缓冲。 静态配色用 #property indicator_color1 Red,Green,BlueViolet,编译期定死 3 色且索引从 0 起。动态配色靠 PlotIndexSetInteger:先传 PLOT_COLOR_INDEXES 告之图形 0 有 2 个颜色索引,再逐条绑 0 号蓝、1 号橙。动态法会在运行时覆盖静态法,两种都写时以后者为准。 OnInit 里 SetIndexBuffer(0, buffer_line, INDICATOR_DATA) 把 0 号绑数据,SetIndexBuffer(1, buffer_color_line, INDICATOR_COLOR_INDEX) 把 1 号绑颜色,顺序必须先数据后颜色。OnCalculate 中若开盘高于收盘给颜色数组写 0(蓝),低于则写 1(橙),逻辑极简,开 MT5 新建指标粘下面代码就能看到独立窗口里的双色直方。外汇与贵金属杠杆高,验证时请用模拟盘。
class="macro">#class="kw">property copyright "ProF" class="macro">#class="kw">property indicator_separate_window class="macro">#class="kw">property indicator_buffers class="num">2 class="macro">#class="kw">property indicator_plots class="num">1 class="macro">#class="kw">property indicator_type1 DRAW_COLOR_HISTOGRAM class="macro">#class="kw">property indicator_width1 class="num">3 class="macro">#class="kw">property indicator_color1 Red,Green,BlueViolet class="type">class="kw">double buffer_line[], buffer_color_line[]; class="type">int OnInit() { SetIndexBuffer(class="num">0,buffer_line,INDICATOR_DATA); SetIndexBuffer(class="num">1,buffer_color_line,INDICATOR_COLOR_INDEX); PlotIndexSetInteger(class="num">0,PLOT_COLOR_INDEXES,class="num">2); PlotIndexSetInteger(class="num">0,PLOT_LINE_COLOR,class="num">0,Blue); }
「用颜色索引区分阴阳线的柱状图」
在 MT5 自定义指标里,想让一根彩色柱状图随 K 线涨跌换色,核心不是改画笔,而是先喂两个缓存:一个放数值,一个放颜色索引。上面这段把 indicator_color1 设成 Red,Green,BlueViolet,但实际只通过 PlotIndexSetInteger 启用了 0 号和 1 号两种索引,分别对应蓝和橙,多余的颜色声明不会参与绘制。 OnCalculate 里从 prev_calculated 开始循环,避免每 tick 重算全部历史。判断 open[i]>close[i] 时给 buffer_color_line[i] 写 0(跌,蓝),否则写 1(涨,橙);同时把 buffer_line[i] 填成开盘价。这样柱子高低表达的是开盘价位置,颜色表达的是该根阴阳状态。 返回值用 rates_total-1,意味着最后一柱留待下一 tick 重算,这是 MT5 指标防止当前未闭合 K 线被锁死的常规做法。外汇与贵金属波动剧烈,这类视觉辅助只帮你看清结构,不代表任何方向概率优势,实盘须自担高风险。 直接把这段逻辑粘进 MQ5 文件,编译后加载到 XAUUSD 的 M5 图,能立刻看到蓝橙交替的开口柱状——若你习惯用收盘价而非开盘价做基线,把 buffer_line[i]=open[i] 换成 close[i] 即可,颜色条件不用动。
PlotIndexSetInteger(class="num">0,PLOT_LINE_COLOR,class="num">1,Orange); class=class="str">"cmt">//1号索引 -> 橙色 class="kw">return(class="num">0); } class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| 自定义指标迭代函数 | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">int OnCalculate(class="kw">const class="type">int rates_total, class="kw">const class="type">int prev_calculated, class="kw">const class="type">class="kw">datetime &time[], class="kw">const class="type">class="kw">double &open[], class="kw">const class="type">class="kw">double &high[], class="kw">const class="type">class="kw">double &low[], class="kw">const class="type">class="kw">double &close[], class="kw">const class="type">long &tick_volume[], class="kw">const class="type">long &volume[], class="kw">const class="type">int &spread[]) { class=class="str">"cmt">//我们为每个柱形循环填充数据缓存,以及颜色索引缓存 for(class="type">int i=prev_calculated;i<=rates_total-class="num">1;i++) { class=class="str">"cmt">//让我们添加一个简单的绘图条件 -> 如果开盘价格大于收盘价,那么: if(open[i]>close[i]) { buffer_color_line[i]=class="num">0; } class=class="str">"cmt">//分配颜色索引为0 else { buffer_color_line[i]=class="num">1; } class=class="str">"cmt">//分配颜色索引为1 class=class="str">"cmt">//确定绘图数据,在这里是开盘价 buffer_line[i]=open[i]; } class="kw">return(rates_total-class="num">1); class=class="str">"cmt">//返回已经计算的柱形的数量, class=class="str">"cmt">//由于最后一个柱形要重算,减1 } class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property indicator_buffers class="num">2 class=class="str">"cmt">///指标缓存数量 class="macro">#class="kw">property indicator_plots class="num">1 class=class="str">"cmt">//绘图图形个数 class="macro">#class="kw">property indicator_type1 DRAW_COLOR_HISTOGRAM class=class="str">"cmt">//绘图样式 - 彩色柱状图 class="macro">#class="kw">property indicator_width1 class="num">3 class=class="str">"cmt">//绘制线宽(可选) class="macro">#class="kw">property indicator_color1 Red,Green,BlueViolet class=class="str">"cmt">//确定3种颜色用来绘图 class="type">class="kw">double buffer_line[]class=class="str">"cmt">/*数据缓存*/, buffer_color_line[]class=class="str">"cmt">/*颜色索引缓存*/; SetIndexBuffer(class="num">0,buffer_line,INDICATOR_DATA); SetIndexBuffer(class="num">1,buffer_color_line,INDICATOR_COLOR_INDEX); class=class="str">"cmt">//确定用来绘图的颜色索引数量 PlotIndexSetInteger(class="num">0,PLOT_COLOR_INDEXES,class="num">2); PlotIndexSetInteger(class="num">0,PLOT_LINE_COLOR,class="num">0,Blue); class=class="str">"cmt">//0号索引 -> 蓝色 PlotIndexSetInteger(class="num">0,PLOT_LINE_COLOR,class="num">1,Orange); class=class="str">"cmt">//1号索引 -> 橙色
MT5 里给颜色赋值的三种写法
在 MQL5 里定义一个 color 类型变量,底层都绕不开 RGB 三通道。每个通道用 0–255 的十进制或 00–FF 的十六进制表达,数值越小颜色越暗,白色是 C'255,255,255' 或 C'0xFF,0xFF,0xFF',黑色则是 C'0,0,0'。 常值写法最直观,比如 C'10,20,255' 和 C'0x0A,0x14,0xFF' 是同一支蓝,只是数制不同,随你习惯选。数值写法要注意字节序:十六进制 0x0000FF 实际等于 C'0xFF,0x00,0x00',也就是纯红,首尾两对字节是反着的。 直接用 Web 颜色名(如 Red、Blue、Orange)最省事,但只能取 web-colors 标准集里的色,想做精细渐变还是得回到 RGB。下面这段代码把三种写法摆在一起,并验证了它们彼此等价——Alert 会打印 true。 外汇与贵金属图表美化虽不影响报价,但过度依赖视觉信号可能干扰客观判断,这类改动请先在模拟盘验证。
class="type">class="kw">color color_var = C&class="macro">#x27;class="num">10,class="num">20,class="num">255&class="macro">#x27;; class="type">class="kw">color color_var = C&class="macro">#x27;0x0A,0x14,0xFF&class="macro">#x27;; class="type">class="kw">color color_var = 0xFFFFFF; class=class="str">"cmt">// 白色 class="type">class="kw">color color_var = 0x0000FF; class=class="str">"cmt">// 红色 class="type">class="kw">color color_var = class="num">16777215 class=class="str">"cmt">// 白色 class="type">class="kw">color color_var = 0x008000 class=class="str">"cmt">// 绿色 class="type">class="kw">color color_var = class="num">32768 class=class="str">"cmt">// 绿色 class="type">class="kw">color color_var = Red; class=class="str">"cmt">//红色 class="type">class="kw">color color_var = Blue; class=class="str">"cmt">//蓝色 class="type">class="kw">color color_var = Orange; class=class="str">"cmt">//橙色 class="type">class="kw">color color1 = C&class="macro">#x27;class="num">255,class="num">0,class="num">0&class="macro">#x27;; class="type">class="kw">color color2 = C&class="macro">#x27;0xFF,0x00,0x00&class="macro">#x27;; class="type">class="kw">color color3 = 0x0000FF; class="type">class="kw">color color4 = class="num">255; class="type">class="kw">color color5 = Red; Alert((color1==color2) && (color1==color2) && (color1==color4) && (color1==color5)); class=class="str">"cmt">//打印true