双彗星指标:峰谷预测新解法
用轨道线池构建可预测节点的高级ZigZag
传统峰谷指标的痛点与局限
峰谷指标(ZigZag)是技术分析中最常用的趋势骨架工具,其折线节点连接价格图表的最高价与最低价,用于过滤微小波动、识别波段。然而,社区中大量MQL5与MQL4实现都存在三个核心缺陷。第一是延迟性,节点往往要在价格反向运行一段幅度后才被确认,导致信号滞后。第二是问题节点(外柱)的不正确标记,在快速反转或跳空行情中,极值容易被错误分配。第三是性能不佳,尤其在多品种、多周期同时加载时,递归计算会拖慢终端。许多开发者试图创建“理想峰谷”,但多数只是在参数上修修补补,未触及结构本质。
在已有方案中,Yuri Kulikov(Yurich)的峰谷实现被公认为较优,其GetExtremums库能稳定提取节点。但即便如此,传统指标只能描述已发生的历史,无法告知交易者在当前柱上未完成节点可能的落点,更无法预估下一节点价格。这种“只回溯、不前瞻”的特性,限制了它在突破交易与拐点博弈中的直接应用。
高级峰谷的核心思路:轨道线池
本文提出的方法不再依赖单一峰谷算法的前瞻外推,而是借用移动平均线轨道线(Envelopes)作为基础。核心假设是:若存在一组参数各异的轨道线指标,其主线(与iMA一致)能包裹绝大部分历史峰谷节点,则这些轨道线的统计截面可反推节点坐标。具体目标定为两个:当前节点(位于零柱、未完成的峰/谷)与预测节点(未来下一峰谷的估测价位)。
我们构建两个指标池,各含100至227条iMA主线:一个用于高峰(取High计算偏差),一个用于低谷(取Low计算偏差)。对池中每条均线,计算其与所有历史ZZ节点的算术平均偏差,据此将主线平移为上轨或下轨。如此,上轨带对应高峰云、下轨带对应低谷云。将这数百条线视为3D平面,用当前零柱作截平面切开,所得横截面的极值与重心,即为特征点。
- 高峰池:搜索与ZZ(High)偏差最小的移动平均线,生成上轨截面
- 低谷池:搜索与ZZ(Low)偏差最小的移动平均线,生成下轨截面
- 截面特征:最大值、最小值、重心(算术平均),投射至零柱存储
- 预测逻辑:高峰取上轨截面特征,低谷取下轨截面特征推断下一节点
数学标记与偏差计算
为严谨描述,原文引入如下标记:ZZ为峰谷指标;ENV为轨道线主线(等于iMA值);Envelopes(i)为第i柱主线值;ZZ(High)、ZZ(Low)分别为峰谷高峰与低谷值;ENV(High)、ENV(Low)为对应轨道线主线值;n_high、n_low为峰谷数量。对每个池指标,计算所有节点与主线偏差的均值,公式简化为 sumHi[i]/H 与 sumLo[i]/L。该均值就是主线需平移的价位偏移量,从而绘制出包络带。
几何上,轨道线池是一个3D曲面。垂直价格图放置并以零柱切割,得到横截面曲线(特殊时为直线)。我们只需曲线上每点坐标,即可求最大、最小及重心。这些特征点被保存于历史,成为当前与下一节点的基础。由于高低峰分离处理,实际获取两个横截面,分别向右、向左旋转90度以便图表观察。
MQL5程序架构与关键类
作者将实现放入EA而非指标,理由是EA拥有独立数据流,性能优于同品种多指标共享流。核心依赖两个MQH:AdvancedZigZag.mqh(封装节点获取)与GetExtremums.mqh(Yurich提供)。AdvancedZigZag类含两种方法:Count()找给定柱数内所有节点并分高低数组;Read()找最后节点供可视化。结构MqlZigZag含price与t字段。以下为类头与构造片段:
struct MqlZigZag
{
double price; // Node coordinate
datetime t; // Time
};
class AdvancedZigZag
{
private:
MqlRates rt[];
dextremum zz[];
int history;
double amplitude;
public:
dextremum zHL[];
MqlZigZag zzH[],zzL[];
int Count(const double range);
int Read(const int nodes);
AdvancedZigZag(const int bars);
~AdvancedZigZag();
};
在two_Comets.mq5中,定义NUMBER_MA=227,即每池227条iMA,共454指标句柄。注意iEnvelopes主线等于iMA,故直接用iMA更方便。数据加载放在OnTick而非OnInit,避免初始化时缓冲未就绪导致计算不全。err变量控制仅首次装载。
宏技巧与图形绘制
为减少重复,作者定义一系列宏:SIZE(i)根据平均周期定像素大小;ObjF1~ObjF10封装文字对象属性设置;ObjFont、ObjCoordinates等组合宏。新手需注意:宏末尾无分号,因宏展开后由调用处补完。例如ObjFont后接ObjCoordinates(...),合起来才是一条语句。以下为EA头部宏声明:
#define NUMBER_MA 227 #define START_MA 5 #define SIZE(i) (double)i*0.3<1?1:(int)(i*0.25) #define ObjF1 ObjectSetString(0,name,OBJPROP_FONT,"Wingdings") #define ObjF2 ObjectSetInteger(0,name,OBJPROP_ANCHOR,ANCHOR_CENTER) #define ObjFont ObjF1;ObjF2; #define ObjCoordinates(T,P) ObjF3(T);ObjF4(P);
横截面点以Wingdings字符绘制,平均周期越大点越大,形似彗星。高峰截面右转90度、低谷左转90度。特征点(max、min、midi)以不同颜色与尺寸标于零柱,并写入历史。图7、图8展示了“双彗星”形态与特征分布。
节点预测与未来线绘制
最后一步是利用特征点标绘高级节点。若当前为高峰(zHL[0].type>0),则MIN类对象删除,绘制MAX连线至零柱,价格取minH、sumH或maxH之一(依已确认节点值判断);同时绘制MAXfuture线至未来柱,价格取maxL、sumL或minL。低谷反之。以下为高峰预测代码片段:
if(Azz.zHL[0].type>0) // peak
{
name="MAXfuture";
ObjectCreate(0,name,OBJ_TREND,0,0,0);
ObjZZ
ObjectSetDouble(0,name,OBJPROP_PRICE,0,price);
ObjectSetInteger(0,name,OBJPROP_TIME,0,t[0]);
ObjectSetDouble(0,name,OBJPROP_PRICE,1,maxL[0]);
ObjectSetInteger(0,name,OBJPROP_TIME,1,t[0]+NUMBER_MA*shift);
if(price<maxL[0]) ObjectSetDouble(0,name,OBJPROP_PRICE,1,sumL[0]/NUMBER_MA);
if(price<sumL[0]/NUMBER_MA) ObjectSetDouble(0,name,OBJPROP_PRICE,1,minL[0]);
}
该指标命名为“双彗星”,因高低截面如两颗飞行彗星。需强调:未来节点完成时间未知,仅预测价格坐标。实盘可将其作为支撑阻力参考,或结合趋势过滤使用。
结果分析与交易应用
观察表明:峰谷节点与预测点偏差在容许范围,多数节点落于截面阴影。彗星尾(最小平均周期点)指向价格方向,其反向弯曲程度暗示趋势反转概率。截面重心超前期高点表明上升趋势。特征点连线可视为动态支撑阻力。该算法不仅限峰谷,也可移植至分形或信号指标。
给MQL5开发者的建议
第一,善用宏削减重复代码,但需理解预处理展开规则。第二,重计算任务放EA独立流,轻绘图。第三,历史节点一次性计算后缓存,避免每Tick重算。第四,指标池规模可权衡统计需要与性能,227非强制。第五,ZigZag类可抽象复用,不仅限于双彗星。本文方法打开三维建模指标的新维度,值得深入。
综上,双彗星指标通过轨道线池横截面特征,实现了对传统峰谷的前瞻补充。它不替代ZigZag,而作为其高级扩展,适合波段与拐点策略研究者。中文交易者可在MT5中导入附带的mq5与mqh,先以可视化理解彗星形态,再逐步用于实盘预警。