量化软件下载:赫兹量化中自动搜索背离和趋合
用于定义背离的通用指标
现在我们已经处理了这个理论, 我们来开发这个指标。
选择一款振荡器。 为了不受单一振荡器定义背离的限制, 我们将使用 本文 中描述的通用振荡器。附件: iUniOsc (通用振荡器) 和 iUniOscGUI (与图形界面相同的振荡器)。我们将使用基础版 — iUniOsc。
创建一款新指标。我们在 MetaEditor 中创建新的 iDivergence 指标。我们会用到 OnCalculate 函数。OnTimer() 函数不是必需的。勾选 "单独窗口中的指标" 选项。我们创建三个缓冲区: 一个显示振荡器曲线, 以及两个出现背离时绘制箭头的缓冲区。在编辑器中打开一个新文件后, 更改缓冲区名称: 1 — buf_osc, 2 — buf_buy, 3 — buf_sell。应该在数组声明的地方以及OnInit() 函数中更改名称。我们还可以调整缓冲区属性: indicator_label1, indicator_label2, indicator_label3 — 将鼠标悬停在曲线或指标标签上以及数据窗口中时, 这些属性的值将显示在工具提示中。我们称呼它们为 "osc", "buy" 和 "sell"。
应用通用振荡器。将 iUniOsc 指标的所有外部参数插入新指标。属性窗口中不需要 ColorLine1, ColorLine2 和 ColorHisto 参数。我们将它们隐藏。Type 参数含有 UniOsc/UniOscDefines.mqh 文件中描述的自定义 OscUni_RSI 类型。我们要包含这个文件。默认情况下, Type 参数值设置为 OscUni_ATR — ATR 指标。但 ATR 不依赖于价格走势的方向, 这意味着它不适合定义背离。所以, 设置 OscUni_RSI — RSI 指标 — 作为默认:
#include <UniOsc/UniOscDefines.mqh> input EOscUniType Type = OscUni_RSI; input int Period1 = 14; input int Period2 = 14; input int Period3 = 14; input ENUM_MA_METHOD MaMethod = MODE_EMA; input ENUM_APPLIED_PRICE Price = PRICE_CLOSE; input ENUM_APPLIED_VOLUME Volume = VOLUME_TICK; input ENUM_STO_PRICE StPrice = STO_LOWHIGH; color ColorLine1 = clrLightSeaGreen; color ColorLine2 = clrRed; color ColorHisto = clrGray;
将通用振荡器的句柄声明在外部变量下方:
int h;
在 OnInit() 函数的开头下载通用振荡器:
h=iCustom(Symbol(),Period(),"iUniOsc", Type, Period1, Period2, Period3, MaMethod, Price, Volume, StPrice, ColorLine1, ColorLine2, ColorHisto); if(h==INVALID_HANDLE){ Alert("不能加载指标"); return(INIT_FAILED); }
在 OnCalculate() 函数中, 将通用振荡器的数据复制到 buf_osc 缓冲区:
int cnt; if(prev_calculated==0){ cnt=rates_total; } else{ cnt=rates_total-prev_calculated+1; } if(CopyBuffer(h,0,0,cnt,buf_osc)<=0){ return(0); }
在这个阶段, 我们可通过将 iDivergence 指标挂载到图表来验证所执行操作的正确性。如果一切正常, 您可以在子窗口中看到振荡器的曲线。
定义振荡器极值。我们已经研究过三种定义极值的方法。我们将它们包括在指标中, 并提供选择其中任何一个的可能性 (外部变量带有一个下拉列表)。在 Include 文件夹中, 我们创建了 UniDiver 文件夹, 所有代码所需的其它文件将位于其中。创建 UniDiver/UniDiverDefines.mqh 包含文件并在其中编写 EExtrType 枚举:
enum EExtrType{ ExtrBars, ExtrThreshold, ExtrMiddle };
枚举选项:
ExtrBars — 利用柱线。
ExtrThreshold — 利用自最后一个高/低价位的阈值超越;
ExtrMiddle — 指标最大值或最小值是否高于或低于其中线。
在指标中, 创建 ExtremumType 外部参数并将其插入所有其它外部参数之上。当利用柱线定义极值时, 我们将需要两个参数 — 极值左侧和右侧的柱线数量, 而在利用阈值定义时, 我们需要用于计算阈值的参数:
input EExtrType ExtremumType = ExtrBars; // 极值类型 input int LeftBars = 2; // ExtrBars 左侧柱线数量 input int RightBars = -1; // ExtrBars 右侧柱线数量 input double MinMaxThreshold = 5; // ExtrThreshold 的阀值
我们来实现使用一个参数 RightBars 或 LeftBars, 以及同时使用两个参数的可能性。RightBars 默认等于 -1。这意味着不会用到这个值, 第二个参数的值降会分配给它。
极值定义类。在指标工作期间不需要改变极值定义方法, 因此使用 OOP 而不是 'if' 和 'switch' 操作符是更合理的。创建基类并派生三个定义极值方法的类。在启动指标时选择其中一个派生类。这些类将用于定义极值, 并执行所有必要的操作来发现背离。它们在定义极值的方式上是不同的, 而在所有情况下, 趋合的定义完全相同。因此, 背离定义函数位于基类中, 并从派生类中调用。但首先, 我们需要提供对所有指标极值的便捷访问 (就像在 "沃尔夫波浪" 一文中之字折线做到的那样)。
SExtremum 结构用于存储一个极值的的有关数据。结构描述位于 UniDiverDefines:
struct SExtremum{ int SignalBar; int ExtremumBar; datetime ExtremumTime; double IndicatorValue; double PriceValue; };