- 显示:
- 34
- 等级:
- 已发布:
-
需要基于此代码的EA交易或指标吗?请在自由职业者服务中订购 进入自由职业者服务
外汇和期货的原始价格具有非平稳性:基于这些数据训练的标准回归和分类模型会面临严重的预见性偏差和虚假相关性。一种简单的解决方法——整数差分——虽然消除了非平稳性,但在这一过程中却破坏了所有价格记忆,舍弃了预测模型所必需的自相关结构。
《金融机器学习进展》(López de Prado,2018)第 5 章中提出的固定宽度分数差分(FFD)方法, 通过采用非整数阶d ∈ (0, 1) 的差分来解决这一问题,该阶数刚好足以满足平稳性,同时保留最大程度的记忆效应。本文提供该方法的 MQL5 生产级实现。

FFD输出结果的双面板示意图:非平稳的原始价格(a)和平稳的FFD序列(b),其中回溯窗口已标注
组件
- FFDEngine.mqh— 仅包含头文件的库,其中包含CFFDEngine 类。提供Init()、Compute()(单根K线)和ComputeBuffer()(带prev_calculated 优化的完整指标缓冲区)函数。OnInit() 之后不再进行动态内存分配。
- FFD.mq5— 封装CFFDEngine 的自定义指标。在单独的图表窗口中绘制 FFD 序列。支持所有ENUM_APPLIED_PRICE 值。
算法工作原理
权重向量由以下递归关系定义(AFML 方程 5.4):
w[0] = 1 w[k] = -w[k-1] * (d - k + 1) / k, k = 1, 2, ...
当|w[k]| < 阈值 时,迭代停止。 随后将该向量反转,使得回溯窗口中最旧的价格获得最小权重,而最新价格获得 1.0。第 i 根K线处的 FFD 值是反转后的权重向量与对数价格窗口[i−width, …, i] 的点积。
当d = 0.4 且阈值 = 1e-5 时,窗口宽度为 1 457 个柱;当阈值 = 1e-3 时,窗口宽度为 54 个柱。阈值控制着平稳性与记忆效应之间的权衡:较小的阈值值能保留更多的记忆效应,但代价是需要更宽的回溯窗口。
输入参数
| 参数 | 默认值 | 描述 |
|---|---|---|
| InpD | 0.4 | 分段差分阶数。典型取值范围:0.1–0.9。大于 0.5 的值会产生近似整数差分;小于 0.1 的值会产生近似原始价格。 最优d 值 是指在所选显著性水平下通过 ADF 检验的最小值——有关 Python 搜索过程,请参阅配套文章。 |
| InpThreshold | 1e-5 | 权重阈值τ。当|w[k]| < τ 时,迭代停止。较小的值会产生更宽的窗口并更好地保留记忆,但需要更多的历史K线才能得到第一个有效输出。推荐范围:1e-4 至 1e-5。 |
| InpUseLog | true | 在求差分前应用ln(价格)。推荐用于原始价格序列(收盘价、开盘价、最高价、最低价)。仅当输入已是收益率或对数收益率序列时,才应设置为false。 |
| InpPrice | PRICE_CLOSE | 应用的价格类型。接受任何ENUM_APPLIED_PRICE 值:PRICE_OPEN、PRICE_HIGH、PRICE_LOW、PRICE_CLOSE、PRICE_MEDIAN、PRICE_TYPICAL、PRICE_WEIGHTED。 |
安装
- 将FFDEngine.mqh 复制到您的MQL5\Include\ 文件夹中(或 CodeBase 下载时指定的子文件夹——请参见下方的文件位置)。
- 将FFD.mq5 复制到MQL5\Indicators\Downloads\ 文件夹中(下载 CodeBase 时会自动放置在此处)。
- 在 MetaEditor 中编译这两个文件。该指标应在#property strict 条件下无警告地编译通过。
- 将FFD 添加到任意图表上。在回溯窗口(宽度 + 1 根 K 线)填充完成后,指标窗口将出现在主图表下方。
在您自己的 EA 或指标中使用 CFFDEngine
FFDEngine.mqh 是一个仅包含头文件的库。请将其包含进来,并在OnInit() 中调用一次Init():
#include <FFDEngine.mqh> //--- 固定宽度分数差分引擎的全局实例 CFFDEngine g_engine; //+------------------------------------------------------------------+ //| 专家初始化函数 | //+------------------------------------------------------------------+ int OnInit() { //--- 使用 d=0.4、阈值=1e-5 并启用对数变换来初始化 FFD 引擎 //--- 此配置会在EA初始化阶段构建一个静态内存权重窗口 if(!g_engine.Init(0.4, 1 e-5, true)) { Print("FFD engine init failed"); return(INIT_FAILED); } return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 专家 tick 函数 | //+------------------------------------------------------------------+ void OnTick() { //--- 向引擎查询,以确定确切需要多少个历史K线 //--- 根据阈值截断计算一个有效的 FFD 值 int need = g_engine.GetMinBars(); double close[]; //--- 获取所需深度的历史价格数据。 //--- 如果历史数据尚未同步或不完整,则跳过执行以避免错误。 if(CopyClose(_Symbol, _Period, 0, need, close) < need) return; //--- 确保数组的索引与时间顺序一致(最旧的柱状图位于索引 0 处) //--- 以便与反向 FFD 权重向量矩阵变换正确对齐 ArraySetAsSeries(close, false); //--- 计算当前实时K线的稳态分数差分输出值 double ffd_value = g_engine.Compute(close, need); //--- 将 ffd_value 作为模型的特征。 }
与 Python 的交叉验证
配套文件FFDValidation.mq5(可在文章下载中获取)将 FFD 值导出到 CSV 文件中。Python 脚本ffd_cross_validate.py 使用afml 库重新计算相同的值,并逐根 K 线进行比较。 在 EURUSD H1 时段的 5 000 根K线数据上,当d = 0.4 且阈值 = 1e-5 时,最大绝对误差小于 1e-12。
性能说明
- 权重向量分配:在OnInit() 中执行一次。在 tick 路径上不进行分配。
- 每根K线计算:O(width) 内积。在现代硬件上,对 1 457 个元素进行内积计算可在 50 μs 内完成。
- ComputeBuffer() 通过prev_calculated 参数跳过已计算的K线——每次 tick 仅重新计算当前未完成的K线。
参考文献与配套文章
- López de Prado, M. (2018).《金融机器学习进展》,第 5 章(分数阶微分),第 76–95 页。Wiley 出版社。
- 完整理论、Python 实现及基于 ADF 的参数搜索:机器学习特征工程——第 2 部分:在 MQL5 中实现固定宽度分数阶微分,作者:Patrick M. Njoroge。
- 配套验证工具:FFDValidation.mq5 和ffd_cross_validate.py—— 包含在文章下载包中。
由MetaQuotes Ltd译自英文
原代码: https://www.mql5.com/en/code/72499
长期趋势TRIX振荡指标
基于双TRIX和LWMA滤波的长期动量和趋势振荡指标。
Institutional Kinematic Price Physics (Velocity and Acceleration)
一种定量物理引擎,通过将微分学应用于价格走势,提取真实的市场速度(一阶导数)和市场加速度(二阶导数),从而在趋势耗尽发生之前就预测到这一情况。