
利点
- 最も高価な機能であるiBarShiftが、ピークの取得に必要なコード全体を完全に置き換えます。
- ZZを各バーごとに構築するために必要なすべての情報が、常にアクセス可能です。
- サスペンドされたピークがありません。
- 効率的なピーク検出方法が利用可能です。
- 非常に高速です。
- ヒストリーの挿入時やTFを切り替える際も正しく動作します。
- EAでの使用に最適です。
欠点
1. メモリ要件。このインジケーターは他の類似実装の2(または1)ではなく5つのバッファを使用します。しかし、私見では、利点#6と#7に対する良い価格だと思います。私が見た高速ZigZagでは、ヒストリーの挿入をフルリビルドなしで処理できるものはありません。私のものはそれを効率的に行います。
2. 追加のラインが必要です。これは外部コードにデータを表示するために必要です。これらのラインは決して表示されるべきではありません。
原理:
ZZはチャンネリング原理によって描画されます。
チャンネル幅はポイント(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); }
この例は、現在形成中の最初の5つのピークを(バーごとに1回)マークするインジケーターです。
注意!このコードは0番バーのモードがオンになっていると正しく動作しない場合があります。
0番バーのモード:
DrawZeroBar変数で設定されます。デフォルトではオフです。
特にこのインジケーターがEAで使用される場合は、このオプションを使用しないことをお勧めします。
お楽しみください ;) 何か質問があればお気軽に聞いてください。
バグが見つかった場合は、報告してください。ありがとうございます。