はじめに
EA(自動売買)やカスタムインジケーターを作成するとき、「現在のスプレッドはいくつ?」「最小ロット数は?」「ストップレベルは?」など、通貨ペア(シンボル)のさまざまな情報をプログラムから取得したい場面がたくさんあります。
MQL4では、こうした通貨ペアの情報を取得するためにSymbolInfoInteger関数とSymbolInfoDouble関数が用意されています。そして、それぞれの関数で「何の情報を取得するか」を指定するために使うのが、ENUM_SYMBOL_INFO_INTEGERとENUM_SYMBOL_INFO_DOUBLEという列挙型(enum)の定数です。
この記事では、これらの定数と関数の使い方を、実践的なコードサンプルを交えてわかりやすく解説します。
SymbolInfoInteger関数とENUM_SYMBOL_INFO_INTEGERとは
関数の基本構文
SymbolInfoInteger関数は、指定した通貨ペアの整数型(long型)のプロパティ情報を取得する関数です。2つの書き方があります。
// 書き方① 戻り値で直接値を受け取る
long SymbolInfoInteger(
string symbol, // 通貨ペア名
ENUM_SYMBOL_INFO_INTEGER prop_id // 取得したいプロパティの識別子
);
// 書き方② 成功/失敗をboolで受け取り、値は第3引数に格納
bool SymbolInfoInteger(
string symbol, // 通貨ペア名
ENUM_SYMBOL_INFO_INTEGER prop_id, // 取得したいプロパティの識別子
long & var // 値を受け取る変数
);
書き方②では、関数の戻り値がbool(true/false)になり、取得に成功したかどうかを判定できます。エラーハンドリングを丁寧に行いたい場合はこちらがおすすめです。
よく使うENUM_SYMBOL_INFO_INTEGERの定数一覧
以下に、EA開発で特によく使う定数をまとめました。
| 定数名 | 説明 | 用途の例 |
|---|---|---|
SYMBOL_DIGITS |
価格の小数点以下の桁数 | 価格の正規化(NormalizeDouble)に使用 |
SYMBOL_SPREAD |
現在のスプレッド(ポイント単位) | スプレッドフィルターの実装 |
SYMBOL_SPREAD_FLOAT |
変動スプレッドかどうか(bool) | スプレッドの監視方法の判断 |
SYMBOL_TRADE_STOPS_LEVEL |
ストップレベル(ポイント単位) | SL/TPの最小距離チェック |
SYMBOL_TRADE_FREEZE_LEVEL |
フリーズレベル(ポイント単位) | 決済価格付近での注文変更制限 |
SYMBOL_TRADE_MODE |
取引モード(売買が許可されているか等) | 取引可能かどうかの判定 |
SYMBOL_TRADE_EXEMODE |
注文執行モード | 成行 / 即時 / マーケット執行の判定 |
SYMBOL_SWAP_MODE |
スワップの計算方法 | スワップ計算ロジックの分岐 |
SYMBOL_SWAP_ROLLOVER3DAYS |
3日分のスワップが付く曜日 | スワップ戦略の参考 |
SYMBOL_SELECT |
気配値表示で選択されているか | マルチ通貨EAでのシンボル確認 |
SYMBOL_TIME |
直近のサーバー時間(Tick受信時刻) | データの鮮度チェック |
SymbolInfoIntegerの使用例
SymbolInfoInteger関数では、SYMBOL_DIGITS で小数点以下の桁数、SYMBOL_SPREAD でスプレッド、SYMBOL_TRADE_STOPS_LEVEL でストップレベル、SYMBOL_TRADE_FREEZE_LEVEL でフリーズレベルなどの情報を取得できます。以下にコードサンプルを示します。
#property strict
void OnInit()
{
string symbol = Symbol();
// 小数点以下の桁数を取得
int digits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
Print("小数点以下の桁数: ", digits);
// 現在のスプレッドを取得
int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);
Print("スプレッド: ", spread, " ポイント");
// ストップレベルを取得
int stopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
Print("ストップレベル: ", stopLevel, " ポイント");
// フリーズレベルを取得
int freezeLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_FREEZE_LEVEL);
Print("フリーズレベル: ", freezeLevel, " ポイント");
// 変動スプレッドかどうか
bool isFloatSpread = (bool)SymbolInfoInteger(symbol, SYMBOL_SPREAD_FLOAT);
Print("変動スプレッド: ", isFloatSpread ? "はい" : "いいえ");
}
ポイント:SymbolInfoIntegerの戻り値はlong型なので、intやboolとして使いたい場合は、上記のようにキャスト(型変換)を行いましょう。ENUM_SYMBOL_TRADE_EXECUTIONなどの列挙型の返り値を受け取る場合は、返り値を対応する列挙型にキャスト(型変換)して変数に代入します。
SymbolInfoDouble関数とENUM_SYMBOL_INFO_DOUBLEとは
関数の基本構文
SymbolInfoDouble関数は、指定した通貨ペアに関するプロパティ情報(double型)を取得します。この関数で取得する通貨ペアのプロパティ情報の識別子は ENUM_SYMBOL_INFO_DOUBLE 列挙値から選択します。こちらも2つの書き方があります。
// 書き方① 戻り値で直接値を受け取る
double SymbolInfoDouble(
string symbol, // 通貨ペア名
ENUM_SYMBOL_INFO_DOUBLE prop_id // 取得したいプロパティの識別子
);
// 書き方② 成功/失敗をboolで受け取り、値は第3引数に格納
bool SymbolInfoDouble(
string symbol, // 通貨ペア名
ENUM_SYMBOL_INFO_DOUBLE prop_id, // 取得したいプロパティの識別子
double & var // 値を受け取る変数
);
よく使うENUM_SYMBOL_INFO_DOUBLEの定数一覧
ENUM_SYMBOL_INFO_DOUBLEには、SYMBOL_BID(Bid売値)、SYMBOL_ASK(Ask買値)、SYMBOL_LAST(直近の約定価格)などの価格情報のほか、各種取引条件の定数が含まれています。
| 定数名 | 説明 | 用途の例 |
|---|---|---|
SYMBOL_BID |
現在のBid(売値) | 売り注文の基準価格 |
SYMBOL_ASK |
現在のAsk(買値) | 買い注文の基準価格 |
SYMBOL_POINT |
1ポイントの価格単位 | SL/TPの距離計算 |
SYMBOL_TRADE_TICK_VALUE |
1Tickの価値(口座通貨建て) | 損益計算 |
SYMBOL_TRADE_TICK_SIZE |
最小価格変動幅 | 価格の丸め処理 |
SYMBOL_TRADE_CONTRACT_SIZE |
1ロットあたりの契約サイズ | ポジションサイズ計算 |
SYMBOL_VOLUME_MIN |
最小取引ロット数 | ロット数のバリデーション |
SYMBOL_VOLUME_MAX |
最大取引ロット数 | ロット数のバリデーション |
SYMBOL_VOLUME_STEP |
ロット数の刻み幅 | ロット数の正規化 |
SYMBOL_SWAP_LONG |
買いスワップ | スワップの確認・計算 |
SYMBOL_SWAP_SHORT |
売りスワップ | スワップの確認・計算 |
SYMBOL_MARGIN_INITIAL |
初期証拠金 | 資金管理 |
SymbolInfoDoubleの使用例
#property strict
void OnInit()
{
string symbol = Symbol();
// Bid / Ask を取得
double bid = SymbolInfoDouble(symbol, SYMBOL_BID);
double ask = SymbolInfoDouble(symbol, SYMBOL_ASK);
Print("Bid: ", bid, " / Ask: ", ask);
// ポイントサイズを取得
double point = SymbolInfoDouble(symbol, SYMBOL_POINT);
Print("1ポイント: ", point);
// ロット関連情報を取得
double minLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
Print("最小ロット: ", minLot, " / 最大ロット: ", maxLot, " / 刻み: ", lotStep);
// スワップ情報を取得
double swapLong = SymbolInfoDouble(symbol, SYMBOL_SWAP_LONG);
double swapShort = SymbolInfoDouble(symbol, SYMBOL_SWAP_SHORT);
Print("買いスワップ: ", swapLong, " / 売りスワップ: ", swapShort);
}
MarketInfo関数との違い ― なぜSymbolInfoXXXを使うべきか
MQL4には、古くからMarketInfo()関数が存在し、通貨ペアの情報を取得できました。しかし、SymbolInfoInteger / SymbolInfoDoubleを使うことをおすすめします。その理由は以下の通りです。
- 型の正確性:MarketInfo()はすべての値をdouble型で返しますが、SymbolInfoIntegerはlong型を返すため、整数値の精度が保たれ、型チェックが正確になります。
- MQL5との互換性:MT4とMT5の両方で動作するコードを書きたい場合は、SymbolInfoDouble()を使うほうがよいとされています。MQL4ではMarketInfo関数でも同様にポイントサイズを取得できますが、MQL4/5共通でSymbolInfoDouble関数が使えるので、そちらを使っておけばよいでしょう。
- エラーハンドリング:書き方②(bool戻り値版)を使えば、情報が取得できなかった場合を明確に判定できます。
// ❌ 古い書き方(MarketInfo)
double spread = MarketInfo(Symbol(), MODE_SPREAD);
double point = MarketInfo(Symbol(), MODE_POINT);
// ✅ 新しい書き方(SymbolInfoXXX)※推奨
int spread = (int)SymbolInfoInteger(Symbol(), SYMBOL_SPREAD);
double point = SymbolInfoDouble(Symbol(), SYMBOL_POINT);
【実践】通貨ペア情報を一括表示するサンプルEA
最後に、ここまで学んだ内容を活用して、チャートに適用した通貨ペアの主要情報をログに一括出力するサンプルEAを紹介します。
//+------------------------------------------------------------------+
//| SymbolInfoViewer.mq4 |
//| 通貨ペアの主要情報を一括表示するサンプルEA |
//+------------------------------------------------------------------+
#property strict
void OnInit()
{
string sym = Symbol();
Print("=== ", sym, " の通貨ペア情報 ===");
// --- Integer型の情報 ---
Print("小数桁数 (Digits): ",
(int)SymbolInfoInteger(sym, SYMBOL_DIGITS));
Print("スプレッド: ",
(int)SymbolInfoInteger(sym, SYMBOL_SPREAD), " point");
Print("変動スプレッド: ",
(bool)SymbolInfoInteger(sym, SYMBOL_SPREAD_FLOAT));
Print("ストップレベル: ",
(int)SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL), " point");
Print("フリーズレベル: ",
(int)SymbolInfoInteger(sym, SYMBOL_TRADE_FREEZE_LEVEL), " point");
// 取引実行モードの取得(列挙型へのキャスト)
ENUM_SYMBOL_TRADE_EXECUTION exeMode
= (ENUM_SYMBOL_TRADE_EXECUTION)SymbolInfoInteger(sym, SYMBOL_TRADE_EXEMODE);
Print("取引執行モード: ", EnumToString(exeMode));
// --- Double型の情報 ---
Print("Bid: ", SymbolInfoDouble(sym, SYMBOL_BID));
Print("Ask: ", SymbolInfoDouble(sym, SYMBOL_ASK));
Print("Point: ", SymbolInfoDouble(sym, SYMBOL_POINT));
Print("最小ロット: ", SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN));
Print("最大ロット: ", SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX));
Print("ロット刻み: ", SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP));
Print("契約サイズ: ", SymbolInfoDouble(sym, SYMBOL_TRADE_CONTRACT_SIZE));
Print("TickValue: ", SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_VALUE));
Print("TickSize: ", SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_SIZE));
Print("買いスワップ: ", SymbolInfoDouble(sym, SYMBOL_SWAP_LONG));
Print("売りスワップ: ", SymbolInfoDouble(sym, SYMBOL_SWAP_SHORT));
Print("=== 情報取得完了 ===");
}
このEAをチャートにセットすると、「エキスパート」タブにその通貨ペアの主要な情報が一覧で出力されます。自分のブローカーの設定値を確認したり、EA開発時のデバッグに非常に便利です。
注意点とTips
- 気配値表示ウィンドウに注意:ストラテジーテスターの中ではSymbolInfoやMarketInfoが取得できない時があり、気配値表示ウィンドウに表示されていない通貨ペアでは値が0.0になることがあります。マルチ通貨EAを作る場合は、対象通貨ペアが気配値表示に含まれているか事前に確認しましょう。
- ストップレベルが0の場合:一部のブローカーではストップレベルが0に設定されています。この場合、SL/TPの距離制限がないという意味ではなく、スプレッド分は最低限必要になることが多いため、実際のテストで確認しましょう。
- EnumToString関数の活用:ENUM_SYMBOL_TRADE_EXECUTION型などの列挙型を受け取る場合は、SymbolInfoIntegerの返り値を対応する列挙型にキャストして変数に代入します。
EnumToString()を使うと定数名が文字列で返されるのでデバッグに便利です。
まとめ
今回は、MQL4で通貨ペア情報を取得するためのENUM_SYMBOL_INFO_INTEGERとENUM_SYMBOL_INFO_DOUBLEの定数、そしてSymbolInfoInteger関数とSymbolInfoDouble関数の使い方を解説しました。
ポイントを整理すると:
- 整数型の情報(桁数、スプレッド、ストップレベルなど)→
SymbolInfoInteger() - 小数型の情報(価格、ポイント、ロット数、スワップなど)→
SymbolInfoDouble() - 古い
MarketInfo()より型安全でMQL5互換のSymbolInfoXXXを使おう - bool戻り値版を使えば、エラーハンドリングもしっかり行える
通貨ペアの情報を正確に取得できるようになると、ロット計算やSL/TP設定、スプレッドフィルターなど、EA開発のあらゆる場面で役立ちます。ぜひ今回のサンプルコードを実際に動かして、自分のブローカーの値を確認してみてください!

