
MQL4 配列関数を体系的にまとめました。ArrayResize()による動的配列のサイズ変更、ArrayCopy()による配列コピー、ArraySort()によるソート、ArrayMaximum()・ArrayMinimum()による最大値・最小値のインデックス検索、ArrayInitialize()による初期化、ArrayRange()・ArraySize()によるサイズ取得、ArraySetAsSeries()による時系列インデックス設定まで、MT4 EA開発に必要な配列操作のすべてをコード付きで解説します。

MQL4とMQL5の配列関数の違い
| 機能 | MQL4 | MQL5 |
|---|---|---|
| 基本関数 | ほぼ同じ | ほぼ同じ |
| ArraySort | 第2-4引数あり(count, start, direction) | 引数は配列のみ(昇順固定) |
| ArrayMaximum/Minimum | start, count引数あり | start, count引数あり |
| ArrayCopy | 同じ | 同じ |
| 時系列配列 | Close[], Open[], High[], Low[] | CopyClose()等で取得 |
MQL4の配列は静的配列(サイズ固定)と動的配列(サイズ可変)の2種類があります。double arr[100];は静的、double arr[];は動的です。動的配列はArrayResize()でサイズを変更でき、EA開発では動的配列の使用が一般的です。
MQL4の配列は静的配列(サイズ固定)と動的配列(サイズ可変)の2種類があります。double arr[100];は静的、double arr[];は動的です。動的配列はArrayResize()でサイズを変更でき、EA開発では動的配列の使用が一般的です。
ArrayResize:動的配列のサイズ変更
int ArrayResize(
void& array[], // 対象配列
int new_size, // 新しいサイズ
int reserve_size = 0 // 予約サイズ(パフォーマンス用)
);
// 戻り値: 新しいサイズ、失敗時は-1void DynamicArrayExample()
{
double prices[];
// サイズ0の状態から動的に拡張
ArrayResize(prices, 0);
// データを追加
for(int i = 0; i < 10; i++)
{
int newSize = ArraySize(prices) + 1;
ArrayResize(prices, newSize);
prices[newSize - 1] = Close[i];
}
Print("配列サイズ:", ArraySize(prices));
Print("最初の要素:", prices[0]);
Print("最後の要素:", prices[ArraySize(prices) - 1]);
}
// 予約サイズを使った効率的な拡張
void EfficientResize()
{
double data[];
ArrayResize(data, 0, 1000); // 1000要素分のメモリを予約
// 追加時にメモリ再割り当てが発生しにくい
for(int i = 0; i < 500; i++)
{
ArrayResize(data, i + 1);
data[i] = MathRand();
}
}ArrayCopy:配列コピー
int ArrayCopy(
void& dst_array[], // コピー先
void src_array[], // コピー元
int dst_start = 0, // コピー先の開始位置
int src_start = 0, // コピー元の開始位置
int count = WHOLE_ARRAY // コピーする要素数
);
// 戻り値: コピーした要素数void CopyExample()
{
double source[] = {1.0, 2.0, 3.0, 4.0, 5.0};
double dest[];
// 全要素コピー
ArrayResize(dest, ArraySize(source));
ArrayCopy(dest, source);
// 部分コピー(3番目から2要素)
double partial[];
ArrayResize(partial, 2);
ArrayCopy(partial, source, 0, 2, 2); // source[2], source[3]をコピー
// partial = {3.0, 4.0}
// 終値の直近20本をコピー
double recentClose[];
ArrayResize(recentClose, 20);
ArrayCopy(recentClose, Close, 0, 0, 20);
}ArraySort:ソート
bool ArraySort(
void& array[], // 対象配列
int count = WHOLE_ARRAY, // ソートする要素数
int start = 0, // 開始位置
int direction = MODE_ASCEND // MODE_ASCEND(昇順) / MODE_DESCEND(降順)
);void SortExample()
{
double values[] = {5.0, 2.0, 8.0, 1.0, 9.0, 3.0};
// 昇順ソート
ArraySort(values);
// values = {1.0, 2.0, 3.0, 5.0, 8.0, 9.0}
// 降順ソート
ArraySort(values, WHOLE_ARRAY, 0, MODE_DESCEND);
// values = {9.0, 8.0, 5.0, 3.0, 2.0, 1.0}
}
// 直近N本の高値・安値の中央値を計算
double MedianPrice(int bars)
{
double highs[];
ArrayResize(highs, bars);
for(int i = 0; i < bars; i++)
highs[i] = High[i + 1]; // 確定バーから
ArraySort(highs);
if(bars % 2 == 0)
return (highs[bars/2 - 1] + highs[bars/2]) / 2.0;
else
return highs[bars/2];
}ArrayMaximum / ArrayMinimum
int ArrayMaximum(
void array[], // 対象配列
int count = WHOLE_ARRAY, // 検索する要素数
int start = 0 // 開始位置
);
// 戻り値: 最大値のインデックス
int ArrayMinimum(
void array[],
int count = WHOLE_ARRAY,
int start = 0
);
// 戻り値: 最小値のインデックスvoid FindHighLow(int bars)
{
// 直近N本の最高値・最安値
int highIdx = iHighest(NULL, 0, MODE_HIGH, bars, 1);
int lowIdx = iLowest(NULL, 0, MODE_LOW, bars, 1);
Print("直近", bars,"本の最高値:", High[highIdx]," (", highIdx,"本前)");
Print("直近", bars,"本の最安値:", Low[lowIdx]," (", lowIdx,"本前)");
// 配列版
double myData[] = {10.5, 20.3, 5.8, 15.2, 30.1};
int maxIdx = ArrayMaximum(myData);
int minIdx = ArrayMinimum(myData);
Print("最大値:", myData[maxIdx]," at index", maxIdx);
Print("最小値:", myData[minIdx]," at index", minIdx);
}配列関数のArrayMaximum/ArrayMinimumとは別に、チャートの価格データを直接検索するiHighest() / iLowest()関数もあります。
int iHighest(string symbol, int timeframe, int type, int count, int start); int iLowest(string symbol, int timeframe, int type, int count, int start); // type: MODE_HIGH, MODE_LOW, MODE_OPEN, MODE_CLOSE, MODE_VOLUME
直近20本の最高値のバーインデックスを取得する場合: int idx = iHighest(NULL, 0, MODE_HIGH, 20, 1);
配列関数のArrayMaximum/ArrayMinimumとは別に、チャートの価格データを直接検索するiHighest() / iLowest()関数もあります。
int idx = iHighest(NULL, 0, MODE_HIGH, 20, 1); … 直近20本の最高値のバーインデックスを取得
ArrayInitialize:配列の初期化
int ArrayInitialize(
double& array[], // 対象配列
double value // 初期値
);
// 全要素を指定値で初期化。戻り値: 初期化した要素数void InitExample()
{
double buffer[100];
// 全要素を0.0に初期化
ArrayInitialize(buffer, 0.0);
// 全要素をEMPTY_VALUE(空値)に初期化
ArrayInitialize(buffer, EMPTY_VALUE);
}ArraySetAsSeries:時系列インデックス
bool ArraySetAsSeries(
void& array[], // 対象配列
bool flag // true=時系列(最新=0), false=昇順(最古=0)
);void SeriesExample()
{
double data[];
ArrayResize(data, 5);
data[0] = 100; data[1] = 101; data[2] = 102; data[3] = 103; data[4] = 104;
// 昇順: data[0]=100(最古), data[4]=104(最新)
Print("昇順: [0]=", data[0]," [4]=", data[4]);
// 時系列に変更
ArraySetAsSeries(data, true);
// 時系列: data[0]=104(最新), data[4]=100(最古)
Print("時系列: [0]=", data[0]," [4]=", data[4]);
// Close[], High[]等は最初から時系列([0]=現在のバー)
Print("Close[0](現在)=", Close[0]);
Print("Close[1](1本前)=", Close[1]);
}- MQL4の定義済み配列(Close[], High[], Low[], Open[], Time[], Volume[])は最初から時系列([0]=現在のバー)
- 自分で作った配列にArraySetAsSeries(arr, true)を設定すると、インデックスの向きが反転する
- ArraySort()は時系列配列では正しくソートされない場合がある。ArraySetAsSeries(arr, false)にしてからソートする
- MQL5ではCopyBuffer()で取得した配列がデフォルトで時系列ではないため、移植時に注意
- MQL4の定義済み配列(Close[], High[], Low[], Open[], Time[], Volume[])は最初から時系列([0]=現在のバー)
- 自分で作った配列にArraySetAsSeries(arr, true)を設定すると、インデックスの向きが反転する
- ArraySort()は時系列配列では正しくソートされない場合がある。ArraySetAsSeries(arr, false)にしてからソートする
- MQL5ではCopyBuffer()で取得した配列がデフォルトで時系列ではないため、移植時に注意
その他の配列関数
| 関数 | 説明 |
|---|---|
| ArraySize(array) | 配列の全要素数 |
| ArrayRange(array, dimension) | 指定次元のサイズ |
| ArrayDimension(array) | 配列の次元数 |
| ArrayFree(array) | 動的配列のメモリ解放 |
| ArrayIsSeries(array) | 時系列配列かどうか |
| ArrayIsDynamic(array) | 動的配列かどうか |
| ArrayBsearch(array, value) | 二分探索(ソート済み配列用) |
配列関数一覧(MQL5対応表)
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| ArrayResize() | ArrayResize() | サイズ変更 |
| ArrayCopy() | ArrayCopy() | 配列コピー |
| ArraySort(arr, cnt, start, dir) | ArraySort(arr)(昇順のみ) | ソート |
| ArrayMaximum() | ArrayMaximum() | 最大値インデックス |
| ArrayMinimum() | ArrayMinimum() | 最小値インデックス |
| ArrayInitialize() | ArrayInitialize() | 全要素初期化 |
| ArraySetAsSeries() | ArraySetAsSeries() | 時系列設定 |
| ArraySize() | ArraySize() | 要素数取得 |
| ArrayRange() | ArrayRange() | 次元サイズ取得 |
| ArrayFree() | ArrayFree() | メモリ解放 |
| ArrayBsearch() | ArrayBsearch() | 二分探索 |
まとめ
MQL4の配列関数はMQL5とほぼ共通で、移植性が高いカテゴリです。実際に試したところ、ArraySetAsSeries()のフラグを変えずにCopyBuffer()と混在させると、インデックスの向きが逆になって値がずれました。押さえておきたいポイントは以下の通りです。
- 動的配列はArrayResize()でサイズ変更:reserve_sizeを使うと頻繁なリサイズが効率化される
- Close[], High[]等は時系列配列:[0]が最新バー、インデックスが増えると過去に遡る
- ArraySort()はMQL5では昇順のみ:MQL4のMODE_DESCENDはMQL5移植時に注意
- ArraySetAsSeries()でデフォルト配列を時系列に変換できるが、インデックスの向きに注意
次のステップとして、MQLリファレンス総合ガイドで他のカテゴリも学習しましょう。
MQL4配列関数 よくある質問
MQL4の配列操作の基本は?
ArraySize()でサイズ取得、ArrayResize()でリサイズ、ArrayCopy()でコピーが基本です。動的配列はArrayResize()で拡張でき、ArrayFree()で解放できます。ArraySetAsSeries()でインデックス方向を時系列(最新=0)に変更できます。
MQL4でインジケーターバッファを配列で受け取る方法は?
iMA()などのインジケーター関数は1値ずつ返します。複数の値を取得するにはCopyBuffer()は使えないため、ループでiMA(Symbol(),0,period,0,shift)を繰り返し呼び出して配列に格納します。MQL5ではCopyBuffer()で一括コピーが可能です。
ArraySetAsSeries()の使い方は?
ArraySetAsSeries(array, true)で配列を時系列(インデックス0=最新バー)に設定します。Close[]やHigh[]などの事前定義時系列配列はデフォルトで時系列です。インジケーターのバッファ配列はSetIndexBuffer()後にArraySetAsSeries()で方向を設定します。
MQL4でArrayMaximum()を使う方法は?
ArrayMaximum(array, start, count)で指定範囲の最大値インデックスを返します。実際の最大値を取得するにはarray[ArrayMaximum(array)]とします。配列が時系列の場合はインデックス方向に注意してください。ArrayMinimum()で最小値も同様に取得できます。
MQL4でArraySort()を使う方法は?
ArraySort(array, count, start, MODE_ASCEND/MODE_DESCEND)でソートします。第2引数にWHOLE_ARRAYを指定すると全要素をソート。時系列配列はArraySetAsSeries(array, false)で一旦普通の配列に戻してからソートしてください。
MQL4とMQL5の配列操作の主な違いは?
MQL5ではCopyRates()/CopyBuffer()で価格データやインジケーターデータを一括取得できます。ArrayPrint()で配列の内容をデバッグ出力する関数も追加されました。MQL4では1要素ずつ手動で取得・操作する方法が主流です。
MQL4リファレンス 関連記事
- MQL4 取引関数:OrderSend・OrderClose・ポジション管理
- MQL4 インジケーター関数:iMA・iRSI・iCustom
- MQL4 口座・マーケット情報:ロット計算
- MQL4 イベントハンドラ:OnInit・OnTick
- MQL4 エラーコード:リトライパターン
- MQL4 時間・日付関数:取引時間フィルター
- EA始め方ガイド:MT4へのEA設定手順
⚠ リスクに関する注意事項
本記事は情報提供を目的としており、特定の金融商品の売買を推奨するものではありません。FX取引はレバレッジ取引の特性上、預託した証拠金以上の損失が生じる可能性があります。取引の際は、ご自身の判断と責任において行ってください。詳しくは特定商取引法に基づく表記をご確認ください。






