1. iMFI関数の概要と実務での活用法
iMFI関数は、マネーフローインデックス(Money Flow Index)のインジケーターハンドルを作成するための関数です。MFIは「ボリューム(出来高)を考慮したRSI」と表現されることが多く、価格の変化だけでなく、そこにどれだけの資金が流入したかを数値化します。
実務での活用ポイント:
MFIは0〜100の間を推移し、一般的に「80以上は買われすぎ」「20以下は売られすぎ」と判断します。RSIとの最大の違いは、価格が上昇していても出来高が伴っていない場合に数値が伸び悩む点です。これにより、価格だけの上昇(ダマシ)を見抜きやすくなります。
開発者がつまずきやすい点:
MQL4から移行した開発者が最も戸惑うのが、「関数を呼んですぐに値が返ってくるわけではない」という点です。iMFIはあくまで計算用の「ハンドル(識別番号)」を返すだけなので、実際の値を取得するには別途CopyBuffer関数を使う必要があります。また、FXにおいては「真の出来高(取引金額)」ではなく「ティック出来高(価格更新回数)」を用いるため、株式市場のMFIとは性質が若干異なることを理解しておくことが重要です。
2. 構文と戻り値
iMFI関数の構文は以下の通りです。
int iMFI(
string symbol, // 通貨ペア(銘柄)名
ENUM_TIMEFRAMES period, // 時間軸
int ma_period, // 平均化期間(通常は14)
ENUM_APPLIED_VOLUME applied_volume // 使用する出来高の種類
);
パラメーター解説
- symbol: 対象となる銘柄を指定します。現在のチャートなら
_Symbolを指定します。 - period: 時間軸を指定します。現在のチャートなら
_Periodを指定します。 - ma_period: MFIを計算する期間です。一般的には「14」が標準的です。
- applied_volume: FXの場合は
VOLUME_TICK(ティック回数)を指定するのが一般的です。取引所取引(株や先物)の場合はVOLUME_REALを使用することもあります。
戻り値
- 成功した場合:インジケーターのハンドル(int型の整数)を返します。
- 失敗した場合:
INVALID_HANDLEを返します。
3. 具体的な使い方・実践サンプルコード
以下は、MFIが20以下で「買い」、80以上で「売り」のシグナルを出すシンプルなEAのスケルトンコードです。
//+------------------------------------------------------------------+
//| MFI_Sample_EA.mq5 |
//+------------------------------------------------------------------+
#property strict
// 入力パラメーター
input int InpMFIPeriod = 14; // MFIの期間
input double InpUpperLevel = 80.0; // 売り基準
input double InpLowerLevel = 20.0; // 買い基準
// グローバル変数
int handleMFI; // MFIのハンドルを格納する変数
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// MFIハンドルの作成(OnInitで一度だけ行うのが鉄則)
handleMFI = iMFI(_Symbol, _Period, InpMFIPeriod, VOLUME_TICK);
// ハンドル作成失敗時のエラーチェック
if(handleMFI == INVALID_HANDLE)
{
Print("MFIハンドルの作成に失敗しました。");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double mfiValues[]; // 値を格納する動的配列
ArraySetAsSeries(mfiValues, true); // 最新のデータを[0]にする設定
// ハンドルを使って最新のMFI値を配列にコピー(最新2個分)
if(CopyBuffer(handleMFI, 0, 0, 2, mfiValues) < 2)
{
Print("データのコピーに失敗しました。");
return;
}
double currentMFI = mfiValues[0]; // 最新のMFI値
// ログ出力(確認用)
Comment("現在のMFI: ", DoubleToString(currentMFI, 2));
// 実践的なエントリーロジックの例
if(currentMFI >= InpUpperLevel)
{
// ここに売り注文のロジックを記述
Print("【売りシグナル】MFIが上限に達しました。");
}
else if(currentMFI <= InpLowerLevel)
{
// ここに買い注文のロジックを記述
Print("【買いシグナル】MFIが下限に達しました。");
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// メモリ解放のためにハンドルを削除
IndicatorRelease(handleMFI);
}
4. 使用上の注意点とよくあるエラー
-
ハンドル作成はOnInitで行うこと
OnTick内でiMFIを毎回呼び出すのは厳禁です。PCのリソースを著しく消費し、ターミナルの動作が重くなる原因となります。 -
CopyBufferの戻り値チェック
チャートが読み込まれた直後などは、計算に必要なバー数が足りずCopyBufferが失敗することがあります。必ず戻り値を確認し、データが取得できた場合のみロジックを動かすようにしてください。 -
配列の時系列設定
ArraySetAsSeries(array, true)を忘れると、array[0]が「最も古いデータ」になってしまいます。最新のMFI値を取得したい場合は、必ずこの設定を行うか、インデックスの計算に注意してください。 -
ボリュームの選択ミス
FX会社によってはVOLUME_REALにデータが入っていない(0になる)場合があります。その場合、MFIの値も常に0や計算不能な値になるため、自身の利用する環境のデータ形式を確認してください。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムトレーダーとして成功するためには、ロジックの優位性と同じくらい「実行環境」が重要です。自宅のPCや一般的なインターネット回線でEAを稼働させることは、プロの視点からは推奨されません。なぜなら、自宅環境ではプロバイダー経由のネットワーク遅延(レイテンシ)が大きく、エントリーボタンが押されてからブローカーのサーバーに注文が届くまでに致命的なタイムラグが生じるからです。
特にMFIのようなオシレーターを用いた短期〜中期のトレードでは、数ミリ秒の遅延が約定価格を滑らせ(スリッページ)、本来利益が出るはずの局面を損失に変えてしまうことが多々あります。約定スピードを極限まで高め、物理的な距離によるロスを最小限に抑えるには、ブローカーのサーバーに近いデータセンターに設置された「専用VPS」の導入が必須です。安定した電源、24時間の稼働保証、そして超低遅延なネットワーク環境があって初めて、あなたの書いたアルゴリズムは真価を発揮します。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント