技術辞典

MQL5 CopyCloseとiCloseの違い|終値・高値・安値を取得する方法

EAファンクラブ

MQL5でEAの価格判定を作る時は、終値、高値、安値を正しく取得する必要があります。

CopyCloseは、指定した銘柄・時間足の終値を配列へ取得する関数です。一方、iClose、iHigh、iLowは、指定したshiftの終値・高値・安値を1つずつ取得する関数です。

EAが確定足の終値で判定したい、現在足の高値・安値を見たい、過去数本の終値を比較したい、CopyRatesと個別価格取得を使い分けたい、といった場合は、CopyClose、iClose、iHigh、iLowの違いを整理しておくことが重要です。

このページでは、MQL5のCopyClose、iClose、iHigh、iLowを使って、終値・高値・安値を取得する方法、shift 0とshift 1の違い、戻り値0の扱い、CopyRatesとの使い分けを整理します。

なお、このページはMQL5開発における技術確認を目的とした内容です。売買判断、推奨エントリー、推奨ロット、利益保証、損失回避保証を行うものではありません。

CopyCloseとは何か

CopyCloseは、指定した銘柄・時間足の終値データをdouble配列へコピーする関数です。

直近1本だけでなく、複数本の終値をまとめて取得したい場合に使いやすい関数です。

void PrintRecentCloseValues()
{
   double close_values[];
   ArraySetAsSeries(close_values, true);

   ResetLastError();

   int copied = CopyClose(_Symbol, PERIOD_CURRENT, 0, 3, close_values);

   if(copied != 3)
   {
      PrintFormat("[COPYCLOSE_NG] symbol=%s timeframe=%d requested=3 copied=%d last_error=%d",
                  _Symbol,
                  PERIOD_CURRENT,
                  copied,
                  GetLastError());
      return;
   }

   PrintFormat("[COPYCLOSE_OK] close0=%.5f close1=%.5f close2=%.5f",
               close_values[0],
               close_values[1],
               close_values[2]);
}

CopyCloseの戻り値は、実際にコピーできたデータ数です。必要本数を取得できていない場合は、その値を判定に使わないようにしてください。

iClose / iHigh / iLowとは何か

iClose、iHigh、iLowは、指定した銘柄・時間足・shiftの価格を1つ返す関数です。

iCloseは終値、iHighは高値、iLowは安値を取得します。

void PrintSingleBarPrices(const int shift)
{
   ResetLastError();

   double close_price = iClose(_Symbol, PERIOD_CURRENT, shift);
   double high_price  = iHigh(_Symbol, PERIOD_CURRENT, shift);
   double low_price   = iLow(_Symbol, PERIOD_CURRENT, shift);

   int last_error = GetLastError();

   PrintFormat("[SINGLE_BAR_PRICES] shift=%d close=%.5f high=%.5f low=%.5f last_error=%d",
               shift,
               close_price,
               high_price,
               low_price,
               last_error);
}

iClose、iHigh、iLowは書きやすい一方で、エラー時に0を返すため、価格が0だから正常とは限りません。対象銘柄・時間足のデータが準備できているか、GetLastErrorも合わせて確認してください。

CopyCloseとiCloseの違い

CopyCloseとiCloseは、どちらも終値を取得できますが、使いやすい場面が異なります。

関数取得方法向いている場面
CopyClose終値を配列へコピーする複数本の終値をまとめて取得したい場合
iClose指定shiftの終値を1つ返す1本分の終値だけを簡単に確認したい場合
CopyRatesOHLC、時刻、出来高、スプレッドをまとめて取得する同じバーの複数情報をまとめて扱いたい場合

終値だけを数本比較するならCopyCloseが使いやすく、1本の終値だけを簡単に確認するならiCloseでも十分です。時刻、高値、安値、終値を同じバーからまとめて確認したい場合はCopyRatesを使うと整理しやすくなります。

shift 0とshift 1を分ける

CopyCloseやiCloseでshift 0を指定すると、現在足の終値に相当する値を取得します。

現在足は形成中のため、tickごとに値が変わる可能性があります。確定足の終値を使いたい場合は、shift 1を基準にしてください。

shift意味EAでの注意点
0現在足形成中のバーです。終値・高値・安値が変わる場合があります。
11本前の確定足確定済みバーとして判定しやすくなります。
2以上さらに過去の足過去比較、クロス判定、レンジ確認に使います。

EAで確定足ベースの判定を行う場合は、価格取得だけでなく、CopyTimeやCopyRatesのバー時刻も同じshiftで揃えると確認しやすくなります。

確定足の終値を取得する例

確定足の終値だけを取得する場合は、CopyCloseでstart_pos 1を指定します。

bool GetConfirmedClose(double &confirmed_close)
{
   double close_values[];
   ArraySetAsSeries(close_values, true);

   ResetLastError();

   int copied = CopyClose(_Symbol, PERIOD_CURRENT, 1, 1, close_values);

   if(copied != 1)
   {
      PrintFormat("[CONFIRMED_CLOSE_NG] symbol=%s timeframe=%d copied=%d last_error=%d",
                  _Symbol,
                  PERIOD_CURRENT,
                  copied,
                  GetLastError());
      return false;
   }

   confirmed_close = close_values[0];

   PrintFormat("[CONFIRMED_CLOSE_OK] close=%.5f",
               confirmed_close);

   return true;
}

このように、戻り値copiedを確認してから値を使うと、履歴データ不足や取得失敗時の誤判定を避けやすくなります。

iCloseで確定足の終値を確認する例

1本前の確定足の終値だけを確認したい場合は、iCloseでも書けます。

bool GetConfirmedCloseByIClose(double &confirmed_close)
{
   ResetLastError();

   double value = iClose(_Symbol, PERIOD_CURRENT, 1);
   int error = GetLastError();

   if(value == 0.0 && error != 0)
   {
      PrintFormat("[ICLOSE_NG] symbol=%s timeframe=%d shift=1 value=%.5f last_error=%d",
                  _Symbol,
                  PERIOD_CURRENT,
                  value,
                  error);
      return false;
   }

   confirmed_close = value;

   PrintFormat("[ICLOSE_OK] shift=1 close=%.5f last_error=%d",
               confirmed_close,
               error);

   return true;
}

iCloseはシンプルですが、0を返す場合があります。通常のFXやCFDの価格で0が返る場合は、履歴未準備や取得エラーの可能性を疑ってください。

高値・安値を取得する

iHighとiLowを使うと、指定したバーの高値・安値を取得できます。

直近高値・直近安値の確認、ブレイク判定、レンジ判定、上位足フィルターなどで使います。

bool GetConfirmedHighLow(double &high_value,
                         double &low_value)
{
   ResetLastError();

   high_value = iHigh(_Symbol, PERIOD_CURRENT, 1);
   low_value  = iLow(_Symbol, PERIOD_CURRENT, 1);

   int error = GetLastError();

   if((high_value == 0.0 || low_value == 0.0) && error != 0)
   {
      PrintFormat("[IHIGH_ILOW_NG] symbol=%s timeframe=%d shift=1 high=%.5f low=%.5f last_error=%d",
                  _Symbol,
                  PERIOD_CURRENT,
                  high_value,
                  low_value,
                  error);
      return false;
   }

   PrintFormat("[IHIGH_ILOW_OK] shift=1 high=%.5f low=%.5f",
               high_value,
               low_value);

   return true;
}

高値・安値も、現在足と確定足を分けて確認してください。現在足の高値・安値は、足が確定するまで変化する可能性があります。

複数本の終値を比較する

終値の並びを確認したい場合は、CopyCloseで複数本をまとめて取得します。

例えば、直近3本の確定足終値を比較する場合は、start_pos 1から3本分を取得します。

bool GetLastThreeConfirmedCloses(double &c1,
                                 double &c2,
                                 double &c3)
{
   double closes[];
   ArraySetAsSeries(closes, true);

   ResetLastError();

   int copied = CopyClose(_Symbol, PERIOD_CURRENT, 1, 3, closes);

   if(copied != 3)
   {
      PrintFormat("[THREE_CLOSES_NG] requested=3 copied=%d last_error=%d",
                  copied,
                  GetLastError());
      return false;
   }

   c1 = closes[0];
   c2 = closes[1];
   c3 = closes[2];

   PrintFormat("[THREE_CLOSES_OK] c1=%.5f c2=%.5f c3=%.5f",
               c1,
               c2,
               c3);

   return true;
}

配列のどの要素がどのバーを指すかをログで確認してください。ArraySetAsSeriesを使う場合は、0番が直近側になる前提で扱います。

CopyHigh / CopyLowとの使い分け

高値や安値を複数本まとめて取得したい場合は、CopyHighやCopyLowを使えます。

iHigh、iLowは1本ずつ取得する関数です。直近20本の高値や安値をまとめて比較したい場合は、CopyHigh / CopyLowの方が整理しやすくなります。

目的使う関数理由
1本前の終値だけ確認したいiCloseシンプルに書けるため
複数本の終値を比較したいCopyClose配列でまとめて取得できるため
1本前の高値だけ確認したいiHigh指定shiftの高値を直接取れるため
複数本の高値を比較したいCopyHigh高値配列としてまとめて取得できるため
1本前の安値だけ確認したいiLow指定shiftの安値を直接取れるため
複数本の安値を比較したいCopyLow安値配列としてまとめて取得できるため
OHLCと時刻をまとめて確認したいCopyRates同じバーの情報をまとめて取得できるため

EAの処理を読みやすくするには、必要な情報量に応じて関数を使い分けることが重要です。

現在価格とバー価格を混同しない

iCloseやCopyCloseで取得するのは、バーの終値です。

現在のBidやAskを取得したい場合は、SymbolInfoDoubleやSymbolInfoTickを使います。現在価格とバー終値を混同すると、発注前チェックやエントリー判定がずれる場合があります。

取得したい値代表関数注意点
現在BidSymbolInfoDouble / SymbolInfoTick現在の気配値です。
現在AskSymbolInfoDouble / SymbolInfoTickBUY成行の価格確認で使います。
現在足の終値相当iClose shift 0 / CopyClose start_pos 0形成中バーのため変化します。
確定足の終値iClose shift 1 / CopyClose start_pos 1確定足ベースの判定に使います。
確定足の高値・安値iHigh / iLow shift 1確定済みのレンジやブレイク確認に使います。

エントリー条件で「終値が上抜けた」と判定する場合と、「現在価格が上抜けた」と判定する場合では、結果が変わります。仕様としてどちらを使うかを明確にしてください。

履歴データ不足を確認する

CopyCloseやiCloseで値が取れない場合は、対象銘柄・時間足の履歴データが不足している可能性があります。

EAをセットした直後、別時間足を初めて参照した時、ストラテジーテスター開始直後などは、データ準備が間に合っていない場合があります。

確認項目内容ログ例
CopyClose戻り値必要本数を取得できたかCOPYCLOSE_NG
iClose戻り値0が返っていないかICLOSE_NG
GetLastErrorエラー詳細last_error
Bars対象銘柄・時間足のバー数BARS_CHECK
SeriesInfoInteger時系列データの同期状態SERIES_SYNC_CHECK
再試行次tickやOnTimerで再確認するかHISTORY_WAIT

履歴データが準備できていない時は、値を使わず、次のtickまたはOnTimerで再確認する設計にしてください。

ログで確認したい項目

CopyClose、iClose、iHigh、iLowを使う処理では、symbol、timeframe、shift、戻り値、取得値、last_errorをログに残すと確認しやすくなります。

ログ名確認内容用途
COPYCLOSE_OKcopied、close値終値配列取得成功の確認
COPYCLOSE_NGrequested、copied、last_error履歴不足や取得失敗の確認
ICLOSE_OKshift、close、last_error単一終値取得の確認
ICLOSE_NGvalue=0、last_error取得失敗や履歴未準備の確認
IHIGH_ILOW_OKshift、高値、安値レンジ・ブレイク判定の確認
PRICE_SOURCE_CHECK現在価格かバー終値か判定基準の混同防止
HISTORY_WAIT履歴準備待ち初回起動や別時間足参照時の確認

通常運用では、価格取得ログを毎tick出しすぎるとExpertsログが膨らみます。デバッグ時、NG時、新バー時、検証モード時に絞ると確認しやすくなります。

ログ出力例

[COPYCLOSE_OK] symbol=GOLD timeframe=15 start_pos=1 count=3 copied=3 c1=2351.80 c2=2349.40 c3=2348.10
[ICLOSE_OK] symbol=GOLD timeframe=15 shift=1 close=2351.80 last_error=0
[IHIGH_ILOW_OK] symbol=GOLD timeframe=15 shift=1 high=2353.20 low=2348.90
[PRICE_SOURCE_CHECK] source=confirmed_bar_close shift=1 value=2351.80
[COPYCLOSE_NG] symbol=GOLD timeframe=240 requested=10 copied=-1 last_error=4401
[ICLOSE_NG] symbol=GOLD timeframe=240 shift=1 value=0.00000 last_error=4401
[HISTORY_WAIT] symbol=GOLD timeframe=240 reason=not_enough_bars

ログ例の銘柄、価格、時間足、エラー番号は確認用です。実際の値は、銘柄、口座、ヒストリカルデータ、テスター条件によって変わります。

よくある失敗パターン

失敗パターン問題点確認方法
shift 0を確定足として使う現在足の変化する終値で判定してしまう確定足ならshift 1を使う
CopyClose戻り値を確認しない取得失敗時の値を使う可能性があるcopiedが必要本数と一致するか確認する
iCloseの0を正常値として扱う履歴不足や取得エラーを見逃すGetLastErrorも確認する
高値・安値と終値のshiftがずれる同じバーの情報として比較できないiHigh、iLow、iCloseのshiftを揃える
現在価格とバー終値を混同する発注前価格と判定価格がずれるSymbolInfo系とCopyClose系を分ける
別時間足の履歴不足を考慮しないMTF判定で値が取れないtimeframe別に取得結果を確認する
毎tickで詳細価格ログを出すログ過多やBT低速化につながる新バー時・NG時・debug時に限定する

CopyClose・iCloseとあわせて確認したい時系列データ

CopyCloseやiCloseで終値を取得する場合は、バー時刻、新バー判定、現在時刻の扱いもあわせて確認しておくと、現在足と確定足の混同を防ぎやすくなります。

確認したい内容関連ページ確認ポイント
バー時刻と新バー判定MQL5 CopyTimeの使い方CopyTimeでバーの開始時刻を取得し、新バー判定や確定足確認に使う流れを確認します。
サーバー時間と稼働時間MQL5 TimeCurrentの使い方TimeCurrent、OnTick、OnTimer、サーバー時間、EA稼働時間判定の違いを確認します。
価格取得関数の整理MQL5時系列・価格取得関数辞典CopyRates、CopyClose、CopyTime、iClose、TimeCurrentなどを目的別に確認します。

関連ページ

CopyClose、iClose、iHigh、iLowは、時系列データ、CopyRates、CopyTime、ログ確認、EA稼働時間と合わせて確認すると整理しやすくなります。

関連ページ確認できること
MQL5関数辞典CopyClose、iClose、iHigh、iLow、SymbolInfo系など主要関数の整理
MQL5イベント処理完全ガイドOnTick、OnTimer、OnInitなどイベントごとの処理整理
MQL5デバッグ・ログファースト開発完全ガイドExpertsログ、再現条件、ログ設計の確認
MT5のログ確認方法ExpertsログとJournalログの確認方法
EAの稼働時間とはEAの稼働時間、停止時間、サーバー時間の基本

時系列データとローソク足情報をあわせて確認する場合

CopyClose、iClose、iHigh、iLowは、終値・高値・安値を取得する時に使う関数です。終値だけを確認する場合は個別取得で整理できますが、同じバーの時刻、始値、高値、安値、終値をまとめて扱いたい場合は、時系列データ全体やCopyRatesの使い方もあわせて確認してください。

確認したいこと確認するページ主な確認内容
MQL5の時系列データ取得全体を確認したいMQL5時系列データ・価格取得完全ガイドCopyRates、CopyTime、CopyClose、iClose、価格データ、バー時刻の確認
OHLCとバー時刻をまとめて取得したいMQL5 CopyRatesの使い方MqlRates、バー時刻、始値、高値、安値、終値、出来高、スプレッドの確認

価格取得を確認する時は、現在価格、現在足の終値、確定足の終値を混同しないようにしてください。確定足ベースで判定する場合は、shift 1を基準にし、バー時刻やOHLCの取得位置もそろえてログで確認すると原因を追いやすくなります。

開発依頼前に整理したい情報

CopyClose、iClose、iHigh、iLowを使った価格取得、確定足判定、ローソク足条件の実装を相談する場合は、次の情報を整理してください。

整理する情報確認内容
対象EA新規EA、既存EA改修、インジケーターEA化、通知ツールのどれか
取得したい価格終値、高値、安値、現在価格のどれか
判定時間足現在チャート時間足か、M15、H1など別時間足か
判定足現在足を使うか、確定足を使うか
取得本数1本だけか、複数本を比較するか
組み合わせる処理新バー判定、CopyRates、CopyBuffer、OrderSend前チェックなど
履歴不足時の扱い次tickで再確認するか、OnTimerで待つか、初期化失敗にするか
ログCOPYCLOSE_OK、COPYCLOSE_NG、ICLOSE_OK、IHIGH_ILOW_OKなど
検証条件バックテスト期間、銘柄、時間足、スプレッド、ログ量、再現手順

価格取得まわりの不具合を相談する場合は、取得したい時間足、shift、CopyClose戻り値、iClose / iHigh / iLowの値、GetLastError、取得ログを合わせて確認してください。

MT4/MT5の開発・改修相談はこちら

まとめ

CopyCloseは、指定した銘柄・時間足の終値を配列へ取得するMQL5関数です。

iClose、iHigh、iLowは、指定したshiftの終値・高値・安値を1つずつ取得する関数です。1本だけ確認する場合は書きやすく、複数本をまとめて扱う場合はCopyClose、CopyHigh、CopyLowが向いています。

shift 0は現在足、shift 1は1本前の確定足です。EAで確定足ベースの判定を行う場合は、終値、高値、安値、バー時刻のshiftを揃えて確認してください。

CopyCloseの戻り値、iCloseの0、GetLastError、履歴データ不足、現在価格との違い、ログ出力範囲を確認しておくと、価格取得まわりの不具合を追跡しやすくなります。

ABOUT ME
記事URLをコピーしました