您应该了解的MQL5向导技巧(第六十六部分):结合点积核使用FrAMA与强力指数形态·进阶篇
📘

您应该了解的MQL5向导技巧(第六十六部分):结合点积核使用FrAMA与强力指数形态·进阶篇

第 2/2 篇

「FrAMA与强力指数共振的二元信号构造」

把形态6写成函数,核心是先铺一个全0的二维数组,行数等于输入数据帧长度,两列分别装看涨、看跌信号。全0初始化保证只有条件命中才翻成1,不会在历史上凭空冒出噪声信号。 三个输入帧——FrAMA、强力指数、收盘价——长度必须严格对齐,否则 shift(1)、shift(2) 错位会直接污染信号。代码里用 np.zeros((len(one_df), 2)) 搭好骨架,前两根K线因偏移产生 NaN,所以函数末尾把第0、1行强制置0,避免无效触发。 看涨列的逻辑是:连续3期收盘价站在 FrAMA 上方,且强力指数为正,同时前两期强力指数呈 U 形回升(shift(1) < shift(2))。看跌列完全对称,价格连续3期在 FrAMA 下方,强力指数为负且近期动量继续向下。 下跌往往比上涨来得快,所以同一套对称条件在牛熊里的命中频率可能差很多。建议先在 MT5 导出的日线或 H1 数据上跑一遍,统计该信号在历史样本里的出现次数,再决定是否值得接进实盘过滤层。外汇与贵金属杠杆高,信号仅作趋势确认参考,不构成方向保证。

MQL5 / C++
def feature_6(one_df, two_df, price_df):
    """
    Generate binary signals based on sustained price-FrAMA alignment and Force Index momentum.
    
    Args:
        one_df: DataFrame with FrAMA values(&class="macro">#x27;main&class="macro">#x27; column).
        two_df: DataFrame with Force Index values(&class="macro">#x27;main&class="macro">#x27; column).
        price_df: DataFrame with price data(&class="macro">#x27;close&class="macro">#x27; column).
    
    Returns:
        2D NumPy array with bullish(column class="num">0) and bearish(column class="num">1) signals.
    """
    feature = np.zeros((len(one_df), class="num">2))
    
    feature[:, class="num">0] = ((price_df[&class="macro">#x27;close&class="macro">#x27;] > one_df[&class="macro">#x27;main&class="macro">#x27;]) &
                            (price_df[&class="macro">#x27;close&class="macro">#x27;].shift(class="num">1) > one_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1)) &
                            (price_df[&class="macro">#x27;close&class="macro">#x27;].shift(class="num">2) > one_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">2)) &
                            (two_df[&class="macro">#x27;main&class="macro">#x27;] > class="num">0.0) &
                            (two_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1) < two_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">2))).astype(class="type">int)
    feature[:, class="num">1] = ((price_df[&class="macro">#x27;close&class="macro">#x27;] < one_df[&class="macro">#x27;main&class="macro">#x27;]) &
                            (price_df[&class="macro">#x27;close&class="macro">#x27;].shift(class="num">1) < one_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1)) &
                            (price_df[&class="macro">#x27;close&class="macro">#x27;].shift(class="num">2) < one_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">2)) &
                            (two_df[&class="macro">#x27;main&class="macro">#x27;] < class="num">0.0) &
                            (two_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1) < two_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">2))).astype(class="type">int)
    
    feature[class="num">0, :] = class="num">0
    feature[class="num">1, :] = class="num">0
    
    class="kw">return feature

价格与FrAMA、强力指数单周期同向的短线信号

这套逻辑只盯一根K线内的变化:收盘价、FrAMA、强力指数三者同时向上或向下,才记一次信号。相比跨多周期平滑的同类特征,它对短期拐点的反应更快,剥头皮或日内短线用起来更跟手。 三个输入必须行数完全一致——FrAMA数据帧、强力指数数据帧和价格数据帧的索引要对齐,否则 shift(1) 比的是错位数据,信号会整列作废。输出是一个 N×2 的二维数组,第 0 列看涨、第 1 列看跌,分开存互不覆盖。 看涨条件写成:今收 > 昨收 且 今FrAMA > 昨FrAMA 且 今强力指数 > 昨强力指数。三项同步上行代表买盘在价、趋、量能上达成一致,单周期判断让它对即时拉升敏感。看跌反之,三项同步下行捕捉卖压一致性。 因为用了 shift,数组前两行(索引 0 和 1)强制置 0——第一行无前值可比,第二行常因指标预热不足噪音大。回测时建议先统计信号触发频率:外汇与贵金属波动大、噪音多,单周期敏感特征在震荡市可能一天触发十几二十次,过度交易会吃掉点差。把信号画在图上对照量价,确认不是假突破再考虑实盘。

MQL5 / C++
def feature_9(one_df, two_df, price_df):
    """
    Generate binary signals based on single-period momentum alignment of price, FrAMA, and Force Index.
    
    Args:
        one_df: DataFrame with FrAMA values(&class="macro">#x27;main&class="macro">#x27; column).
        two_df: DataFrame with Force Index values(&class="macro">#x27;main&class="macro">#x27; column).
        price_df: DataFrame with price data(&class="macro">#x27;close&class="macro">#x27; column).
    
    Returns:
        2D NumPy array with bullish(column class="num">0) and bearish(column class="num">1) signals.
    """
    feature = np.zeros((len(one_df), class="num">2))
    
    feature[:, class="num">0] = ((price_df[&class="macro">#x27;close&class="macro">#x27;] > price_df[&class="macro">#x27;close&class="macro">#x27;].shift(class="num">1)) &
                            (one_df[&class="macro">#x27;main&class="macro">#x27;] > one_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1)) &
                            (two_df[&class="macro">#x27;main&class="macro">#x27;] > two_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1))).astype(class="type">int)
    feature[:, class="num">1] = ((price_df[&class="macro">#x27;close&class="macro">#x27;] < price_df[&class="macro">#x27;close&class="macro">#x27;].shift(class="num">1)) &
                            (one_df[&class="macro">#x27;main&class="macro">#x27;] < one_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1)) &
                            (two_df[&class="macro">#x27;main&class="macro">#x27;] < two_df[&class="macro">#x27;main&class="macro">#x27;].shift(class="num">1))).astype(class="type">int)
    
    feature[class="num">0, :] = class="num">0
    feature[class="num">1, :] = class="num">0
    
    class="kw">return feature

◍ 点积卷积网络怎么替FrAMA形态挑重点

把自适应均线(FrAMA)和强力指数揉进机器学习,最轻量的做法是点积核一维卷积网络。它吃进去的是 [批次, 通道, 序列长度] 的三维张量,吐出来每个样本一个 0 到 1 之间的标量:靠近 0 倾向看跌,靠近 1 倾向看涨。外汇与贵金属杠杆高、跳空频繁,这种概率输出只适合当辅助信号,不能直接当成下单依据。 传统 CNN 的局部感受野容易漏掉长程依赖,而点积注意力让每个时间步都能回头看整条序列。高波动段和平稳段的参考价值不同,注意力分数按输入动态算,模型会自己给混乱行情里的关键 K 线加权重,不必靠堆大卷积核去扩视野。 代码里初始化用 kernel_size=3 算对称填充,保住卷积后序列长度不变;Q、K、V 三个 1×1 卷积本质是逐时间步线性映射。proj 末尾接 Sigmoid,把输出锁死在 [0,1]。 前向传播里注意力矩阵是 Q 转置与 K 做批量矩阵乘得到的 [B, W, W],再除以序列长度平方根做缩放 Softmax 稳梯度。最后 V 乘回注意力权重,经全局平均池化压成单值——比完整 Transformer 省算力,中等序列长度上跑得动。

MQL5 / C++
class DotProductConv1D(nn.Module):
    def __init__(self, in_channels=class="num">1, out_channels=class="num">1, kernel_size=class="num">3):
        super().__init__()
        self.kernel_size = kernel_size
        self.padding = kernel_size class=class="str">"cmt">// class="num">2
        
        # Projections for dot product attention(1D convolution)
        self.query = nn.Conv1d(in_channels, out_channels, kernel_size=class="num">1)
        self.key = nn.Conv1d(in_channels, out_channels, kernel_size=class="num">1)
        self.value = nn.Conv1d(in_channels, out_channels, kernel_size=class="num">1)
        
        # Output projection to produce a single value per sample
        self.proj = nn.Sequential(
            nn.Conv1d(out_channels, class="num">1, kernel_size=class="num">1),
            nn.AdaptiveAvgPool1d(class="num">1),  # Reduce width to class="num">1 (global average pooling)
            nn.Sigmoid()  # Ensures output in [class="num">0, class="num">1]
        )
    def forward(self, x):
        B, C, W = x.shape  # [Batch, Channels, Width]
        
        # Compute Q/K/V(all [B, out_channels, W])
        q = self.query(x)
        k = self.key(x)
        v = self.value(x)
        
        # Dot product attention
        attn = torch.bmm(q.transpose(class="num">1, class="num">2), k)  # [B, W, W]
        attn = F.softmax(attn / (W ** class="num">0.5), dim=-class="num">1)  # Scaled softmax
        
        # Apply attention to values
        out = torch.bmm(v, attn.transpose(class="num">1, class="num">2))  # [B, out_channels, W]
        
        # Project to [B, class="num">1, class="num">1] and squeeze to [B, class="num">1]
        out = self.proj(out)  # [B, class="num">1, class="num">1]
        class="kw">return out.squeeze(-class="num">1)  # [B, class="num">1]

「有限样本下的前向测试结果」

形态6与形态9都跑通了前向测试,说明这两类特征结构在样本内具备可识别性。但必须点明:本次训练集规模极小,结论的外推性存疑,外汇与贵金属市场高杠杆、高波动,盲信小样本回测极易踩坑。 读者若想确认形态6、形态9是否真有边缘概率优势,应自己在MT5用更大周期、更多品种重跑验证,而不是照搬这份报告当长期依据。 任何形态识别都只是概率倾向,不是确定性信号;样本外的失效风险始终存在。

把工具请下神坛

FrAMA 叠加强力指数震荡指标,再接点积核机器学习模型,这次只跑了形态 6 与形态 9 两种,样本量极小,远谈不上验证充分。外汇与贵金属市场高杠杆、高波动,这类组合策略只代表一种可探索的信号扩展路径,实战胜率仍偏概率性。 除已测的两种外,剩下 8 种形态和同组指标的其它实现方式都还没碰,wz_66.mq5 与 SignalWZ_66.mqh 已放出,66_6.onnx、66_9.onnx 各 29.43 KB,直接丢进 MT5 用向导编译就能复现初步结果。 别把向导生成的 EA 当圣杯,它只是把人工看形态的事交给核函数去算;真要落地,自己换形态编号、调包含文件引用才是正经事。

常见问题

取价格与FrAMA同向、且强力指数同周期为正的三重共振作为二元信号,仅在三者同方向时考虑开仓,避免单一指标假突破。
有限样本前向测试显示该类信号在趋势初段命中概率偏高,但样本外衰减明显,仅适合作为辅助过滤而非独立依据,外汇贵金属高风险需严控仓位。
可以,小布盯盘的AIGC已内置这类形态诊断,打开对应品种页即可看到实时共振提示,把重复劳动交给小布,你专注决策。
它是对FrAMA历史形态做加权卷积,自动挑出对当前价格响应最强的窗口,替你过滤掉噪声段,只保留高权重形态重点。
样本量不足会导致前向测试过拟合倾向,仅能说明构造逻辑可行,真要用得跑足够长周期和多品种验证,别把工具请下神坛。