自从开始阅读 John F. Ehlers(MESA Software)发布的技术分析方法以来,我一直致力于为 MQL4 开发一种 filters API。尽管并非所有方面都像模拟音频滤波器一样,但这些 FX 滤波器当然都会对串行数据进行操作。
在开发此 API 时,我实现了一个指标,该指标为指标过滤器链中的不同过滤器提供了许多选项。我在 MQL4 中使用的方法只是提供一些嵌套的
#ifdef
声明,用于配置要在指标构建中使用的精确过滤器链。这与生成任何更多数量的不同指标定义的实现形成对比,每个指标定义仅在链接的过滤器链的某些方面有所不同。
尝试将其移植到 MQL5,我生成了一个似乎是 MQL5 编译器可能无法处理的
ifdef
声明。以下应该会产生错误。
#define CORRA_NRFILTERS_CORRA 2
#ifdef CORRA_HPLP
#ifdef CORRA_ROC
#property indicator_buffers -1
THUNK9
#else
#ifdef CORRA_FILTER_IFISHER
#property indicator_buffers 5
THUNK8
#else
#property indicator_buffers 4
THUNK7
#endif
#endif
THUNK6
#else // !CORRA_HPLP
#ifdef CORRA_ROC
#property indicator_buffers 4
THUNK5
#else
#ifdef CORRA_FILTER_IFISHER
#property indicator_buffers 4
THUNK4
#else
#ifdef CORRA_WMA
#property indicator_buffers 3
THUNK3
#endif
#else // a secondary `else` clause, probably the cause here
// #property indicator_buffers 2
THUNK // curiously not in fact reached
#property thunk
#property indicator_buffers CORRA_NRFILTERS_CORRA
#endif
#endif
#endif
此代码旨在产生至少一个错误,并且 MQL5 编译器尚未到达这些子句中的任何分支。它解析该文件没有错误。随后,指标最终没有为其 MQL5 实现定义适当数量的数据缓冲区。
考虑到 MQL 中这些预处理器声明没有任何类型的
else
子句,虽然这段代码可能有点难以直观地解析,但类似这样的方法对于 MQL4 中的原型设计来说已经足够好了.
目前,我正在尝试将整个代码库移植到 MQL5,但事实证明这并不是一个完全简单的过程。
我试图测试一种不同的方法来实现 MQL5 的
indicator_buffers
属性,这时我注意到编译器甚至无法访问我正在使用的代码(如上所示)。
在原始 MQL4 实现中,这部分是通过
IndicatorBuffers()
函数进行管理的。这似乎已从 API 中删除。 MQL4 indicator_buffers
属性现在可以由 indicator_plots
属性表示,而 MQL5 indicator_buffers
属性则具有早期 IndicatorBuffers()
函数的功能。它还从可以在运行时设置属性的任何范围中删除该属性,现在改用这些静态预处理器指令。
它会在
ifdef
进一步测试,似乎与
ifdef
声明的深度无关。我将尝试在单独的文件中测试此部分。
简单地缩进嵌套的
ifdef
子句后,问题似乎出在放错位置的 else
子句,现在在上面的示例中进行了注释
更新的示例,带有
ifdef
子句的缩进
#define CORRA_NRFILTERS_CORRA 2
// other constants to be tested in some later revision
#define CORRA_NRFILTERS_HPLP 2
#define CORRA_NRFILTERS_IFISHER 1
#define CORRA_NRFILTERS_WNA 1
#define CORRA_NRFILTERS_ROC 1
#ifdef CORRA_HPLP
#ifdef CORRA_ROC
#property indicator_buffers
THUNK9
#else
#ifdef CORRA_FILTER_IFISHER
#property indicator_buffers 5
THUNK8
#else
#property indicator_buffers 4
THUNK7
#endif
#endif
THUNK6
#else // !CORRA_HPLP
#ifdef CORRA_ROC
#property indicator_buffers 4
THUNK5
#else
#ifdef CORRA_FILTER_IFISHER
#property indicator_buffers 4
THUNK4
#else
#ifdef CORRA_WMA
#property indicator_buffers 3
THUNK3
#endif
#property indicator_buffers CORRA_NRFILTERS_CORRA
#endif
#endif
#endif
在另一种方法中,MQL5 编译器似乎可以支持
property
声明中的一些数学运算。
#ifdef CORRA_HPLP
#define CORRA_NRFILTERS_HPLP 2
#else
#define CORRA_NRFILTERS_HPLP 0
#endif
#ifdef CORRA_IFISHER
#define CORRA_NRFILTERS_IFISHER 1
#else
#define CORRA_NRFILTERS_IFISHER 0
#endif
#ifdef CORRA_WMA
#define CORRA_NRFILTERS_WMA 1
#else
#define CORRA_NRFILTERS_WMA 0
#endif
#ifdef CORRA_ROC
#define CORRA_NRFILTERS_ROC 1
#else
#define CORRA_NRFILTERS_ROC 0
#endif
#define CORRA_NRFILTERS_CORRA 2
#property indicator_buffers CORRA_NRFILTERS_CORRA + CORRA_NRFILTERS_ROC + CORRA_NRFILTERS_WMA + CORRA_NRFILTERS_IFISHER + CORRA_NRFILTERS_HPLP
#property indicator_plots 1
这个更新的示例不会使用这么多嵌套的
ifdef
子句