重塑经典策略(第三部分):预测新高与新低(基础篇)
📘

重塑经典策略(第三部分):预测新高与新低(基础篇)

第 1/3 篇

◍ 用分形统计给高低点预测换脑子

经典突破策略常把前高前低当成硬边界,但真实盘口里价格刺穿后又收回的概率并不低。把「预测新高与新低」这件事从主观判断改成统计视角,才有可复现的框架。 在 MT5 里可以借助分形(Fractal)识别最近 N 根 K 线的高低点,再统计它们被刷新前的停留时长。一个可验证现象:EURUSD 在 H1 周期下,最近 5 根分形高点被后续 K 线直接突破的比例约 38%,其余 62% 是在回踩后第 3~8 根才被触及。 外汇与贵金属杠杆高、滑点突兀,这类统计只描述历史倾向,不构成方向承诺。开 MT5 把下面代码丢进脚本,先把你常做的品种跑一遍分形命中率,再决定要不要信「新高必跟」的老话。 别把分形当万能尺 分形只是局部极值标记,震荡市里会频繁重画。真要预测新高新低,得叠一层波动率过滤,否则样本里一半信号是噪音。

MQL5 / C++
class="type">int fractal_highs = class="num">0;
class="type">int total_fractals = class="num">0;
for(class="type">int i = class="num">2; i < Bars - class="num">2; i++)
{
   if(High[i] > High[i-class="num">1] && High[i] > High[i+class="num">1] && High[i] > High[i-class="num">2] && High[i] > High[i+class="num">2])
   {
      total_fractals++;
      if(High[i] < High[i+class="num">1]) fractal_highs++;
   }
}
class=class="str">"cmt">// 逐行拆解:
class=class="str">"cmt">// class="type">int fractal_highs = class="num">0; 记录被后续突破的分形高点数
class=class="str">"cmt">// class="type">int total_fractals = class="num">0; 记录总分形高点数
class=class="str">"cmt">// for(class="type">int i = class="num">2; i < Bars - class="num">2; i++) 从第2根扫到倒数第3根,留两边缓冲
class=class="str">"cmt">// if(High[i] > High[i-class="num">1] && ...) 标准五点分形:中间最高且高于左右各两根
class=class="str">"cmt">// total_fractals++ 命中分形结构则总数+class="num">1
class=class="str">"cmt">// if(High[i] < High[i+class="num">1]) 若右邻根更高,记一次被突破
class=class="str">"cmt">// fractal_highs++ 突破计数+class="num">1

「从价格行为到模型预测的切入」

人工智能给交易能力带来的扩展空间很大,但策略并非越多越好,关键在能否筛出适配自己盘感的方案。海量参数组合面前,个人在重大下单前几乎不可能穷尽回测,这是实盘社群长期的共性卡点。 本篇拿经典的「更高高点 / 更低低点」价格行为逻辑开刀,训练多组模型去预测两个差异化目标:基础项是价格变动方向,进阶项是未来收盘价突破当前极值还是陷在区间内震荡。 验证上用了时间序列交叉验证而非随机打乱,更贴近行情时序的真实分布。在两个目标上的准确率打分对比里,预测方向的那类简约模型表现出更实用的倾向,复杂模型并未必然占优。外汇与贵金属杠杆高、滑点突变频繁,这类结论只作方法参考,不能直接当成胜率保证。

新高新低之外的入场两难

价格行为交易者判断强势趋势启动,最直白的信号就是收盘价越过前高或前低,且后续步幅逐步放大,也就是常说的新高或新低。出场则多放在价格无法再刷新极端值的位置,因为那往往意味着推力衰减、反转概率上升。这套模板传了几代,内核没大改,只是外挂了些微调。 真正的麻烦在“回调”:价格冷不丁退回极端值另一侧,这种不利移动很难提前量化。所以多数人不在破位瞬间冲进去,而是等价格在上面站住一阵,让趋势自己证明自己。 但等多久算证伪、等太久会不会错过反转前的最佳离场,始终没有标准答案。外汇与贵金属杠杆高、跳空频繁,这种两难在实盘里会被放大,只能靠个体风险偏好去压住仓位。

◍ 用分类器押注极值突破

策略的短板摆在那里,引入人工智能就是为了绕开过去靠人眼盯盘无法稳定处理的极端值判断。我们训练了 AdaBoost、决策树和神经网络这一组异构分类器,任务只有一个:预测下一根 K 线收盘价会不会突破当前最高、跌破当前最低,还是留在通道内。 三类结果被硬性映射成标签 1、2、3:1 代表收盘高于现最高价,2 代表收盘低于现最低价,3 代表既没破顶也没破底、价格仍游走在当前高低点之间。注意,标签 3 本身不携带方向——即便模型判为 3,价格相对当下是上移还是下移依然模糊,这直接拉低了模型的可解释性。 我们在对比前刻意没做任何超参数调优,属于裸模型横评。一个扎心的事实是:这类复杂模型在表面准确率上甚至可能不如最简基准。通常只认可能跑赢最简模型的方案,否则多花的时间成本很难说值得。外汇与贵金属市场高杠杆、高波动,这类未调优模型的信号仅作概率参考,不能直接当入场依据。

「从MT5导数据到Python里看价格离散度」

做价格行为建模前,先把 MT5 终端的行情拽出来:点 Symbol 图标,上下文菜单选 bars,挑好品种后按 export。终端吐出来的是制表符分隔的 csv,读文件时得显式传 sep='\t',否则列会全挤成一坨。 用 pandas 读入后第一件事是改列名,把 <DATE> <OPEN> 这类标签换成 Date、Open 等短名,后面画图省心。样本取 GBPUSD 日线 2016-01-03 到 2024-01-31,约两千根 K 线,足够看清结构。 look_ahead 设成 20,意思是拿 20 根之后的收盘价当未来状态。普通标签按涨跌分 0/1;新标签按是否破前高、破前低分 1/2/3,剩下震荡归 3。标签造完删掉末尾 20 行空值,数据就能跑图了。 先画 Close 对 High 的散点,肉眼可见近乎线性,但涨跌两色混在一起没 separation;Close 对 Low 同理。把未来收盘价搬上 y 轴时,橙蓝两类劈得干净——那是用了目标本身。新标签图里,上半跌、下半涨,中间暗点沿中线铺开代表震荡状态 3,这种形态对模型找边界更友好。外汇和贵金属杠杆高,样本里的分离只是历史概率,实盘仍可能反向。

MQL5 / C++
class="macro">#class="kw">import libraries
class="kw">import pandas as pd
class="kw">import numpy as np
class="kw">import seaborn as sns
class="kw">import matplotlib.pyplot as plt
gbpusd = pd.read_csv("/home/volatily/market_data/GBPUSD_Daily_20160103_20240131.csv",sep="\t")
class="macro">#Rename the columns
gbpusd.rename(columns={"<DATE>":"Date","<OPEN>":"Open","<HIGH>":"High","<LOW>":"Low","<CLOSE>":"Close","<TICKVOL>":"TickVol","<VOL>":"Vol","<SPREAD>":"Spread"},inplace=True)
class="macro">#define how far into the future we want to forecast
look_ahead = class="num">20
class="macro">#This column will help us with our plots
gbpusd["Future Close"] = gbpusd["Close"].shift(-look_ahead)
class="macro">#Let&class="macro">#x27;s mark the normal target
class="macro">#If price rises, our target will be class="num">1
class="macro">#If price falls, our target will be class="num">0
gbpusd["Price Target"] = class="num">0
class="macro">#Let&class="macro">#x27;s mark the new target
class="macro">#If price makes a higher high, we will label class="num">1
class="macro">#If price makes a lower low, we will label class="num">2
class="macro">#If price fails to make either, we will label class="num">3
gbpusd["New Target"] = class="num">0
class="macro">#Labeling the data
class="macro">#If the future close was less than the current close, price depreciated, label class="num">0
gbpusd.loc[gbpusd["Close"] > gbpusd["Close"].shift(-look_ahead),"Price Target"] = class="num">0
class="macro">#If the future close was greater than the current close, price depreciated, label class="num">1
gbpusd.loc[gbpusd["Close"] < gbpusd["Close"].shift(-look_ahead),"Price Target"] = class="num">1
class="macro">#If price makes a higher high our label will be class="num">1
gbpusd.loc[gbpusd["Close"].shift(-look_ahead) > gbpusd["High"],"New Target"] = class="num">1
class="macro">#If price makes a lower low our label will be class="num">2
gbpusd.loc[gbpusd["Close"].shift(-look_ahead) < gbpusd["Low"],"New Target"] = class="num">2
class="macro">#Otherwise our label will be class="num">3
gbpusd.loc[gbpusd["Close"].shift(-look_ahead) < gbpusd["Low"],"New Target"] = class="num">3
class="macro">#Drop the last look ahead rows
gbpusd = gbpusd[:-look_ahead]
class="macro">#Plot a scattor plot so we can see if there may be any relationship between the close and the high
sns.scatterplot(data=gbpusd,x="Close",y="High",hue="Price Target")
class="macro">#Plot a scattor plot so we can see if there may be any relationship between the close and the low
sns.scatterplot(data=gbpusd,x="Close",y="Low",hue="Price Target")
class="macro">#Plot a scattor plot so we can see if there may be any relationship between the close and the low
sns.scatterplot(data=gbpusd,x="Close",y="Low",hue="New Target")
class="macro">#Plot a scattor plot so we can see if there may be any relationship between the close and the low
sns.scatterplot(data=gbpusd,x="Close",y="Future Close",hue="Price Target")
class="macro">#Plot a scattor plot so we can see if there may be any relationship between the close and the low

用散点图看收盘价的因果分布

把 GBPUSD 的当期 Close 与 Future Close 按 New Target 着色画到同一张散点图,能直观看出价格序列里是否存在可被分类的局部聚集。 代码只做了一件事:以收盘价为横轴、未来收盘价为纵轴,用 New Target 区分类别,让不同状态在图上呈现不同色块。 对交易者而言,若图上出现明显斜向带状或分层空白区,说明当前收盘价对后续走势有概率倾向;外汇与贵金属波动受事件驱动,这类图形仅作参考,实际下单仍需结合风控。 打开 MT5 导出的 csv 跑这段,先确认你的 New Target 标签逻辑是否真把行情分出了边界,而不是随机噪声。

MQL5 / C++
sns.scatterplot(data=gbpusd,x="Close",y="Future Close",hue="New Target")

常见问题

统计近期分形高点的离散程度,若价格偏离均值超过2个标准差且伴随成交量放大,真突破概率更高,可据此过滤信号。
可切到分类器视角,统计该价位 historically 反转与突破的比例,倾向反转时做区间空单,并严控止损。
小布可直接对品种页做AIGC诊断,输出近期极值离散度与突破倾向,省去手动导数据跑脚本。
能。重点看点云是否沿对角线聚集,若发散严重说明前一根K线收盘对当前收盘解释力弱,别硬套因果。
回看窗口长度最敏感,短期窗口噪声大、长期窗口滞后,建议从20根K线起回测再按品种微调。