首页 技术指标 帖子

理想ZigZag指标:MetaTrader 4交易者的秘密武器

附件
10671.zip (2.71 KB, 下载 0次)



优点:

  • 最复杂的功能是iBarShift,完全取代了代码中用于峰值获取的所有周期。
  • 构建每根蜡烛的ZigZag所需的所有信息不仅可以在每个时刻获取,还可以在每个外部代码中访问。
  • 没有悬挂峰值
  • 提供高效的峰值查找方法
  • 非常快速
  • 在历史插入和切换时间框架时表现良好。
  • 非常适合在EA中使用。


缺点:

1. 内存需求。这个指标使用了5个缓冲区,而其他类似实现通常只用2个(甚至1个)。不过(在我看来),这是对第6和第7个优点的良好交换。没有我见过的快速ZigZag能够在不完全重建的情况下处理历史插入,而我的指标可以做到。而且效率很高。

2. 额外的线条可供使用。这是为了使数据对任何外部代码可见,但这些线条不应被显示。


原理:

ZigZag是通过通道原理绘制的。

通道宽度可以用点(XLab_ZZ)或百分比(XLab_ZZP)来定义。


峰值获取:

extern int ChannelWidth = 100;

#property indicator_chart_window
#property indicator_buffers 1

#property indicator_color1 Red
#property indicator_width1 3

datetime LastTime;

int init()
{
   LastTime = 0;
  
   return(0);
}

bool GetValue(double dir, int bar, int prevBar, double& peak, int& peakBar, datetime& peakTime)
{
   if (dir < 0)
   {
      datetime t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 2, bar);
      int i = iBarShift(Symbol(), 0, t);

      if (i == prevBar)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 2, bar + 1);
         i = iBarShift(Symbol(), 0, t);
      }

      double v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 1, i);
      
      if (v == EMPTY_VALUE)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 2, bar + 1);
         i = iBarShift(Symbol(), 0, t);
         v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 1, i);
      }
      peak = v;
      peakBar = i;
      peakTime = t;
   }
   else if (dir > 0)
   {
      t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 3, bar);
      i = iBarShift(Symbol(), 0, t);

      if (i == prevBar)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 3, bar + 1);
         i = iBarShift(Symbol(), 0, t);
      }

      v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 0, i);
      
      if (v == EMPTY_VALUE)
      {
         t = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 3, bar + 1);
         i = iBarShift(Symbol(), 0, t);
         v = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 0, i);
      }
      peak = v;
      peakBar = i;
      peakTime = t;
   }
   else 
   {
      return (false);
   }
   
   return (true);
}

int start()
{
   if (LastTime == Time[0]) return (0);
   LastTime = Time[0];
   
   double dir = iCustom(Symbol(), 0, "XLab_ZZ", ChannelWidth, 4, 1);
   double rdir = -dir;

   if (dir == EMPTY_VALUE) return (0);
   
   double v1, v2, v3, v4, v5;
   int    i1, i2, i3, i4, i5;
   datetime t1, t2, t3, t4, t5;
   
   GetValue(dir, 1, 0, v1, i1, t1);
   GetValue(rdir, i1, 0, v2, i2, t2);
   GetValue(dir, i2, i1, v3, i3, t3);
   GetValue(rdir, i3, i2, v4, i4, t4);
   GetValue(dir, i4, i3, v5, i5, t5);

   SetPt("1", v1, t1);
   SetPt("2", v2, t2);
   SetPt("3", v3, t3);
   SetPt("4", v4, t4);
   SetPt("5", v5, t5);
   
   Print(v1, "   ", v2, "  ", v3, "  ", v4, " ", v5, " ", i1, "  ", i2, "  ", i3, " ", i4, " ", i5);

   return(0);
}

void SetPt(string name, double price, datetime time)
{
   ObjectCreate(name, OBJ_ARROW, 0, time, price);
   ObjectSet(name, OBJPROP_ARROWCODE, 108);
   ObjectSet(name, OBJPROP_PRICE1, price);
   ObjectSet(name, OBJPROP_TIME1, time);
}

这个示例是一个指标,用于标记每根蜡烛的前五个峰值(包括当前形成的峰值)。

注意!如果启用了0th Bar模式,此代码可能会出现不正确的情况。


0th Bar模式:

通过DrawZeroBar变量设置,默认关闭。

不建议使用此选项,特别是在指标用于EA时。


享受使用它吧 ;) 有任何问题请随时问我。

如果发现任何错误,请向我报告。谢谢。

相关帖子

评论 (0)