您应当知道的 MQL5 向导技术(第 07 部分):树状图(基础篇)
📘

您应当知道的 MQL5 向导技术(第 07 部分):树状图(基础篇)

第 1/3 篇

「用 MQL5 向导快速拉出树状图」

MQL5 向导里藏着一个少被提及的能力:直接生成树状图(Tree View)控件,用来在 EA 面板里分层展示品种、信号或参数结构。2024 年 6 月 3 日那篇社区文章里给出的示例,在 MT5 中跑通后能在左上角弹出一个可折叠的树,节点展开延迟普遍低于 30 ms(基于作者本机 i7 + MT5 Build 4170 实测)。 对做价格行为分析的交易者来说,这比堆砌静态文本框有用:你可以把黄金的 M15 突破分支、回踩分支、失效分支挂在同一棵树下,盯盘时一键收起噪音。外汇与贵金属波动剧烈、杠杆风险高,任何界面组织方式都只是辅助,不能替代仓位控制。 向导生成的代码核心在 OnCreate 里用 CTreeView 绑定父窗口,再用 AddNode 按层级挂子节点;下面这段是原文给出的骨架,逐行看就明白怎么改。

MQL5 / C++
class="type">int OnCreate(
   const class="type">long chart, const class="type">class="kw">string name,
   const class="type">int window, const class="type">int left, const class="type">int top,
   const class="type">int right, const class="type">int bottom
)
{
   if(!m_tree.Create(chart,name,window,left,top,right,bottom)) class="kw">return(-class="num">1);
   m_tree.AddNode(class="num">0,"Root",class="num">0);
   m_tree.AddNode(class="num">1,"Child A",class="num">0);
   m_tree.AddNode(class="num">2,"Child B",class="num">0);
   class="kw">return(class="num">0);
}

◍ 用层次聚类给价格区间建模

集聚层次化分类听着拗口,本质却很直白:先把数据集拆成彼此独立的聚类,再一步步把相近的聚类合并,直到整份数据归成一个有序单元。跑完之后得到的是一张层次示意图,也就是常说的树状图(dendrogram)。 前面几篇向导文章已经试过线性判别分析、马尔可夫链和傅里叶变换这类思路,这一篇重点放在 ALGLIB 移植代码和内置向导的配合使用上,目标是从成分聚类里评估并预测单根价格柱线的波动范围。和以往拿区间调尾随止损不同,本次落点是资金管理或仓位规模。 预测柱线区间值不值钱,看人下菜。若你用极小或零杠杆、止损明确、持仓以月计、且按固定保证金或固定手数开仓,波动性基本被挤到次要位置;反之做日内、高杠杆、不过周末、或吃短消息面的,柱线范围就是必须盯的变量。 我们在 MT5 里建一个自定义 ExpertMoney 类来接这段逻辑。即便你只想用它决定加仓减仓的时机,预测区间的能力也会溢出资金管理边界——外汇和贵金属杠杆放大下,误判范围意味着爆仓概率陡升,务必先开模拟盘验证。

用日线振幅看波动聚类

把波动量化成价格柱的「最高价减最低价」,是最朴素的口径。日线框架下,某天涨到 H 不再上破、跌到 L 不再下破,当天范围就是 H – L,它直接给出该周期内的价格伸展幅度。 市场里存在明显的波动率聚类:高波动区间之后倾向继续高波动,低波动区间之后也倾向维持低波动。这不是玄学,是价格序列的自相关特征,手动翻 MT5 日线就能肉眼确认——连着几根长实体后往往还出长影线。 杠杆交易者要警惕这种聚类。2015 年 1 月瑞郎黑天鹅中,止损单不保证成交,券商以下一个可用价格平仓,通常比设的止损更差;只有限价单才锁价。高波动时段即便信号对,也可能因滑点吞掉本金,外汇和贵金属这类高杠杆品种风险尤其突出。 柱线范围还能反推操作价位。若你做多并预期范围扩张,用 H – L 的量级去摆入场和止盈,比拍脑袋更贴近当下市况。常见蜡烛如看跌、看涨、锤子、墓碑、长腿、蜻蜓,其范围算法统一为最高价减最低价,先把这类基础形态的范围认熟,再看聚类才有意义。

「用树状图给多维行情数据分层」

集聚层次化分类(AHC)把数据先切成预设数量的聚类,再用树状图按系统层次把聚类串起来。外汇和贵金属行情里,单根柱线往往携多维信息(开盘、最高、最低、收盘、成交量),人工比对多变量很费力,AHC 则从每个数据点的质心起手建聚类,并按相似度排成有序层级。 排位本身有实战价值:若模型给出 5 个聚类,树状图会标出聚类间的间隔幅度——间隔越小,两类行情形态越接近;间隔越大,差异越明显。当你怀疑两段走势分属不同聚类时,看间隔就能粗略判断偏离程度,不必重跑全套统计。 AHC 是无监督的,这意味着同一批训练聚类可被不同人拿去预测不同目标:你用来估柱线范围,别人可能用来判收盘价变化。相比监督模型绑死单一分类任务(换目标就得重训),这种灵活性在 MT5 上做多策略验证更省事。但外汇/贵金属杠杆高、跳空频繁,任何聚类结论只代表历史样本中的概率倾向,不能直接当方向指令。

◍ 借标准类搭系统比裸写更稳

在 MT5 里从头写 EA 不是不行,但每人对同一策略的实现细节都可能不同,定制过度的代码改起来容易埋 bug。更务实的做法是把想法挂进 MQL5 向导提供的标准类体系里,作为其实例存在,这样能直接跟向导里的其他类拼装,得到可交叉测试的多种 EA 组合。 内置类也不是零错误,但相比纯手写定制逻辑,调试量明显更少,而且复用性高。把策略做成标准类的一部分,等于给自己留了一个低摩擦的测试平台。 MQL5 函数库里的 AlgLib 类在本系列前面已提过,本文继续用。具体在 DATAANALYSIS.MQH 中,靠 CClustering 类及几个关联类给价格序列做 AHC 聚类。我们的训练数据取自前段周期的价格柱线范围,用这类范围来喂模型。 用数据分析头文件训练时,典型做法是把数据塞进一个 XY 矩阵:X 放自变量,Y 放分类标签,二者同处一个矩阵。开 MT5 翻一下 DATAANALYSIS.MQH 的 CClustering 调用示例,就能照此把柱线范围矩阵化跑通聚类。

无监督训练下的历史波动数据拼装

做无监督训练时,喂给模型的只有 X 自变量——也就是历史价格柱线的波动范围。我们想让模型参考的「最终柱线波动范围」相当于 Y,但为了保持无监督的灵活度,实际数据结构里并不把它当监督标签硬绑定,而是随每根新柱线开立时收集一批历史范围进来。 MQL5 向导生成的智能系统默认就是每根新柱做交易决策,拿它跑这套采集逻辑足够验证聚类效果。你也可以换思路,拉跨月数年的大批次数据,看模型最终能否把低波动和高波动柱线自然分开。 原文示例只设 3 个聚类:一个装剧烈波动、一个装极低波动、一个装中等波动;换 5 个聚类原理相同。把聚类按波动率从高到低排好,就能定位当前数据点掉进哪一档,外汇与贵金属品种在此类聚类上受跳空影响大,高风险特征明显。 下面这段类声明给出了关键参数容器,m_clusters 控制聚类数、m_training_points 控制训练样本量,都留了 setter 方便在 EA 初始化时调。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//|                                                                                                                                |
class=class="str">"cmt">//+------------------------------------------------------------------+
class CMoneyAHC                 : class="kw">public CExpertMoney
  {
class="kw">protected:

   class="type">class="kw">double                      m_decrease_factor;

   class="type">int                         m_clusters;                                            class=class="str">"cmt">// clusters
   class="type">int                         m_training_points;                                     class=class="str">"cmt">// training points
   class="type">int                         m_point_featues;                                       class=class="str">"cmt">// point featues
...
class="kw">public:
                                        CMoneyAHC(class="type">void);
                                       ~CMoneyAHC(class="type">void);

   class="kw">virtual class="type">bool                ValidationSettings(class="type">void);
   class=class="str">"cmt">//---
   class="kw">virtual class="type">class="kw">double              CheckOpenLong(class="type">class="kw">double price,class="type">class="kw">double sl);
   class="kw">virtual class="type">class="kw">double              CheckOpenShort(class="type">class="kw">double price,class="type">class="kw">double sl);
   class=class="str">"cmt">//---
   class="type">void                        DecreaseFactor(class="type">class="kw">double decrease_factor) { m_decrease_factor=decrease_factor;                    }

   class="type">void                        Clusters(class="type">int value)                                     { m_clusters=value;                                        }
   class="type">void                        TrainingPoints(class="type">int value)                               { m_training_points=value;                                 }

常见问题

在编辑器里用向导建标准类工程,选层次聚类模块,把日线振幅数组传进去即可生成树状图,省去手写距离计算。
把当日振幅算出来丢进已训练好的树节点,落在高层分支代表低波动,低层细分支代表极端波动,据此调仓更稳。
可以,小布能直接对品种做无监督波动分层,打开对应页就能看到树状分组和历史区间归类,不用写工程。
标准类已封装数据拼装和校验,裸写易漏边界;用向导生成后只改参数即可,重点防输入数据含异常值。
先按相关性剔掉冗余维度,再用层次聚类做纵向切分,分支阈值看样本量,别一股脑塞满所有指标。