📘

「山型与冰山型图表的视觉逻辑」

「山型与冰山型图表的视觉逻辑」

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 索引,颜色映射在双色矩阵里定死。若在计算函数里塞颜色常量,绘制模型直接错乱。

MQL5 / C++
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 可能更直观看到多空分界。外汇与贵金属杠杆高,参数误用会放大视觉误判,实盘前务必在策略测试器跑一遍。

MQL5 / C++
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 绑定正确。

MQL5 / C++
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 不行」的论调,直接把这类小实现甩过去。平台定位本就是功能性、安全、快,外加极高定制自由度,剩下的只差你愿不愿意动手试。

常见问题

山型突出收盘均价连线、忽略影线,适合看趋势惯性;冰山型把成交量或波动沉在下方,适合判资金厚度。日内跟风用山型,找支撑用冰山型。
用双缓冲区自定义指标,在主图缓冲画均价线并调用ChartSetInteger隐藏蜡烛。代码里置OBJPROP_HIDDEN即可切换显隐。
可以。小布盯盘的AIGC已内置图表形态切换,打开对应品种页点「视图」就能一键换山型,不用自己写指标。
多在OnInit没给缓冲设DRAW_LINE类型和颜色。补上PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrDodgerBlue)即可正常渲染。
只是降噪、不预示方向,贵金属高杠杆仍易爆仓。山形帮你少看杂讯,决策还得结合量价,风险自担。