「直近20本の中で一番高い値段を知りたい」と思ってiHighest()を使ってみたら、
返ってきた数値が価格として見るとおかしい(1や5のような小さい整数しか出てこない)——という戸惑いはないでしょうか。
実はiHighest()・iLowest()が返すのは価格そのものではなく、
「その最高値・最安値がついた足が、何本前にあるか」を表すインデックス(シフト)です。
実際の価格を知るには、このインデックスをもう一度iHigh()・iLow()に渡す、
という2段階の手順が必要になります。
この記事では、iHighest()・iLowest()の戻り値がインデックスである理由と、
実際の価格を取り出す手順、
そしてhl-line.md(前日の高値・安値表示)では扱わなかった「直近N本」という任意の期間内で高値・安値を探す方法を、
実際に動くコードで解説します。
iHighest・iLowestの書式
int iHighest( string symbol, //通貨ペア(NULLで現在の通貨ペア) int timeframe, //時間足(0で現在の時間足) int type, //探す対象(MODE_HIGH=高値、MODE_LOW=安値、MODE_CLOSEなど) int count=WHOLE_ARRAY, //何本前まで遡って探すか(既定値は全履歴) int start=0 //探索を始める足(0=最新の確定していない足を含む) ); int iLowest( string symbol, int timeframe, int type, int count=WHOLE_ARRAY, int start=0 );
typeには価格の種類を指定します。
高値を探すのが目的でも、
MODE_HIGH以外にMODE_CLOSE(終値ベースで最大値を探す)なども指定でき、
「ヒゲを含めた高値」と「実体(終値)ベースの高値」のどちらを探すかを使い分けられます。
戻り値は「価格」ではなく「インデックス」
iHighest()・iLowest()の戻り値は、
count本の範囲の中で最も条件に合う値を持つ足の、
startからの相対的なインデックス(シフト)です。
価格そのものではありません。
//誤解: これで「直近20本の最高値」が取れると思ってしまう
int highestValue = iHighest(Symbol(), 0, MODE_HIGH, 20, 0);
Print("最高値=", highestValue); //実際には「0〜19本」のインデックス(例: 3)が出るだけ
実際の高値を得るには、返ってきたインデックスをもう一度iHigh()に渡す必要があります。
//正しい: インデックスを使ってiHigh()で実際の価格を取得する
int shift = iHighest(Symbol(), 0, MODE_HIGH, 20, 0);
double highestPrice = iHigh(Symbol(), 0, shift);
Print("直近20本の最高値=", highestPrice, "(", shift, "本前)");
iLowest()も同様に、
返ってきたインデックスをiLow()に渡して初めて実際の安値が得られます。
hl-line.mdとの違い: 「前日」固定ではなく「直近N本」を自由に探せる
既存記事の前日の高値・安値を表示するインジケーターは、
iHigh(Symbol(), PERIOD_D1, 1)のように「1日足の1本前(=前日)」というインデックスをあらかじめ固定して高値・安値を取得していました。
これは「探す」のではなく「決まった位置の値をそのまま読む」処理です。
一方iHighest()・iLowest()は、
countで指定した本数の範囲全体を検索し、条件に合う足を「探し出す」処理です。
「直近5本の中で一番高い値」「直近100本の中で一番安い値」のように、
範囲を自由に変えられる点が、固定インデックスを読むだけのhl-line.mdとの違いです。
直近スイング高値・安値を使ったブレイクアウト判定や、
トレーリングストップの基準値を作る場面でよく使われます。
実際に動くコード全体
直近N本(input変数で指定)の中の最高値・最安値と、それぞれ何本前かを表示する、
実際にMetaEditorでコンパイルできるスクリプトです。
//+------------------------------------------------------------------+
//| HighestLowestDemo.mq4 |
//| Copyright 2026, FX-EA System Project Creator |
//| https://creator.fx-ea-system-project.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, FX-EA System Project Creator"
#property link "https://creator.fx-ea-system-project.com/"
#property version "1.00"
#property strict
#property script_show_inputs
input int RangeBars = 20;//直近何本の中から探すか
void OnStart()
{
if(RangeBars <= 0)
{
Print("RangeBarsは1以上を指定してください。");
return;
}
//直近RangeBars本の中で最も高い足のインデックスを探す(start=0なので最新足も含む)
int highestShift = iHighest(Symbol(), 0, MODE_HIGH, RangeBars, 0);
//直近RangeBars本の中で最も安い足のインデックスを探す
int lowestShift = iLowest(Symbol(), 0, MODE_LOW, RangeBars, 0);
if(highestShift < 0 || lowestShift < 0)
{
Print("iHighest/iLowestが失敗しました。エラーコード=", GetLastError());
return;
}
//インデックスをiHigh()/iLow()に渡して実際の価格を取得する
double highestPrice = iHigh(Symbol(), 0, highestShift);
double lowestPrice = iLow(Symbol(), 0, lowestShift);
PrintFormat("直近%d本: 最高値=%.5f(%d本前) / 最安値=%.5f(%d本前) / 値幅=%.5f",
RangeBars, highestPrice, highestShift,
lowestPrice, lowestShift,
highestPrice - lowestPrice);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MT4のMetaEditorで「ファイル」→「新規作成」→「スクリプト」を選び、名前を「HighestLowestDemo」にして作成する
- テンプレートの中身を全て削除し、上のコードを丸ごと貼り付ける
- F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- 任意のチャートへドラッグ&ドロップし、RangeBarsの値を入力欄で確認・変更して実行する
- 「エキスパート」タブに最高値・最安値と、それぞれ何本前かが表示されることを確認する
コピペしてコンパイルが通らない・値がおかしいときに確認すること
iHighest()・iLowest()の戻り値をそのまま価格として使っていないか(必ずiHigh()・iLow()へインデックスとして渡す)count(この記事のRangeBars)を大きくしすぎて、実際のヒストリーデータの本数を超えていないか(超えた分は取得可能な範囲までしか検索されない)- 戻り値が
-1になる場合、指定した通貨ペア・時間足のヒストリーデータがまだダウンロードされていない可能性がある typeにMODE_HIGHとMODE_LOWを取り違えていないか(高値を探すつもりでMODE_LOWを指定すると、意図と逆の値になる)
【MQL4】iHighest・iLowestが返すのは価格じゃない?直近N本の高値・安値を『インデックス』で取得する関数の使い方:まとめ
iHighest()・iLowest()は、直近N本の範囲から最も高い/安い足を検索し、
その足の「インデックス(何本前か)」を返す関数です。
価格そのものが欲しい場合は、
返ってきたインデックスをiHigh()・iLow()にもう一度渡す2段階の手順が必要になります。
hl-line.mdのように決まった位置の値を読むだけでなく、
任意の範囲から高値・安値を「探す」処理が必要な場面(ブレイクアウト判定やトレーリングストップの基準値作成など)で活用してください。
コメント