「直近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);
  }
//+------------------------------------------------------------------+
Copy

MetaEditorで実際に動かす手順

  1. MT4のMetaEditorで「ファイル」→「新規作成」→「スクリプト」を選び、名前を「HighestLowestDemo」にして作成する
  2. テンプレートの中身を全て削除し、上のコードを丸ごと貼り付ける
  3. F7キーでコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
  4. 任意のチャートへドラッグ&ドロップし、RangeBarsの値を入力欄で確認・変更して実行する
  5. 「エキスパート」タブに最高値・最安値と、それぞれ何本前かが表示されることを確認する

コピペしてコンパイルが通らない・値がおかしいときに確認すること

  • `iHighest()`・`iLowest()`の戻り値をそのまま価格として使っていないか(必ず`iHigh()`・`iLow()`へインデックスとして渡す)
  • `count`(この記事の`RangeBars`)を大きくしすぎて、実際のヒストリーデータの本数を超えていないか(超えた分は取得可能な範囲までしか検索されない)
  • 戻り値が`-1`になる場合、指定した通貨ペア・時間足のヒストリーデータがまだダウンロードされていない可能性がある
  • `type`に`MODE_HIGH`と`MODE_LOW`を取り違えていないか(高値を探すつもりで`MODE_LOW`を指定すると、意図と逆の値になる)

まとめ

`iHighest()`・`iLowest()`は、直近N本の範囲から最も高い/安い足を検索し、

その足の「インデックス(何本前か)」を返す関数です。

価格そのものが欲しい場合は、返ってきたインデックスを`iHigh()`・`iLow()`にもう一度渡す2段階の手順が必要になります。

hl-line.mdのように決まった位置の値を読むだけでなく、

任意の範囲から高値・安値を「探す」処理が必要な場面(ブレイクアウト判定やトレーリングストップの基準値作成など)で活用してください。

関連記事