MetaTrader5
フィボナッチ・ジグザグ:MetaTrader 5向けインジケーターの設定ガイド
セットアップ 必要なもの: 1つのジグザグプロット 高値と安値のためのデータバッファ2つ 入力パラメータ インジケーターが再計算されるたびにリセットされるシステム変数のセット 次に、コードの基本部分を見てみましょう: #property indicator_buffers 2
#property indicator_plots 1
input double retracement=23.6; // リトレースメントの割合
input double minSizeInAtrUnits=0.0; // ATR単位での波の最小サイズ
input int rollingAtrPeriod=14; // ローリングATR期間
input color Color=clrDodgerBlue; // 波の色
input int Width=3; // 波の幅
input ENUM_LINE_STYLE Style=STYLE_SOLID; // 波のスタイル
//--- アップウェーブとダウンウェーブの配列
double upWaves[], dwWaves[]; upWaves配列は高値を、dwWaves配列は安値を格納します。 システム変数について: 最後の波のタイプ、開始位置、終了位置、開始と終了からのバーの距離を把握する必要があります。 さらに、局所的な高値と低値の変数、各ポイントからのバーの距離も必要です。 //--- ジグザグの追跡
int wave_type=0; // 波のタイプ [0] なし [1] 上昇 [2] 下降
double wave_start_price=0.0; // 波の開始価格
double wave_end_price=0.0; // 波の終了価格
int wave_start_distance=0; // 開始価格からのバーの距離
int wave_end_distance=0; // 終了価格からのバーの距離
//--- 高値の追跡
double high_mem=0.0;
int distance_from_high=0;
//--- 低値の追跡
double low_mem=0.0;
int distance_from_low=0;
//--- ローリングATR
double rollingAtr=0.0;
int rollingAtrs=0; これでローリングATRの単位と計算された数値が準備できました。 次に、システムリセット関数を作成します: void resetSystem() {
ArrayFill(upWaves, 0, ArraySize(upWaves), 0.0);
ArrayFill(dwWaves, 0, ArraySize(dwWaves), 0.0);
wave_type=0;
wavestart_price=0.0;
wavend_price=0.0;
wavestart_distance=0;
wavend_distance=0;
high_mem=0.0;
low_mem=0.0;
distance_from_high=0;
distance_from_low=0;
rollingAtr=0.0;
rollingAtrs=0;
} 標準的な処理で、配列をゼロで埋め、システム変数をリセットします。 OnInitでは、バッファを設定し、プロットを作成し、初めてリセットを呼び出します: SetIndexBuffer(0, upWaves, INDICATOR_DATA);
SetIndexBuffer(1, dwWaves, INDICATOR_DATA);
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_ZIGZAG);
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, Color);
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, Width);
PlotIndexSetInteger(0, PLOT_LINE_STYLE, Style);
resetSystem(); では、計算に進みましょう。 最初に処理するのはローリングATRです。このATR期間を超えるバーが集まるまで、他のことは何もしません。 ローリングATRを管理する部分は次の通りです: 期間を超えるまで、見つかったバーの範囲を合計に追加し続ける 期間に到達したら、最初の割り算(平均)を行う その後、ローリングATRから古い部分をクリップし、新しい部分を追加します //--- ATRを管理する
rollingAtrs++;
if(rollingAtrs > rollingAtrPeriod) {
double new_portion = ((high[i] - low[i]) / _Point) / ((double)rollingAtrPeriod);
//--- 古い部分を削除し、新しい部分を追加
rollingAtr = (rollingAtr) - (rollingAtr / ((double)rollingAtrPeriod)) + new_portion;
}
else if(rollingAtrs high_mem && low[i] >= low_mem) {
double new_wave_size_in_atr_units = ((high[i] - low_mem) / _Point) / rollingAtr;
//--- 新しい波のサイズが有効であれば
if(new_wave_size_in_atr_units >= minSizeInAtrUnits) {
//--- 新しいアップウェーブを開始
wave_type = 1;
wave_start_price = low_mem;
wave_start_distance = distance_from_low;
wave_end_price = high[i];
wave_end_distance = 0;
dwWaves[i - wave_start_distance] = low_mem;
upWaves[i] = high[i];
high_mem = high[i];
distance_from_high = 0;
low_mem = low[i];
distance_from_low = 0;
}
}
//--- 安値を下回り、高値は超えない場合
else if(low[i] < low_mem && high[i] = minSizeInAtrUnits) {
//--- 新しいダウンウェーブを開始
wave_type = -1;
wave_start_price = high_mem;
wave_start_distance = distance_from_high;
wave_end_price = low[i];
wave_end_distance = 0;
upWaves[i - wave_start_distance] = high_mem;
dwWaves[i] = low[i];
high_mem = high[i];
distance_from_high = 0;
low_mem = low[i];
distance_from_low = 0;
}
}
//--- 両方を超えた場合
else if(low[i] < low_mem && high[i] > high_mem) {
high_mem = high[i];
low_mem = low[i];
distance_from_high = 0;
distance_from_low = 0;
}
} 素晴らしい!最後の部分です。 アップウェーブの場合: 新しい高値が作成されると、前の高値から新しい高値の位置にジグザグを移動します。この際、バーの距離を保持しているので可能です。また、安値と安値からの距離を更新します。これにより、ピークからの最安値をキャッチし、その後に十分にリトレースするか確認します。 新しい安値が作成された場合、または新しい安値が設定された場合、ピークから安値までの距離を計算し、波のサイズで割ります。そして、入力パラメータのスケールに合わせるために100を掛けます。もし波のサイズが100ポイント、リトレースメントが24ポイントであれば、24/100=0.24、次に×100=24%となります。新しい「仮想的な」波が以前のものをリトレースする際もATR単位に対して有効であれば新しいダウンウェーブを開始し、局所的な高値と安値を設定し、バーの距離を設定します。 関連するコードは以下の通りです: //--- アップウェーブがある場合
if(wave_type == 1) {
//--- 波が上に拡大した場合
if(high[i] > wave_end_price) {
//--- 配列位置から前の終了価格を削除(0.0=空)
upWaves[i - wave_end_distance] = 0.0;
//--- 新しい位置に配置
upWaves[i] = high[i];
wave_end_price = high[i];
wave_end_distance = 0;
high_mem = high[i];
distance_from_high = 0;
low_mem = low[i];
distance_from_low = 0;
}
//--- リトレースメントを確認
if(low[i] < low_mem || distance_from_low == 0) {
low_mem = low[i];
distance_from_low = 0;
double size_of_wave = (wave_end_price - wave_start_price) / _Point;
double size_of_retracement = (wave_end_price - low_mem) / _Point;
if(size_of_wave > 0.0) {
double retraced = (size_of_retracement / size_of_wave) * 100.0;
double new_wave_size_in_atr_units = ((wave_end_price - low_mem) / _Point) / rollingAtr;
//--- 新しい波のサイズが有効であれば
if(new_wave_size_in_atr_units >= minSizeInAtrUnits) {
//--- リトレースメントが重要であれば、新しいダウンウェーブを開始
if(retraced >= retracement) {
wave_type = -1;
wave_start_price = high[i - distance_from_high];
wave_start_distance = distance_from_high;
wave_end_price = low[i];
wave_end_distance = 0;
upWaves[i - wave_start_distance] = high_mem;
dwWaves[i] = low[i];
high_mem = high[i];
distance_from_high = 0;
low_mem = low[i];
distance_from_low = 0;
}
}
}
}
} ダウンウェーブの場合も同様の処理を行います。 これで、リトレースメントジグザグが完成しました! こちらが23.6%のリトレースメントとATR単位での最小波サイズ0.0のジグザグです: そして、こちらがATR単位での最小波サイズ3の同じジグザグです: これで、素晴らしいトレーディングを楽しんでください!
2025.03.03