1. FrameFilter関数の概要と実務での活用法
MQL5におけるFrameFilterは、ストラテジーテスターを用いた最適化(最適化)中に、特定のデータ「フレーム」を抽出・選別するための関数です。
MQL5には、最適化の計算を複数のCPUコアや外部のエージェントに分散させ、その結果をリアルタイムで収集する「フレーム」という仕組みがあります。実務での開発、特に数千・数万通りのパラメータを検証する際、すべての結果を無差別に受け取ると処理が追いつかず、ターミナルの動作が重くなる原因になります。
そこでFrameFilterの出番です。この関数を使うことで、「特定の名称が付いたデータ」や「特定のIDを持つ結果」だけにフォーカスして読み取ることが可能になります。例えば、最適化の中で「特定のドローダウン許容範囲内のデータのみを抽出してグラフ化したい」といった高度な分析を行う際に、フィルタリングの役割を果たします。
初心者が特につまずきやすいのは、この関数を「いつ・どこで」使うかという点です。FrameFilterは、バックテスト終了時に呼ばれるOnTesterPassイベント内で使用されるのが一般的であり、通常のトレードロジック内(OnTickなど)では機能しないことを理解しておく必要があります。
2. 構文と戻り値
FrameFilterの構文は非常にシンプルです。
bool FrameFilter(
string name, // フレーム名
long id // フレームID
);
パラメーター
- name: フィルタリングしたいフレームの名前を指定します。
FrameAdd関数でデータを送る際に設定した文字列と同じものを指定します。 - id: フレームの識別番号(ID)を指定します。特定の番号を指定する以外に、グループ化されたデータを一括で扱う際にも利用されます。
戻り値
- 成功した場合:
true - 失敗した場合:
false(エラーコードを確認するにはGetLastError()を呼び出します)
この関数を呼び出すと、内部的な読み取りポインタがリセットされ、指定した条件に合致するデータのみがFrameNext関数で読み込める状態になります。
3. 具体的な使い方・実践サンプルコード
以下は、最適化中に特定の計算結果(ここでは利益とドローダウン)をフレームとして送信し、それをOnTesterPassでフィルタリングして取得する実用的なコード例です。
//+------------------------------------------------------------------+
//| FrameFilter_Example |
//+------------------------------------------------------------------+
#property strict
// 最適化中にデータを送信する
double OnTester()
{
double profit = TesterStatistics(STAT_PROFIT);
double dd = TesterStatistics(STAT_EQUITY_DDREL_PERCENT);
// "MyResults" という名前で、IDを101としてデータをフレームに追加
double data[2];
data[0] = profit;
data[1] = dd;
if(!FrameAdd("MyResults", 101, 0, data))
{
Print("フレーム追加失敗: ", GetLastError());
}
return(profit);
}
// フレームが送信されてくるたびにターミナル側で実行される
void OnTesterPass()
{
string name = "";
long id = 0;
double value = 0;
double data[];
// 1. "MyResults" という名前のフレームだけを抽出するようにフィルタリング
if(!FrameFilter("MyResults", 101))
{
Print("フィルタリング失敗: ", GetLastError());
return;
}
// 2. フィルタリングされたフレームを順番に読み込む
while(FrameNext(name, id, value, data))
{
// ここでフィルタリングされたデータを処理
PrintFormat("受信データ: 名前=%s, ID=%d, 利益=%.2f, ドローダウン=%.2f%%",
name, id, data[0], data[1]);
}
}
このコードでは、FrameFilterによって「MyResults」かつ「ID 101」のデータだけがFrameNextのループ対象となるため、他の無関係なフレームデータが混ざることを防いでいます。
4. 使用上の注意点とよくあるエラー
-
呼び出し場所に注意:
FrameFilterは原則としてOnTesterPassイベントハンドラ内で使用します。通常のEA実行中やバックテスト中に呼び出しても意味がありません。 -
フィルタの重複に注意:
FrameFilterを一度呼び出すと、その条件で抽出が固定されます。別の条件でデータを取得したい場合は、再度FrameFilterを呼び出して条件を上書きする必要があります。 -
大文字・小文字の区別:
フレーム名(name)は文字列として扱われます。FrameAddで指定した名前と完全に一致(大文字・小文字含む)させる必要があるため、定数(#define)として定義しておくのが安全です。 -
空文字の指定:
FrameFilter(NULL, id)のように名前をNULLや空文字にすると、名前に関わらず指定したIDを持つすべてのフレームが対象となります。逆にIDを無視したい場合は、フレーム設計の段階でルールを決めておく必要があります。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムトレードにおいて、どれほど優れたロジックをFrameFilterなどの関数を駆使して開発したとしても、それを実行する「環境」が劣悪であればすべては水の泡となります。特に、日本の自宅PCから海外のブローカーサーバーへ接続して自動売買を行う場合、物理的な距離に起因するネットワーク遅延(レイテンシ)は避けられません。
この数ミリ秒から数百ミリ秒の遅延は、ボラティリティが高い相場局面において「注文した価格と実際に約定した価格の差(スリッページ)」として顕著に現れます。プロのクオンツの世界では、このコンマ数秒の遅延が月間の収益率を数%単位で悪化させることは常識です。極限まで約定スピードを高め、ロジック通りのパフォーマンスを発揮させるためには、ブローカーのデータセンターに近い場所に位置する「専用のVPS(仮想専用サーバー)」の導入が不可欠です。安定した電源と高速なバックボーン回線を備えたVPS環境こそが、自動売買エンジニアが最初に投資すべき最も重要なインフラと言えるでしょう。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント