量化交易软件下载: 赫兹量化NRTR 指标和交易模块
基于 NRTR 指标的交易系统属于突破策略。当价格超过某个周期的前一高点时, 会产生一个买入信号; 当价格跌至前一低点时产生卖出信号。在趋势变化期间, 这种系统也许会使用前一趋势的高点和低点。为了避免这种情况, 计算周期在我们的系统中会动态设置。
作者已经将 NRTR 定义为 动态价格通道突破的趋势指标。
指标操作原则如下: 在上升趋势中, 指标线 (通道) 处于指定时间段内检测到的高位之下的某个价位。下降趋势线处于价格之上, 与某个时间段内的价格低点处于恒定的距离。
用于指标计算的价格通道周期从趋势起点开始动态增加。因此, 前一个计算周期的价格不会影响指标。
从图例中可以看出, 指标首先以的一定距离跟随趋势。指标位于距本地高点 H1 和 H2 固定的距离。本地高点 H3 低于前一个, 则不用于计算。
然后价格在 L3 点突破了通道。这是一个卖出信号。L3 点的值被设置为新的低点。新周期从这一点开始, 即之前的所有价格均被重置, 不再用于将来的计算。随着趋势的发展, 最低值更新为 L3-L4-L5。动态价格通道的周期将延长, 直到趋势发生变化或周期长度达到所允许的最大值。
通道宽度按极值的百分比计算, 或是依据价格波动。这两种方法在本文中均已实现。
买入/卖出信号在价格突破通道边界线时产生。买入信号在价格突破支撑线时形成。如果突破了阻力线, 则形成卖出信号。
现在, 我们需要将指标操作原则的描述转换为 MQL5。我们这就开始。
编写指标: 从简单到复杂
首先, 我们需要定义指标的行为。指标将基于收盘价。基于历史数据的指标值被明确解释。但若是价格突破不完整烛条的支撑/阻力线会怎样呢?在这个版本中, 趋势没有形成, 因此在烛条完整成形之前不会产生信号。一方面, 我们可能会错过走势的一部分。例如, 如果走势开始于一根巨大烛条突破通道, 只有在下一根烛条开盘时才会开仓。另一方面, 这是防止大量假突破所做的保护。
注意: 指标有许多变体, 本文只针对作者提出的原始版本进行描述。
该指标的实现可在代码库找到, 但其周期只是部分为动态的。当趋势发生变化时, 这个周期会被重新设定, 但在理论上可以无止境地延伸。即, 支撑线以前值的 MathMax() 和当前收盘价计算。在这种情况下, 支撑线只能上升, 而阻力线总是下降。在原始版本中, 所有较早的数值均被认定过时, 从而被忽略。此处的最大值/最小值计算为 ArrayMaximum/Minimum(close,i,dynamic_period)。在这种方式下, 支撑线和阻力线都会上涨和下跌。因此, 在动态周期较短的情况下, 支撑线可能在一些舒缓的区间震荡走势情况下深度下移。但是这种平滑的长期趋势很罕见, 两种方法都不是很理想。在本文中, 我们坚持指标作者最初提出的想法。
下一次滞留与时间序列有关。MQL5 中的价格系列 (收盘) 默认值为 ArraySetAsSeries = false。MQL4 中的价格系列带有一个时间序列标志, 它们的 Close[0] 值是最右边柱线的收盘价 (此刻最左边的柱线按规定是不可见的)。请注意, 在本文中 ArraySetAsSeries(close,true)。
现在我们继续实现这个指标。我们将处理四个指标缓冲区: 其中两个用于支撑/阻力线, 另外两个用于买入和卖出信号。
#property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 //指标线条样式 #property indicator_type1 DRAW_LINE #property indicator_color1 Green #property indicator_style1 STYLE_DASH #property indicator_type2 DRAW_LINE #property indicator_color2 Red #property indicator_style2 STYLE_DASH #property indicator_type3 DRAW_ARROW #property indicator_color3 Green #property indicator_type4 DRAW_ARROW #property indicator_color4 Red
我们来声明指标缓冲区和指标的外部参数
input int period =12; //动态周期 input double percent =0.2; //缩进百分比 double Buff_Up[],Buff_Dn[]; double Sign_Up[],Sign_Dn[];
指标信号将在图表上显示为箭头。其余参数在 OnInit() 函数中设置。我的 DRAW_ARROW 参数来自 Wingdings 字符集, 编号为 236, 238。"向上" 信号的参数:
SetIndexBuffer(2,Sign_Up,INDICATOR_DATA); PlotIndexSetDouble(2,PLOT_EMPTY_VALUE,0.0); PlotIndexSetInteger(2,PLOT_ARROW,236); PlotIndexSetInteger(2,PLOT_LINE_WIDTH,1); ArraySetAsSeries(Sign_Up,true);
在 OnCalculate() 中开始计算时, 我们检查所需数据的可用性以及指标是否首次开始计算。
//+------------------------------------------------------------------+ //| 自定义指标迭代函数 | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { int start =0; //计算的起始点 int trend =0; //趋势值, 0 向上 -1 向下 static int trend_prev =0; double value =0; //指标值 static double value_prev =0; int dyn_period =1; //动态周期值 static int curr_period =1; double maxmin =0; //用于计算的技术变量 ArraySetAsSeries(close,true); if(rates_total<period) return(0); if(prev_calculated==0) // 检查指标计算的首次开始 { start=rates_total-1; // 所有柱线的起始计算索引 trend_prev =1; value=close[start]*(1-0.01*percent); } else { start=rates_total-prev_calculated; // 新柱线的起始计算索引 } trend =trend_prev; value =value_prev; dyn_period =curr_period;