1. ArrayFree関数の概要と実務での活用法
MQL5におけるArrayFree関数は、動的配列(Dynamic Array)に割り当てられたメモリを解放し、配列のサイズを0にリセットするための関数です。
実務開発において、EA(エキスパートアドバイザー)やインジケーターは数日間、あるいは数ヶ月間連続して稼働し続けます。この際、計算のために巨大な価格データやティックデータを動的配列に格納し、使い終わった後もそのままにしておくと、MT5が使用するメモリ容量が肥大化し続けます(メモリリークに近い状態)。
特に初心者がつまずきやすいのは、「配列を上書きすれば大丈夫」という思い込みです。サイズを大きくし続ける処理だけを記述し、不要になったタイミングでArrayFreeによるメモリ解放を行わないと、PCやサーバーの動作が徐々に重くなり、最悪の場合はプラットフォームがクラッシュして機会損失を招く恐れがあります。
プロのクオンツ現場では、ループ処理内や特定のイベント(OnDeinitなど)で、使い終わったリソースを明示的に解放し、実行環境をクリーンに保つのが鉄則です。
2. 構文と戻り値
ArrayFreeの構文は非常にシンプルです。
構文
void ArrayFree(
void& array[] // 解放したい動的配列
);
パラメーター
- array[]: メモリを解放したい動的配列を指定します。型(int, double, 構造体など)は問いません。
戻り値
- なし(void)。
この関数を実行すると、対象の配列は「要素数0」の状態に戻ります。また、その配列が確保していたメモリ領域がOSに返却されます。
3. 具体的な使い方・実践サンプルコード
以下は、特定の条件で過去の注文チケット一覧を取得し、処理が終わった後にArrayFreeでメモリをリセットする実践的なEAのコード例です。
//+------------------------------------------------------------------+
//| SampleArrayFree.mq5 |
//+------------------------------------------------------------------+
#property strict
//--- グローバル変数としての動的配列
ulong g_tickets[];
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// 1. 配列に現在の保有ポジションのチケット番号を格納する
int total = PositionsTotal();
// 配列のサイズを現在のポジション数に変更
if(ArrayResize(g_tickets, total) < 0)
{
Print("配列のリサイズに失敗しました。");
return;
}
// 2. 配列にデータを流し込む
for(int i = 0; i < total; i++)
{
g_tickets[i] = PositionGetTicket(i);
}
// --- ここでチケット番号を使った何らかのロジックを実行 ---
if(ArraySize(g_tickets) > 0)
{
Print("現在 " + (string)ArraySize(g_tickets) + " 個のポジションを監視中です。");
}
// 3. 【重要】処理の最後、または特定の条件でメモリを解放する
// 今回の例では毎ティックのリセットは不要かもしれませんが、
// 大規模なデータ分析を行う際は、計算が終わるごとに解放するのがベストプラクティスです。
if(total == 0)
{
ArrayFree(g_tickets);
Print("ポジションがゼロになったため、配列メモリを解放しました。");
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// EA終了時には必ずメモリを解放して、MT5の負荷を下げます
ArrayFree(g_tickets);
Print("EA終了につき、動的配列をクリーンアップしました。");
}
4. 使用上の注意点とよくあるエラー
① 静的配列には使用できない
double my_array[10]; のように、宣言時にサイズが決まっている静的配列に対してArrayFreeを呼び出すと、コンパイルエラーまたは実行時エラーが発生します。ArrayFreeはあくまで動的配列(ArrayResizeが必要な配列)専用です。
② 解放後のアクセスに注意
ArrayFreeを実行した直後の配列は、サイズが「0」になっています。この状態で g_tickets[0] のように要素へアクセスしようとすると、「array out of range(配列の範囲外アクセス)」エラーが発生し、EAが停止してしまいます。再度使用する場合は、必ずArrayResizeでサイズを再設定してください。
③ ArrayResize(arr, 0) との違い
ArrayResize(arr, 0) も配列サイズを0にしますが、ArrayFreeはより明示的に「メモリの解放」を意図した関数です。MQL5の内部実装では、ArrayFreeの方がより確実にバッファをクリアし、メモリ消費を抑える効果が期待できます。
5. 【重要】自動売買における約定スピードと環境の罠
アルゴリズムの効率化のためにArrayFreeでメモリ管理を徹底することは、ソフトウェアエンジニアとして素晴らしい姿勢です。しかし、どれほどコードを最適化して0.001秒の計算短縮を実現したとしても、実行環境が「自宅のPC」であれば、その努力は水の泡になる可能性が高いのが現実です。
FXの自動売買において、最も大きなボトルネックとなるのは「ネットワーク遅延(レイテンシ)」です。自宅のインターネット回線経由では、ブローカーのサーバーに注文が届くまでに数十〜数百ミリ秒の遅延が発生します。このわずかな遅延の間に価格が動き、不利な価格での約定(スリッページ)が起きることで、バックテスト通りの利益が出ない「環境の罠」に陥ります。
極限まで約定スピードを高め、ロジックの優位性を守るためには、ブローカーの取引サーバーに物理的に近いデータセンターに設置された「FX専用VPS」の導入が不可欠です。低レイテンシな環境でEAを稼働させることは、高度なコードを書くこと以上に、プロのトレーダーが真っ先に投資すべき必須条件と言えます。
💡 この記事の内容を実運用で活かすには?
この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント