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本より高い(安い)」という比較的緩い条件のため、レンジ相場では頻発しやすい。単体で売買判断せず、他の環境認識指標と組み合わせる
まとめ
`iFractals()`は、対象の足の前後2本ずつ、計5本の関係でフラクタルを判定する関数のため、直近の1〜2本は仕組み上どうやっても`0.0`しか返りません。
この制約はバグではなく設計そのものであり、`shift=2`以降だけをループして確定済みのフラクタルだけを扱うようにすれば、意図しない挙動を避けられます。EAに組み込む際は、この「2本分の遅れ」を損切り幅の設計にも織り込んでください。
コメント