「直近20本の高値を探すなら`iHighest()`を使えばいい」
と知っていても、`ArrayMaximum()`はいつ使う関数なのか、
ピンとこないことはないでしょうか。
実はこの2つ、「配列から最大値・最小値の位置(インデックス)を探す」
という見た目はよく似ていますが、対象にできる配列の種類が全く違います。
`iHighest()`・`iLowest()`が使えるのは、
価格や出来高などの決まった時系列配列だけで、
自分で計算して作った配列には使えません。
この記事では、`ArrayMaximum()`・`ArrayMinimum()`の、
使い方と`iHighest()`・`iLowest()`との役割分担を、
実際に動くコードで解説します。
・ArrayMaximum()/ArrayMinimum()の引数と戻り値
・iHighest()/iLowest()との対象範囲の違い
・自分で計算した配列から最大値を探す方法
・混同すると起きる事故パターン
ArrayMaximum・ArrayMinimumとは何か
まず、この2つの関数が何をする関数なのかを確認します。
配列の中から最大値・最小値のインデックスを探す関数
`ArrayMaximum()`は、指定した配列の中で最も大きい値が入っている、
「位置(インデックス)」を返す関数です。
`ArrayMinimum()`は同じ仕組みで、最も小さい値の位置を返します。
戻り値はインデックス、値そのものではない
ここが`iHighest()`・`iLowest()`と共通して誤解しやすい点です。
戻り値は「値そのもの」ではなく「何番目の要素か」というインデックスです。
実際の値を知るには、返ってきたインデックスで配列にもう一度アクセスする必要があります。
失敗すると-1を返す
配列が空、または指定した範囲が不正な場合、
`ArrayMaximum()`・`ArrayMinimum()`は`-1`を返します。
戻り値をそのまま配列の添字として使うと、存在しない`-1`番目を読みにいってしまうため、
必ずチェックが必要です。
iHighest・iLowestと何が違うのか(ここが最大の注意点)
似た機能を持つ2つの関数ですが、対象にできる配列の種類が全く異なります。
iHighest・iLowestは時系列配列(価格・出来高)専用
`iHighest()`・`iLowest()`は、MT4が内部で管理している、
価格(High/Low/Close等)や出来高といった、
決まった時系列データしか対象にできません。
通貨ペア・時間足・対象の種類(`MODE_HIGH`等)を指定して呼び出す専用関数です。
ArrayMaximum・ArrayMinimumは任意の配列に使える汎用関数
一方`ArrayMaximum()`・`ArrayMinimum()`は、
自分で`double`型の配列を用意して好きな値を入れれば、
その配列からそのまま最大値・最小値を探せます。
「自分で計算した値」
「インジケーターバッファの一部」など、どんな配列にも使える汎用関数です。
混同すると起きる具体的な事故パターン
・ArrayMaximum()に時系列配列を渡しても動くが向きの前提が違う
・iHighest()には自作の配列を渡せずコンパイルエラーになる
・『高値を探したい』だけで関数名を決めず対象配列を先に確認する
関数のシグネチャと引数の見方
次に、具体的な書式を確認します。
ArrayMaximum/ArrayMinimumの書式
int ArrayMaximum( const void& array[], //対象の配列 int count=WHOLE_ARRAY, //検索する要素数(既定値は配列全体) int start=0 //検索を始める位置 ); int ArrayMinimum( const void& array[], int count=WHOLE_ARRAY, int start=0 );
戻り値はint型で、見つかった要素のインデックスです。
失敗した場合は`-1`を返します。
count/startのデフォルト値と意味
`count`を省略すると配列全体が検索対象になり、
`start`を省略すると配列の先頭(添字0)から検索します。
一部の区間だけを検索したい場合は、`start`で開始位置、
`count`で検索する個数を指定します。
時系列配列で使う場合はArraySetAsSeriesの向きに注意
`ArraySetAsSeries(true)`を設定した配列は、
添字0が「最新」を指す向きに反転しています。
`ArrayMaximum()`はこの向きを意識せずそのまま探すため、
「何日前が最大か」を知りたい場合は、向きを自分で理解したうえで計算する必要があります。
自分で計算した配列から最大値を探すサンプルコード
直近20日の値幅(High-Low)を自分で計算して配列に入れ、
最も値幅が大きかった日を`ArrayMaximum()`で探すスクリプトです。
//+------------------------------------------------------------------+
//| DailyRangeMaxFinder.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property strict
#property show_inputs
input int InpDays = 20; //調べる日数
void OnStart()
{
double rangeArray[];
ArrayResize(rangeArray, InpDays);
for(int i = 0; i < InpDays; i++)
{
double dayHigh = iHigh(_Symbol, PERIOD_D1, i);
double dayLow = iLow(_Symbol, PERIOD_D1, i);
rangeArray[i] = dayHigh - dayLow;
}
int maxIdx = ArrayMaximum(rangeArray);
int minIdx = ArrayMinimum(rangeArray);
if(maxIdx < 0 || minIdx < 0)
{
Print("配列が空のため検索に失敗しました");
return;
}
Print(InpDays, "日前までで最も値幅が大きかったのは",
maxIdx, "日前、値幅=", rangeArray[maxIdx] / _Point, "point");
Print(InpDays, "日前までで最も値幅が小さかったのは",
minIdx, "日前、値幅=", rangeArray[minIdx] / _Point, "point");
}
`rangeArray`は自分で計算して入れた値幅のデータであり、
MT4が管理する時系列データそのものではありません。
このような自作配列には`iHighest()`は使えず、
`ArrayMaximum()`だけが使えます。
MetaEditorでのコンパイル・実行手順
- MetaEditorで新規スクリプト「DailyRangeMaxFinder」を作成し、上のコードを貼り付けてコンパイルする
- 任意の通貨ペアのチャートにドラッグ&ドロップで実行する
- 「エキスパート」タブで、最も値幅が大きかった日・小さかった日が表示されることを確認する
- `InpDays`の値を変えて、集計期間が変わることを確認する
よくあるエラーと注意点
実際に使う前に確認しておきたい注意点をまとめます。
配列が空(サイズ0)のまま渡すと-1が返る
・ArrayResize()を呼び忘れた配列はサイズ0のままです
・サイズ0の配列を渡すとArrayMaximum()は-1を返します
・戻り値を必ずチェックしてから配列にアクセスしてください
時系列方向(ArraySetAsSeries)を間違えると違う位置を指す
`ArraySetAsSeries(true)`にした配列と、
通常の(添字0が先頭の)配列では、
同じ`ArrayMaximum()`の戻り値でも「何日前か」
の意味が逆になります。
自分がどちらの向きで配列を作ったかを、コメントで残しておくと安全です。
よくある質問
ArrayMaximum・ArrayMinimumについて、
よく検索される疑問に回答します。
iHighest()で十分な場面でもArrayMaximum()を使ってよいですか?
使えますが、価格データそのものを調べるだけなら`iHighest()`の方がシンプルです。
`ArrayMaximum()`が本当に役立つのは、
自分で計算した値(値幅・インジケーターの差分等)を検索したい場面です。
同じ値が複数ある場合、どちらのインデックスが返りますか?
公式リファレンスには優先順位の明記がないため、
同値が複数ある状況を前提にしたロジックは組まないことをおすすめします。
必要な場合は自分でループして明示的に判定してください。
MQL5でも同じ関数が使えますか?
はい、MQL5にも同名の、
`ArrayMaximum()`・`ArrayMinimum()`があり、
配列を対象にする考え方は共通しています。
MQL5では引数の型がテンプレート化されている点が、MQL4との細かな違いです。
【MQL4】ArrayMaximum・ArrayMinimumでiHighest・iLowestと何が違うのかを解説してみた:まとめ
ArrayMaximum()・ArrayMinimumは、
iHighest()・iLowest()と見た目は似ていますが、
対象にできる配列の種類が異なります。
価格や出来高そのものを調べるならiHighest()・iLowest()、
自分で計算した値を調べるならArrayMaximum()・ArrayMinimum()、
という役割分担で覚えておくと混同しにくくなります。
コメント