您应当知道的 MQL5 向导技术(第 64 部分):运用 DeMarker 和包络通道形态,搭配白噪内核(基础篇)
◍ 用 DeMarker 加包络通道搭白噪策略骨架
MQL5 向导里可以拼出一种组合:DeMarker 指标负责捕捉超买超卖拐点,包络通道(Envelopes)框定价格偏离中轨的边界,再叠一层白噪内核(white noise kernel)来打乱信号时序、降低过拟合。这套思路适合在 MT5 里先做离线回测,而不是实盘直接跑。 DeMarker 取值在 0~1 之间,常规阈值 0.7 上方视为超买、0.3 下方视为超卖;包络通道默认偏差 0.1 即价格上下各偏离均线 10%。把两者交叉过滤后,白噪内核的作用是在信号触发里注入随机扰动,让样本内表现没那么「漂亮」到失真。 外汇与贵金属杠杆高、跳空频繁,这类形态策略在极端行情里可能频繁假突破。建议先在 EURUSD 的 H1 周期用策略测试器跑 2023 全年 Tick 数据,看信号分布再决定参数。
用 Python 接管 MQL5 指标信号
想把 DeMarker 和支撑/阻力包络带动量指标配对做机器学习,不必困在 MQL5 环境里硬写。实操路径是用 Python 重写 MQL5 指标逻辑,再借 MetaTrader 5 的 Python 模块把行情拉过来。 该 Python 模块能直连经纪商服务器,取回历史价格与品种规格,这意味着你本地训练用的样本和 MT5 终端看到的完全一致,避免跨源偏差。 对于外汇、贵金属这类高波动品种,先用小样本跑通取数—指标计算—特征拼装这条链路,比直接上模型更划算。开 MT5 装好 Python 包,导入一组 XAUUSD 的 H1 数据验证连通性,是第一步该做的事。
「Python 里缺的指标自己写更稳」
Python 生态里技术分析库不少,但标准覆盖并不齐。以 pandas-ta 为例,它就没有 DeMarker 振荡器;而另一个常见库 'ta' 虽有 DeMarker,却缺了原生形式的包络线(Envelopes),只用布林带和 Donchian 通道做了替代。 实际跑下来,从零实现 DeMarker 和包络线,工作量跟装库调标准函数差不多,甚至更省心。我们自建了这两个函数,在减少外部模块依赖的同时,解释器加载负担更低,脚本整体可能略快一点。 外汇与贵金属行情高波动、杠杆风险大,任何自写指标都先在 MT5 导出的历史数据上回测再上实盘。
◍ 用 Python 拆开 DeMarker 的动能内核
DeMarker 是区间锁在 0~1 的振荡器,高于 0.7 倾向超买、低于 0.3 倾向超卖,外汇与贵金属品种受消息驱动跳空多,这套阈值只作概率参考,实战须自认高风险。它的核心不是收盘价,而是高低点相对前一根的位移方向。 DeMax 取最高价差分的正值部分,低点差分负值取绝对值得 DeMin,分别记上行动能与下行动能。代码里用 diff() 后接 clip,一行就把「不涨/不跌」抹成零,避免噪声污染缓冲区。 demax = df['high'].diff().clip(lower=0) # 最高价较前根走高才留数,否则置零 demin = -df['low'].diff().clip(upper=0) # 最低价较前根走低取绝对值,否则置零 demax_sma = demax.rolling(window=period).mean() # 对上行动能做 period 周期均值平滑 demin_sma = demin.rolling(window=period).mean() # 下行动能同步平滑,引入滞后降敏 demarker = demax_sma / (demax_sma + demin_sma) # 归一化到 0~1,返回单列 main 平滑用 rolling(mean) 会吃掉前 period-1 个 NaN,默认 14 周期时开头 13 根不可用,回测前先 dropna。周期越短灵敏度越高,14 是平衡宏观趋势识别的常用值,黄金 M15 上可试 9 看反应。 除零在 demarker 这步理论存在、实盘罕见,因为高低点总在变;返回 Pandas 单列是为了直接拼进你已有的策略框架,开 MT5 对照自定义指标看偏离即可。
def DeMarker(df, period=class="num">14): """ Calculate DeMarker indicator for a DataFrame with OHLC prices Args: df: Pandas DataFrame with columns [&class="macro">#x27;open&class="macro">#x27;, &class="macro">#x27;high&class="macro">#x27;, &class="macro">#x27;low&class="macro">#x27;, &class="macro">#x27;close&class="macro">#x27;] period: Lookback period(class="kw">default class="num">14) Returns: Pandas Series with DeMarker values """ # Calculate DeMax and DeMin demax = df[&class="macro">#x27;high&class="macro">#x27;].diff().clip(lower=class="num">0) demin = -df[&class="macro">#x27;low&class="macro">#x27;].diff().clip(upper=class="num">0) # Smooth the values class="kw">using SMA demax_sma = demax.rolling(window=period).mean() demin_sma = demin.rolling(window=period).mean() # Calculate DeMarker demarker = demax_sma / (demax_sma + demin_sma) class="kw">return pd.DataFrame({&class="macro">#x27;main&class="macro">#x27;: demarker})
用包络线框住价格的常态区间
价格包络线围绕移动平均线上下各画一条波带,按固定百分比偏离中心线,给交易者标出潜在的支撑与阻力区。上轨和下轨之间的距离由 deviation 决定,默认 0.1 即中心线上下各 10%,把价格日常波动圈在一个可观测的通道里。 实现时先算简单移动平均:取 close 列做 rolling(window=period).mean(),period 默认为 14。注意前 period-1 个位置会是 NaN,实际接入行情时要先丢弃或向前填充,否则前 13 根 K 线带值是空的。 上轨 = MA × (1 + deviation),下轨 = MA × (1 - deviation)。以 deviation=0.1 为例,上轨是均值的 110%,下轨是 90%。价格触到任一波带,可能意味着突破启动,也可能是超买超卖后的回归,两种情形都对应趋势延续或震荡的不同概率。 deviation 直接控制带宽:外汇欧美盘这类波动温和的品种用 0.05~0.1 更贴身,黄金或数据行情用 0.15 以上才不容易被毛刺扫出。deviation 必须为正,否则下轨会翻到均值上方形成无效带。若想上下不对称,应换布林带而非硬改这套对称逻辑。 返回的 DataFrame 含 upper / ma / lower 三列,可直接喂给可视化或信号函数。下面这段是核心计算,逐行拆完就能在本地 pandas 环境跑通。
<span class="keyword">def</span> Envelopes(df, period=<span class="number">class="num">14</span>, deviation=<span class="number">class="num">0.1</span>): <span class="class="type">class="kw">string">""" Calculate Price Envelopes for a DataFrame with OHLC prices Args: df: Pandas DataFrame with columns [&class="macro">#x27;open&class="macro">#x27;, &class="macro">#x27;high&class="macro">#x27;, &class="macro">#x27;low&class="macro">#x27;, &class="macro">#x27;close&class="macro">#x27;] period: MA period(class="kw">default class="num">20) deviation: Percentage deviation from MA(class="kw">default class="num">0.05 for class="num">5%) Returns: DataFrame with columns [&class="macro">#x27;upper&class="macro">#x27;, &class="macro">#x27;ma&class="macro">#x27;, &class="macro">#x27;lower&class="macro">#x27;] """</span> <span class="comment"># Calculate moving average(typically class="kw">using close prices)</span> ma = df[<span class="class="type">class="kw">string">&class="macro">#x27;close&class="macro">#x27;</span>].rolling(window=period).mean() <span class="comment"># Calculate upper and lower envelopes</span> upper = ma * (<span class="number">class="num">1</span> + deviation) lower = ma * (<span class="number">class="num">1</span> - deviation) <span class="keyword">class="kw">return</span> pd.DataFrame({<span class="class="type">class="kw">string">&class="macro">#x27;upper&class="macro">#x27;</span>: upper, <span class="class="type">class="kw">string">&class="macro">#x27;ma&class="macro">#x27;</span>: ma, <span class="class="type">class="kw">string">&class="macro">#x27;lower&class="macro">#x27;</span>: lower})
「RNN 只吃这 6 个能前向漫游的特征」
我们说的特征,是把 DeMarker 和包络线两个指标的 signal 做成矢量化表达,再喂给用白噪内核的循环神经网络。模型本身在 Python 里实现,承接上一篇文章里初次考察的共 10 个特征。 这 10 个特征里只有 6 个允许前向漫游:编号 0、1、5、6、7、8。其余 4 个在 RNN 结构下无法前向传递,直接弃用。 所以在投喂 RNN 之前,必须先用 Python 手写代码把上述 6 个特征单独抽出来、排好时序。外汇与贵金属行情高波动,这类特征工程只是预处理环节,模型输出仅代表概率倾向,不构成方向保证。