
优点:
- 最复杂的功能是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时。
享受使用它吧 ;) 有任何问题请随时问我。
如果发现任何错误,请向我报告。谢谢。