この記事では、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 | 実際の出来高(取引所通貨ペアのみ) |
構造体の図解
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()の戻り値は必ずチェックし、取得失敗時の処理を入れること


