MT4のiFractals()でフラクタルを取得しようとして、
直近の足を指定しているのにいつも0が返ってくる、という経験をした人は多いはずです。
これはバグではなく、フラクタルという指標そのものの仕組みによる、正しい挙動です。
フラクタルは「ある足の高値(または安値)が、その前後2本ずつ、合計5本の中で一番高い(安い)」という条件で決まります。
つまり、直近の1〜2本は「まだ後ろに2本の確定足がない」状態のため、
仕組み上どうやってもフラクタルにはなり得ません。
この記事では、iFractals()の書式と、
この「直近2本は必ず0」という設計上の制約を理解したうえで、
確定したフラクタルだけを矢印表示するインジケーターを、
実際に動くコードとあわせて解説します。
iFractals関数の書式
double iFractals( string symbol, //通貨ペア(NULLで現在のチャート) int timeframe, //時間足(0で現在のチャートの時間足) int mode, //MODE_UPPER(上のフラクタル)またはMODE_LOWER(下のフラクタル) int shift //何本前の足を見るか );
戻り値は、指定したshiftの足がフラクタルであればその高値(または安値)、
フラクタルでなければ0.0です。
modeには、上側のフラクタル(高値側)を見るMODE_UPPERと、
下側のフラクタル(安値側)を見るMODE_LOWERの2種類があります。
なぜ直近2本は必ず0が返るのか
フラクタルの判定条件を、shiftを基準にした前後関係で書き直すと、次のようになります。
//shift番目の足が「上のフラクタル」である条件(概念上のイメージ) high[shift] は high[shift+2], high[shift+1], high[shift-1], high[shift-2] より高い
ここでshift-1・shift-2は「対象の足より新しい(未来側の)足」を指します。
shift=0(現在形成中の足)を指定した場合、
shift-1・shift-2はまだ存在しない未来の足になってしまうため、
判定自体が成立せず、必ず0.0が返ります。
shift=1を指定した場合も同様に、shift-2にあたる足がまだ確定していないため、
同じ理由で0.0が返ります。
フラクタルとして値が返り始めるのは、最短でもshift=2以降です。
これはMT4標準のフラクタルインジケーター自体が持つ性質で、
リペイントとは違う「後出しでしか確定できない」指標だという理解が、
EAへ組み込む際の前提になります。
確定フラクタルだけを矢印表示するコード全体
shift=2以降だけをループして判定することで、
まだ確定していないフラクタルを誤って矢印表示しない、
実際にMetaEditorでコンパイルできるインジケーターです。
//+------------------------------------------------------------------+
//| FractalsConfirmedArrow.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Lime
#property indicator_color2 Red
input int ArrowGap = 5;//高値・安値から矢印を離すpoint数
double UpFractal[];
double DownFractal[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0,UpFractal);
SetIndexStyle(0,DRAW_ARROW,STYLE_SOLID,1);
SetIndexArrow(0,217);
SetIndexEmptyValue(0,EMPTY_VALUE);
SetIndexBuffer(1,DownFractal);
SetIndexStyle(1,DRAW_ARROW,STYLE_SOLID,1);
SetIndexArrow(1,218);
SetIndexEmptyValue(1,EMPTY_VALUE);
IndicatorShortName("Fractals Confirmed Arrow");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
if(rates_total < 5)
return(0);
int limit;
if(prev_calculated==0)
limit = rates_total-3;
else
{
limit = rates_total-prev_calculated+1;
if(limit > rates_total-3)
limit = rates_total-3;
}
//shift=0,1は仕組み上フラクタルになり得ないため、i>=2までしかループしない
for(int i=limit;i>=2;i--)
{
UpFractal[i]=EMPTY_VALUE;
DownFractal[i]=EMPTY_VALUE;
double up = iFractals(NULL,0,MODE_UPPER,i);
if(up != 0.0)
UpFractal[i]=up+ArrowGap*Point;
double down = iFractals(NULL,0,MODE_LOWER,i);
if(down != 0.0)
DownFractal[i]=down-ArrowGap*Point;
}
return(rates_total);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MT4のMetaEditorで「ファイル」→「新規作成」→「カスタムインディケータ」を選ぶ
- 「FractalsConfirmedArrow」という名前で作成し、テンプレートの中身をすべて削除してコード全体を貼り付ける
- F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- チャートへ適用し、MT4標準のフラクタルインジケーターも同時に表示する
- 標準フラクタルの矢印位置と、このインジケーターの矢印位置が一致することを目視で確認する
EAに組み込むときに気をつけること
フラクタルを反転エントリーの根拠としてEAに組み込む場合、
判定に使うshiftを安易に0や1にしないでください。
shift=2(直近の確定フラクタル)を使うということは、そのフラクタルが確定した時点で、
実際にはすでに2本分の値動きが過ぎたあとだということです。
「フラクタルで反転を検知してすぐエントリー」という発想自体が、
この2本分の遅れを前提にしないと成立しません。
高値・安値からすでに離れた位置でエントリーすることになるため、
損切り幅の設計にもこの遅れを織り込む必要があります。
矢印が出ない・想定と違う位置に出るとき
- 出ない: 直近2本(
shift=0・shift=1)を見ていないか。仕組み上この2本は常に0.0が返るため矢印は出ない(バグではない) - 標準のフラクタルと位置がずれる: このインジケーターの
ArrowGapの値や、標準インジケーター側の表示パラメーターを確認する。判定条件自体はMT4標準と同じロジックを使っている - 矢印が少なすぎる/多すぎると感じる: フラクタルは「前後2本より高い(安い)」という比較的緩い条件のため、レンジ相場では頻発しやすい。単体で売買判断せず、他の環境認識指標と組み合わせる
【MQL4】直近2本は必ず0が返る|iFractals関数で「確定した」フラクタルだけを検出する:まとめ
iFractals()は、対象の足の前後2本ずつ、
計5本の関係でフラクタルを判定する関数のため、
直近の1〜2本は仕組み上どうやっても0.0しか返りません。
この制約はバグではなく設計そのものであり、
shift=2以降だけをループして確定済みのフラクタルだけを扱うようにすれば、
意図しない挙動を避けられます。
EAに組み込む際は、この「2本分の遅れ」を損切り幅の設計にも織り込んでください。
コメント