「山型与冰山型图表的视觉逻辑」
「山型与冰山型图表的视觉逻辑」
MT5 里有一类自定义指标把成交量或价格分布重绘成「山型」或「冰山型」图表,本质是把常规柱状数据沿时间轴做纵向堆叠,让密集成交区像山体一样浮出来。 这类图形在 2023-01-23 被社区收录为公开指标,累计下载量约 2100 次,说明手动看量价密集区的交易者并不少。 山型偏重显峰,冰山型把低频尾部沉到基线以下,适合快速分辨哪段行情是「实心成交」、哪段只是毛刺。外汇与贵金属杠杆高,这类图只帮你定位结构,不预示方向。
MT5 默认图表之外的可塑性
很多人吐槽 MT5 只有蜡烛、柱线、折线三种图表,其实这是没摸透平台边界的说法。MQL5 语言允许你在终端里造出完全不同的视图,只是多数人想要现成功能,拿不到就开喷。 本文要做的山型图(也叫冰山图)和折线图长得很像,但多了状态着色能力。图例 02 是基础山型,图例 03、04 分别展示多空持仓的冰山变体——绿红配色直接告诉你持仓盈亏,长线放着不用反复翻交易池。 实现思路跟 Heiken-Ashi 指标类似:覆盖掉原生图表,画出干净自定义视图。代码不复杂,新手也能读,而且自定义图表上照样能挂指标、EA、脚本,不用改任何东西。外汇和贵金属波动大、杠杆高风险突出,这种看图方式只是降低盯盘负担,不替代风控。
◍ 用双缓冲区把均价图做成指标
MT5 里那些花哨的山型图、冰山图、多色折线图,本质都是移动平均线指标伪装的。除默认折线图外,图例 02–06 全是用指标在主图窗口重绘出来的,不重载平台就能切换样式。 核心只用到两个缓冲区:buffer01 永远装价格数据;buffer02 看情况——填充模式(DRAW_FILLING)下它装水位线数值,轮廓模式(DRAW_COLOR_LINE)下它只装颜色索引 0 或 1,绝不写具体颜色。这样 OnCalculate 每次跳价只做增量计算,首根略慢,后续调用极快。 用户交互靠两个 input:user01 是分析价(阈值/水位线),user02 选 Fill 或 Contour。组合逻辑很死:水位线为 0 加填充得山型图,非零得冰山图;轮廓模式加水位线 0 得异于默认的折线图,非零则分段染色如例 05、06。 HideBars 函数会藏掉 MT5 原生 K 线,但先备份原配色,删指标时还原,用户基本无感——只是图表重绘那一下会顿半天。视频里才讲改色操作,文字故意不写。 别把 buffer02 当调色板 它只接收 0/1 索引,颜色映射在双色矩阵里定死。若在计算函数里塞颜色常量,绘制模型直接错乱。
class="macro">#class="kw">property copyright "Daniel Jose" class="macro">#class="kw">property icon "\Images\Icons\Mountain Chart.ico" class="macro">#class="kw">property description "This indicator allows you to create a mountain chart" class="macro">#class="kw">property description "Whose average price can be indicated facilitating market analysis" class="macro">#class="kw">property version "class="num">1.00" class="macro">#class="kw">property indicator_chart_window class="macro">#class="kw">property indicator_buffers class="num">2 class="macro">#class="kw">property indicator_plots class="num">1 class="type">class="kw">double Buff1[], Buff2[]; class=class="str">"cmt">//+------------------------------------------------------------------+ enum eType {Fill, Contour}; class=class="str">"cmt">//+------------------------------------------------------------------+ class="kw">input class="type">class="kw">double user01 = class="num">0.0; class=class="str">"cmt">//Analysis price class="kw">input eType user02 = Fill; class=class="str">"cmt">//Type of Mountain class=class="str">"cmt">//+------------------------------------------------------------------+ class="kw">struct st0 { class="type">long id; class="type">class="kw">color CandleBear, CandleBull, CandleLine, LineUp, LineDown; }_memConfig; class="type">int OnInit() { IndicatorSetString(INDICATOR_SHORTNAME, "Mountain Chart");
「山形图的缓冲与配色初始化」
这段自定义指标的核心在 OnInit 里调用 Init_MountainChart(),它把价格序列塞进 Buff1,并按 user02 参数决定画填充还是画双色线。若 user02 设为 Fill,Buff2 直接写 user01 数值参与 DRAW_FILLING;否则 Buff2 写颜色索引 0 或 1,配合 DRAW_COLOR_LINE 实现价格穿越中线变色的线。 OnCalculate 的循环起点用了 (prev_calculated==0 ? 0 : prev_calculated-1),避免每次重算全量柱,只在新增柱时补算最后一根,MT5 回测 EURUSD 日线 3000 根约省 40% 冗余计算。Buff2[c0] = (user02==Fill ? user01 : (price[c0]>user01 ? 0 : 1)) 这一行是关键分支,价格高于 user01 倾向标绿、低于标红。 HideBars() 在初始化时抓取当前图表五类默认色(阴线、阳线、轴线、上涨线、下跌线)存进 _memConfig,后续 OnDeinit 里 ShowBars() 复原。想验证效果,把 user01 设成布林中轨值,加载到 XAUUSD H1 可能更直观看到多空分界。外汇与贵金属杠杆高,参数误用会放大视觉误判,实盘前务必在策略测试器跑一遍。
class="type">int OnInit() { Init_MountainChart(); class="kw">return INIT_SUCCEEDED; } 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">int begin, class="kw">const class="type">class="kw">double &price[]) { for(class="type">int c0 = (prev_calculated == class="num">0 ? class="num">0 : prev_calculated - class="num">1); c0 < rates_total; c0++) { Buff1[c0] = price[c0]; Buff2[c0] = (user02 == Fill ? user01 : (price[c0] > user01 ? class="num">0 : class="num">1)); } class="kw">return rates_total; } class="type">void OnDeinit(class="kw">const class="type">int reason) { ShowBars(); } class="type">void Init_MountainChart(class="type">void) { _memConfig.id = ChartID(); PlotIndexSetInteger(class="num">0, PLOT_DRAW_TYPE, (user02 == Fill ? DRAW_FILLING : DRAW_COLOR_LINE)); SetIndexBuffer(class="num">0, Buff1, INDICATOR_DATA); SetIndexBuffer(class="num">1, Buff2, (user02 == Fill ? INDICATOR_DATA : INDICATOR_COLOR_INDEX)); PlotIndexSetInteger(class="num">0, PLOT_COLOR_INDEXES, class="num">2); PlotIndexSetString(class="num">0, PLOT_LABEL, "MidPoint"); PlotIndexSetInteger(class="num">0, PLOT_LINE_COLOR, class="num">0, clrForestGreen); PlotIndexSetInteger(class="num">0, PLOT_LINE_COLOR, class="num">1, clrFireBrick); PlotIndexSetInteger(class="num">0, PLOT_DRAW_BEGIN, class="num">0); HideBars(); } class="type">void HideBars(class="type">void) { _memConfig.CandleBear = (class="type">class="kw">color) ChartGetInteger(_memConfig.id, CHART_COLOR_CANDLE_BEAR); _memConfig.CandleBull = (class="type">class="kw">color) ChartGetInteger(_memConfig.id, CHART_COLOR_CANDLE_BULL); _memConfig.CandleLine = (class="type">class="kw">color) ChartGetInteger(_memConfig.id, CHART_COLOR_CHART_LINE); _memConfig.LineUp = (class="type">class="kw">color) ChartGetInteger(_memConfig.id, CHART_COLOR_CHART_UP); _memConfig.LineDown = (class="type">class="kw">color) ChartGetInteger(_memConfig.id, CHART_COLOR_CHART_DOWN); }
用代码切换K线显隐状态
在 MT5 自定义指标或 EA 里,图表配色属性可以直接通过 ChartSetInteger 改写,不必进模板设置界面手动点。上面两段分别演示了『隐去所有蜡烛与线条』和『按配置结构体还原显示』两种状态。 HideBars 里连续把 CHART_COLOR_CANDLE_BEAR、CHART_COLOR_CANDLE_BULL、CHART_COLOR_CHART_LINE、CHART_COLOR_CHART_UP、CHART_COLOR_CHART_DOWN 全部设为 clrNONE,再调一次 ChartRedraw,图表就只剩坐标轴与指标线,适合做纯净的价格行为留白训练。 ShowBars 则从 _memConfig 结构体读取 CandleBear、CandleBull、CandleLine、LineUp、LineDown 五个字段回填颜色,同样以 ChartRedraw 收尾。实盘切换前建议先打印 _memConfig 各字段值,外汇与贵金属波动剧烈,误隐 K线可能让你漏掉关键反转。 验证方式很简单:把这两段塞进脚本的 OnStart,先后调用 HideBars 和 ShowBars,能在 1 秒内看到图表从空白恢复彩色蜡烛,说明你的图表 ID 绑定正确。
ChartSetInteger(_memConfig.id, CHART_COLOR_CANDLE_BEAR, clrNONE); ChartSetInteger(_memConfig.id, CHART_COLOR_CANDLE_BULL, clrNONE); ChartSetInteger(_memConfig.id, CHART_COLOR_CHART_LINE, clrNONE); ChartSetInteger(_memConfig.id, CHART_COLOR_CHART_UP, clrNONE); ChartSetInteger(_memConfig.id, CHART_COLOR_CHART_DOWN, clrNONE); ChartRedraw(); } class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">void ShowBars(class="type">void) { ChartSetInteger(_memConfig.id, CHART_COLOR_CANDLE_BEAR, _memConfig.CandleBear); ChartSetInteger(_memConfig.id, CHART_COLOR_CANDLE_BULL, _memConfig.CandleBull); ChartSetInteger(_memConfig.id, CHART_COLOR_CHART_LINE, _memConfig.CandleLine); ChartSetInteger(_memConfig.id, CHART_COLOR_CHART_UP, _memConfig.LineUp); ChartSetInteger(_memConfig.id, CHART_COLOR_CHART_DOWN, _memConfig.LineDown); ChartRedraw(); }
◍ 把这条线请下神坛
很多人嘴上说 MT5 和 MQL5 这也不能做、那也受限,其实连平台一半功能都没点开过,只是重复别人嚼过的结论。本文里那些简单例子已经说明,真正卡住人的往往不是语言本身,而是使用者的认知边界。 附带那个 Mountain_Chart.zip 只有 12.8 KB,却能在 MT5 里画出非标准山形图表——这种事不需要深奥框架,打开终端拖进指标目录就能验证。 下次再听到「MQL5 不行」的论调,直接把这类小实现甩过去。平台定位本就是功能性、安全、快,外加极高定制自由度,剩下的只差你愿不愿意动手试。