【MQL4リファレンス】MqlRates構造体の使い方!CopyRates()でローソク足データを配列取得する方法

構造体

この記事では、MQL4のMqlRates構造体について詳しく解説します。
CopyRates()関数と組み合わせることで、過去のローソク足データ(OHLC)を配列としてまとめて取得できます。iClose()やiOpen()より効率的にデータ処理ができます。

MqlRates構造体とは?

MqlRatesは、ローソク足1本分のデータを格納するための構造体です。始値・高値・安値・終値(OHLC)に加え、ティック数やスプレッドも格納します。

MqlRates rates[]のように配列で宣言し、CopyRates()を使って複数本のバーデータを一度に取得できるのが特徴です。

MqlRates が便利な場面
・過去N本のローソク足データをまとめて取得したいとき
・最高値・最安値のスキャンをループで行うとき
・カスタムインジケーターのバッファ計算

構造体の定義・フィールド一覧

フィールド 説明
time datetime ローソク足の開始時刻
open double 始値
high double 高値
low double 安値
close double 終値
tick_volume long ティック数(そのバーの値動き回数)
spread int スプレッド(ポイント単位)
real_volume long 実際の出来高(取引所通貨ペアのみ)

構造体の図解

struct MqlRates high 高値 (double) open 始値 (double) close 終値 (double) low 安値 (double) time 開始時刻 (datetime) tick_volume ティック数 (long) spread スプレッド (int) real_volume 実出来高 (long) 取得関数 CopyRates()
MqlRates構造体のフィールドとローソク足の対応

CopyRates()の使い方

CopyRates()は指定した通貨ペア・時間足のバーデータをMqlRates配列にコピーする関数です。

int CopyRates(
    string            symbol,        // 通貨ペア(例: "USDJPY")
    ENUM_TIMEFRAMES   timeframe,     // 時間足(例: PERIOD_H1)
    int               start_pos,     // 開始インデックス(0=最新バー)
    int               count,         // 取得するバー数
    MqlRates         &rates_array[]  // 取得先の配列
);

戻り値はコピーされたバー数(失敗時は -1 または 0)です。必ず戻り値をチェックしましょう。

ArraySetAsSeries()を忘れずに!
CopyRates()で取得したデータはデフォルトで「古い順」になります。
ArraySetAsSeries(rates, true)を先に呼ぶとrates[0]が最新バーになり、使いやすくなります。

プログラム例①:直近10本のバーデータを取得・表示

void OnTick()
{
    MqlRates rates[];
    ArraySetAsSeries(rates, true);  // [0]が最新バーになるよう設定

    int copied = CopyRates(Symbol(), PERIOD_H1, 0, 10, rates);
    if(copied <= 0)
    {
        Print("データ取得失敗: ", GetLastError());
        return;
    }

    for(int i = 0; i < copied; i++)
    {
        Print("バー[", i, "] ",
              TimeToString(rates[i].time, TIME_DATE|TIME_MINUTES),
              "  始: ", rates[i].open,
              "  高: ", rates[i].high,
              "  安: ", rates[i].low,
              "  終: ", rates[i].close,
              "  ティック: ", rates[i].tick_volume);
    }
}

プログラム例②:過去N本の最高値・最安値を求める

EAやインジケーターでよく使われる「直近N本の高値・安値」を取得するサンプルです。

// 過去N本の最高値を返す
double GetHighestHigh(int bars)
{
    MqlRates rates[];
    ArraySetAsSeries(rates, true);

    if(CopyRates(Symbol(), Period(), 0, bars, rates) != bars)
        return 0;

    double highest = rates[0].high;
    for(int i = 1; i < bars; i++)
    {
        if(rates[i].high > highest)
            highest = rates[i].high;
    }
    return highest;
}

// 過去N本の最安値を返す
double GetLowestLow(int bars)
{
    MqlRates rates[];
    ArraySetAsSeries(rates, true);

    if(CopyRates(Symbol(), Period(), 0, bars, rates) != bars)
        return 0;

    double lowest = rates[0].low;
    for(int i = 1; i < bars; i++)
    {
        if(rates[i].low < lowest)
            lowest = rates[i].low;
    }
    return lowest;
}

// 使用例(OnTick内)
void OnTick()
{
    double highest20 = GetHighestHigh(20);
    double lowest20  = GetLowestLow(20);
    Comment("20本高値: ", highest20, "  20本安値: ", lowest20);
}

プログラム例③:前日の終値を取得する

// 前日日足の終値を取得する
double GetYesterdayClose()
{
    MqlRates daily[];
    ArraySetAsSeries(daily, true);

    // 日足を2本取得([0]=本日、[1]=前日)
    if(CopyRates(Symbol(), PERIOD_D1, 0, 2, daily) < 2)
        return 0;

    return daily[1].close;  // [1]が前日バー
}

void OnTick()
{
    double prevClose = GetYesterdayClose();
    if(prevClose == 0) return;

    double currentPrice = Bid;
    if(currentPrice > prevClose)
        Comment("前日終値(", prevClose, ")より上: 強気");
    else
        Comment("前日終値(", prevClose, ")より下: 弱気");
}

まとめ

  • MqlRatesはローソク足1本分のOHLC・ティック数・スプレッドを格納する構造体
  • CopyRates()で複数本のバーデータを配列として一括取得できる
  • ArraySetAsSeries(rates, true)を使うとrates[0]が最新バーになり直感的に扱える
  • 最高値・最安値スキャン、前日データ参照など多くの場面で活用できる
  • CopyRates()の戻り値は必ずチェックし、取得失敗時の処理を入れること