您应当知道的 MQL5 向导技术(第 64 部分):运用 DeMarker 和包络通道形态,搭配白噪内核(基础篇)
📘

您应当知道的 MQL5 向导技术(第 64 部分):运用 DeMarker 和包络通道形态,搭配白噪内核(基础篇)

第 1/3 篇

◍ 用 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 对照自定义指标看偏离即可。

MQL5 / C++
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 环境跑通。

MQL5 / C++
<span class="keyword">def</span> Envelopes(df, period=<span class="number">class="num">14</span>, deviation=<span class="number">class="num">0.1</span>):
&nbsp;&nbsp;&nbsp;&nbsp;<span class="class="type">class="kw">string">"""
&nbsp;&nbsp;&nbsp;&nbsp;Calculate Price Envelopes for a DataFrame with OHLC prices
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Args:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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;]
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;period: MA period(class="kw">default class="num">20)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;deviation: Percentage deviation from MA(class="kw">default class="num">0.05 for class="num">5%)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Returns:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataFrame with columns [&class="macro">#x27;upper&class="macro">#x27;, &class="macro">#x27;ma&class="macro">#x27;, &class="macro">#x27;lower&class="macro">#x27;]
&nbsp;&nbsp;&nbsp;&nbsp;"""</span>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment"># Calculate moving average(typically class="kw">using close prices)</span>
&nbsp;&nbsp;&nbsp;&nbsp;ma = df[<span class="class="type">class="kw">string">&class="macro">#x27;close&class="macro">#x27;</span>].rolling(window=period).mean()
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment"># Calculate upper and lower envelopes</span>
&nbsp;&nbsp;&nbsp;&nbsp;upper = ma * (<span class="number">class="num">1</span> + deviation)
&nbsp;&nbsp;&nbsp;&nbsp;lower = ma * (<span class="number">class="num">1</span> - deviation)
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;<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 个特征单独抽出来、排好时序。外汇与贵金属行情高波动,这类特征工程只是预处理环节,模型输出仅代表概率倾向,不构成方向保证。

常见问题

原文基础篇未给固定值;建议先在日线把包络偏离设 0.5%~1%,用历史 K 线看价格穿透频率,再按品种波动微调。
在 Python 侧按 bar 开盘时间做左连接,丢弃无对应 bar 的 tick;别用本地接收时间,避免时区与重报价造成偏移。
可以。小布能按你设定的品种与参数持续扫描,出现通道外穿透且 DeMarker 极值时推送提醒,省去手动刷图。
自己写能固定算法口径、避开不同库默认周期差;只要逐根 bar 用最高价最低价与前置 N 根极值算好,回测更可控。
会丢掉价格脱离常态区间的尺度信息;原文用带宽框住常态,缺它模型难分辨穿透是噪音还是趋势启动。