MQL4で動いていたインジケーターやEAを「とりあえずMQL5にも移植してみよう」
とコードをそのままコピーしてMetaEditorでコンパイルすると、
`’Bid’ – undeclared identifier`というエラーが大量に出て手が止まった、
という経験はないでしょうか。
原因は単純で、MQL5には`Bid`・`Ask`という予約変数そのものが存在しません。
現在のBid・Ask価格は、`SymbolInfoTick()`という関数を使って取得する仕様に変わっています。
この記事では、MQL4の`Bid`・`Ask`変数がMQL5でなぜ使えなくなったのか、
代わりに使う`SymbolInfoTick()`関数と構造体`MqlTick`の中身、
そして似た用途の`SymbolInfoDouble()`との使い分けを、
実際に動くコードで解説します。
MQL4のBid・Askは「現在チャートの通貨ペア専用」の予約変数
MQL4では、`Bid`と`Ask`はあらかじめ用意された予約変数で、
コード中に書くだけで現在のチャートの通貨ペアの最新価格を参照できました。
double currentBid = Bid; //MQL4: 現在チャートの通貨ペアのBid価格 double currentAsk = Ask; //MQL4: 現在チャートの通貨ペアのAsk価格
ただしMQL4でも、現在チャート以外の通貨ペアの価格を知りたい場合は`Bid`・`Ask`は使えず、
`MarketInfo(symbol, MODE_BID)`・`MarketInfo(symbol, MODE_ASK)`という別の関数が必要でした。
「現在チャートは変数、他の通貨ペアは関数」という2系統の使い分けがすでにMQL4の時点で存在していたことになります。
MQL5にはBid・Ask予約変数が存在しない
MQL5では、この2系統がSymbolInfoTick()・SymbolInfoDouble()という関数への呼び出しに統一されました。
`Bid`・`Ask`という識別子自体が言語仕様から削除されているため、
MQL4のコードをそのまま貼り付けると次のようなコンパイルエラーになります。
//MQL5でこのまま書くとエラー double currentBid = Bid; //'Bid' - undeclared identifier double currentAsk = Ask; //'Ask' - undeclared identifier
現在チャートの通貨ペアであっても、他の通貨ペアであっても、MQL5では常に関数を呼んで値を取得する必要があります。
SymbolInfoTick関数: Bid・Askを同時刻のスナップショットとして取得する
bool SymbolInfoTick( string symbol, //通貨ペア名 MqlTick& tick //値を受け取る構造体(参照渡し) );
戻り値は取得の成否(bool)で、実際のデータは第2引数に渡した`MqlTick`構造体に書き込まれます。
構造体のメンバーは次の通りです。
struct MqlTick
{
datetime time; //直近の価格更新時刻(秒単位)
double bid; //現在のBid価格
double ask; //現在のAsk価格
double last; //直近約定した価格(現物・株式銘柄向け、FXでは0のことが多い)
ulong volume; //直近価格での出来高
long time_msc; //直近の価格更新時刻(ミリ秒単位)
uint flags; //ティックフラグ(どの値が更新されたか)
double volume_real; //出来高(倍精度)
};
`SymbolInfoTick()`最大の利点は、Bid・Ask・時刻をすべて1回の呼び出しでまとめて取得できることです。
次に説明する`SymbolInfoDouble()`を2回に分けて呼ぶと、
1回目と2回目の呼び出しの間にわずかな時間差が生まれ、価格が動くタイミングによってはBidとAskの組み合わせが「同時刻の実際の値」
ではなくなる可能性があります。
スプレッドを正確に計算したい場面など、BidとAskの整合性が重要な処理では`SymbolInfoTick()`でまとめて取得するほうが安全です。
SymbolInfoDouble関数: 1項目だけ個別に取得する
BidかAskの片方だけで十分な場合や、スプレッド・最小価格変動幅など他のシンボル情報と一緒に取得したい場合は、
`SymbolInfoDouble()`のほうが簡潔に書けます。
double bid = SymbolInfoDouble(symbol, SYMBOL_BID); double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
MQL4のMarketInfo(symbol, MODE_BID/MODE_ASK)(他通貨ペア用) → MQL5ではSymbolInfoDouble(symbol, SYMBOL_BID/SYMBOL_ASK)
BidとAskをまとめて同時刻で取得したい → MQL5ではSymbolInfoTick(symbol, tick)
実際に動くコード全体
現在チャートの通貨ペアについて、`SymbolInfoTick()`でBid・Ask・更新時刻をまとめて取得し、
スプレッドをポイント単位で計算して表示する、実際にMetaEditorでコンパイルできるスクリプトです。
//+------------------------------------------------------------------+
//| SymbolInfoTickDemo.mq5 |
//| 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 script_show_inputs
input string TargetSymbol = "";//空欄なら現在チャートの通貨ペア
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
string symbol = (TargetSymbol == "") ? _Symbol : TargetSymbol;
MqlTick tick;
if(!SymbolInfoTick(symbol, tick))
{
Print(symbol, " のティック取得に失敗しました。エラーコード=", GetLastError());
return;
}
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
double spreadPoints = (tick.ask - tick.bid) / point;
PrintFormat("%s Bid=%.5f Ask=%.5f スプレッド=%.1fポイント 更新時刻=%s",
symbol, tick.bid, tick.ask, spreadPoints,
TimeToString(tick.time, TIME_DATE | TIME_SECONDS));
//SymbolInfoDoubleで個別取得した場合との比較(通常はほぼ同じ値になる)
double bidOnly = SymbolInfoDouble(symbol, SYMBOL_BID);
double askOnly = SymbolInfoDouble(symbol, SYMBOL_ASK);
PrintFormat("(参考)SymbolInfoDoubleで個別取得: Bid=%.5f Ask=%.5f",
bidOnly, askOnly);
}
//+------------------------------------------------------------------+
MetaEditorで実際に動かす手順
- MetaTrader 5の「ツール」→「MetaQuotes Language Editor」でMetaEditorを開く
- 「ファイル」→「新規作成」→「スクリプト」を選び、名前を「SymbolInfoTickDemo」にして作成する(中身は空のテンプレートで構いません)
- テンプレートの中身を全て削除し、上のコードを丸ごと貼り付ける
- F7キー(またはコンパイルボタン)でコンパイルし、「0 error(s), 0 warning(s)」になることを確認する
- チャートへドラッグ&ドロップし、「エキスパート」タブにBid・Ask・スプレッド・更新時刻が表示されることを確認する
コピペしてコンパイルが通らない・値が取得できないときに確認すること
- MQL4のコードをそのまま貼り付けて`Bid`・`Ask`をコンパイルエラーの箇所に残したままにしていないか(`SymbolInfoTick()`または`SymbolInfoDouble()`への書き換えが必要)
- `SymbolInfoTick()`が`false`を返す場合、指定した通貨ペア名が「気配値表示」に表示されていない(市場ウォッチに追加されていない)可能性がある。`SymbolSelect(symbol, true)`で表示状態にしてから呼び出す
- 拡張子が「.mq5」になっているか(このコードはMQL5専用で、MQL4環境ではコンパイルできません)
- `tick.bid`のように構造体のメンバーへ小文字でアクセスしているか(MqlTickのメンバー名は小文字始まり)
まとめ
MQL4の`Bid`・`Ask`予約変数はMQL5には存在せず、
そのまま移植するとコンパイルエラーになります。
現在値を取得するには、BidとAskをまとめて同時刻のスナップショットとして取得できる`SymbolInfoTick()`(構造体`MqlTick`で受け取る)か、
1項目だけで十分なら`SymbolInfoDouble()`を使います。
他通貨ペアの価格を扱っていたMQL4のMarketInfo()も、
MQL5ではこの2つの関数に置き換わっている、と覚えておくと移植時の書き換え漏れを防げます。
コメント