MQL4の口座情報関数とマーケット情報関数を体系的にまとめました。AccountBalance()・AccountEquity()・AccountFreeMargin()による口座状態の取得、MarketInfo()による通貨ペア仕様(スプレッド・ストップレベル・ロット情報)の取得、リスクベースのロット自動計算、証拠金チェック、5桁ブローカー対応まで、MT4 EA開発に必要な口座・マーケット情報のすべてをコード付きで解説します。
MQL4とMQL5の口座・マーケット情報の違い
| 機能 | MQL4 | MQL5 |
|---|---|---|
| 口座残高 | AccountBalance() | AccountInfoDouble(ACCOUNT_BALANCE) |
| 口座情報 | Account〇〇()系関数 | AccountInfoDouble/Integer/String() |
| マーケット情報 | MarketInfo(symbol, MODE_〇〇) | SymbolInfoDouble/Integer/String() |
| スプレッド | MarketInfo(sym, MODE_SPREAD) | SymbolInfoInteger(sym, SYMBOL_SPREAD) |
| 定義済み変数 | Ask, Bid, Point, Digits | _Symbol, _Point, _Digits(Ask/Bidなし) |
| 証拠金計算 | AccountFreeMarginCheck() | OrderCalcMargin() |
MQL4ではAsk、Bid、Point、Digitsが定義済み変数として直接使えます。MQL5ではSymbolInfoDouble()等で取得する必要があり、コード量が増えます。
口座情報関数
残高・有効証拠金・余剰証拠金
| 関数 | 戻り値 | 説明 |
|---|---|---|
| AccountBalance() | double | 口座残高(確定損益のみ) |
| AccountEquity() | double | 有効証拠金(残高+含み損益) |
| AccountFreeMargin() | double | 余剰証拠金(新規注文可能額) |
| AccountMargin() | double | 使用中の証拠金 |
| AccountProfit() | double | 含み損益の合計 |
void PrintAccountInfo()
{
Print("=== 口座情報 ===");
Print("残高: ", DoubleToStr(AccountBalance(), 2));
Print("有効証拠金: ", DoubleToStr(AccountEquity(), 2));
Print("余剰証拠金: ", DoubleToStr(AccountFreeMargin(), 2));
Print("使用証拠金: ", DoubleToStr(AccountMargin(), 2));
Print("含み損益: ", DoubleToStr(AccountProfit(), 2));
// 証拠金維持率
if(AccountMargin() > 0)
{
double marginLevel = AccountEquity() / AccountMargin() * 100;
Print("証拠金維持率: ", DoubleToStr(marginLevel, 1), "%");
}
}口座設定情報
| 関数 | 戻り値 | 説明 |
|---|---|---|
| AccountNumber() | int | 口座番号 |
| AccountName() | string | 口座名義 |
| AccountServer() | string | サーバー名 |
| AccountCompany() | string | ブローカー名 |
| AccountCurrency() | string | 口座通貨(”JPY”, “USD”等) |
| AccountLeverage() | int | レバレッジ倍率 |
| AccountStopoutLevel() | int | ロスカット水準 |
| AccountStopoutMode() | int | 0=パーセント, 1=金額 |
| AccountFreeMarginMode() | double | 余剰証拠金計算モード |
| IsDemo() | bool | デモ口座かどうか |
| IsTradeAllowed() | bool | 自動売買が許可されているか |
bool CheckAccountReady()
{
if(!IsTradeAllowed())
{
Print("自動売買が許可されていません");
return false;
}
if(!IsConnected())
{
Print("サーバーに接続されていません");
return false;
}
Print("口座番号: ", AccountNumber());
Print("ブローカー: ", AccountCompany());
Print("サーバー: ", AccountServer());
Print("口座通貨: ", AccountCurrency());
Print("レバレッジ: 1:", AccountLeverage());
Print("デモ口座: ", IsDemo() ? "はい" : "いいえ");
return true;
}AccountFreeMarginCheck — 証拠金事前チェック
double AccountFreeMarginCheck(
string symbol, // 通貨ペア
int cmd, // OP_BUY または OP_SELL
double volume // ロット数
);
// 戻り値: 注文後の余剰証拠金(負の値なら証拠金不足)int SafeBuy(double lots, int slPoints, int tpPoints, int magic)
{
// 証拠金事前チェック
double freeMargin = AccountFreeMarginCheck(Symbol(), OP_BUY, lots);
if(freeMargin < 0)
{
Print("証拠金不足: 必要追加額=", DoubleToStr(MathAbs(freeMargin), 2));
return -1;
}
// 余剰証拠金が口座の50%未満なら警告
if(freeMargin < AccountBalance() * 0.5)
{
Print("警告: 証拠金維持率が低下します");
}
double sl = NormalizeDouble(Ask - slPoints * Point, Digits);
double tp = NormalizeDouble(Ask + tpPoints * Point, Digits);
return OrderSend(Symbol(), OP_BUY, lots, Ask, 3, sl, tp,
"SafeBuy", magic, 0, clrBlue);
}MarketInfo — マーケット情報
MarketInfo()は通貨ペアの仕様情報を取得する汎用関数です。第2引数のモード定数で取得する情報を指定します。
double MarketInfo(
string symbol, // 通貨ペア
int type // 情報タイプ(MODE_〇〇定数)
);主要なMODE定数
| 定数 | 値 | 説明 | 例 |
|---|---|---|---|
| MODE_BID | 9 | 現在のBid | 110.123 |
| MODE_ASK | 10 | 現在のAsk | 110.135 |
| MODE_POINT | 11 | ポイントサイズ | 0.001 (3桁) / 0.00001 (5桁) |
| MODE_DIGITS | 12 | 小数点以下の桁数 | 3 or 5 |
| MODE_SPREAD | 13 | スプレッド(ポイント) | 12 |
| MODE_STOPLEVEL | 14 | ストップレベル(ポイント) | 20 |
| MODE_LOTSIZE | 15 | 1ロットの通貨量 | 100000 |
| MODE_TICKVALUE | 16 | 1ティックの価値 | 1000 (USDJPY) |
| MODE_TICKSIZE | 17 | 最小変動幅 | 0.001 |
| MODE_SWAPLONG | 18 | 買いスワップ | -2.5 |
| MODE_SWAPSHORT | 19 | 売りスワップ | 1.2 |
| MODE_MINLOT | 23 | 最小ロット | 0.01 |
| MODE_MAXLOT | 25 | 最大ロット | 100.0 |
| MODE_LOTSTEP | 24 | ロットステップ | 0.01 |
| MODE_FREEZELEVEL | 33 | フリーズレベル | 10 |
| MODE_MARGINREQUIRED | 31 | 1ロットの必要証拠金 | 44000 |
void PrintSymbolInfo(string sym)
{
Print("=== ", sym, " ===");
Print("Bid: ", MarketInfo(sym, MODE_BID));
Print("Ask: ", MarketInfo(sym, MODE_ASK));
Print("スプレッド: ", MarketInfo(sym, MODE_SPREAD), " points");
Print("ポイント: ", MarketInfo(sym, MODE_POINT));
Print("桁数: ", (int)MarketInfo(sym, MODE_DIGITS));
Print("ストップレベル: ", MarketInfo(sym, MODE_STOPLEVEL), " points");
Print("フリーズレベル: ", MarketInfo(sym, MODE_FREEZELEVEL), " points");
Print("1ロット=", MarketInfo(sym, MODE_LOTSIZE), " 通貨");
Print("ティック価値: ", MarketInfo(sym, MODE_TICKVALUE));
Print("最小ロット: ", MarketInfo(sym, MODE_MINLOT));
Print("最大ロット: ", MarketInfo(sym, MODE_MAXLOT));
Print("ロットステップ: ", MarketInfo(sym, MODE_LOTSTEP));
Print("必要証拠金/ロット: ", MarketInfo(sym, MODE_MARGINREQUIRED));
Print("買いスワップ: ", MarketInfo(sym, MODE_SWAPLONG));
Print("売りスワップ: ", MarketInfo(sym, MODE_SWAPSHORT));
}- MODE_TICKVALUEは口座通貨建ての値を返す。JPY口座とUSD口座では値が異なる
- MODE_SPREADはポイント単位。5桁ブローカーでは「12」= 1.2pips
- MODE_STOPLEVELが0のブローカーもある(制限なし)
- MODE_FREEZELEVELは現在価格に近い注文の変更・削除を禁止する範囲
- 週末やメンテナンス時はBid/Askが0になることがある
- MODE_TICKVALUEは口座通貨建ての値を返す。JPY口座とUSD口座では値が異なる
- MODE_SPREADはポイント単位。5桁ブローカーでは「12」= 1.2pips
- MODE_STOPLEVELが0のブローカーもある(制限なし)
- MODE_FREEZELEVELは現在価格に近い注文の変更・削除を禁止する範囲
- 週末やメンテナンス時はBid/Askが0になることがある
定義済み変数
MQL4では、現在のチャートに関する情報が定義済み変数として利用できます。
| 変数 | 型 | 説明 | MQL5対応 |
|---|---|---|---|
| Ask | double | 現在のAsk価格 | SymbolInfoDouble(_Symbol,SYMBOL_ASK) |
| Bid | double | 現在のBid価格 | SymbolInfoDouble(_Symbol,SYMBOL_BID) |
| Point | double | ポイントサイズ | _Point |
| Digits | int | 小数点桁数 | _Digits |
| Bars | int | チャートのバー数 | Bars(_Symbol,_Period) |
| Close[] | double[] | 終値配列 | CopyClose() / iClose() |
| Open[] | double[] | 始値配列 | CopyOpen() / iOpen() |
| High[] | double[] | 高値配列 | CopyHigh() / iHigh() |
| Low[] | double[] | 安値配列 | CopyLow() / iLow() |
| Volume[] | long[] | 出来高配列 | CopyTickVolume() |
| Time[] | datetime[] | 時刻配列 | CopyTime() / iTime() |
実践: リスクベースのロット自動計算
double CalcLotSize(string sym, double riskPercent, double slPrice, bool isBuy)
{
double balance = AccountBalance();
double riskMoney = balance * riskPercent / 100.0;
// SLまでの距離(ポイント単位)
double entryPrice = isBuy ? MarketInfo(sym, MODE_ASK) : MarketInfo(sym, MODE_BID);
double slDistance = MathAbs(entryPrice - slPrice);
if(slDistance < MarketInfo(sym, MODE_POINT))
return MarketInfo(sym, MODE_MINLOT);
// 1ロットあたりのSL損失額
double tickValue = MarketInfo(sym, MODE_TICKVALUE);
double tickSize = MarketInfo(sym, MODE_TICKSIZE);
if(tickValue == 0 || tickSize == 0)
return MarketInfo(sym, MODE_MINLOT);
double slMoney = slDistance / tickSize * tickValue;
// ロット数計算
double lots = riskMoney / slMoney;
double minLot = MarketInfo(sym, MODE_MINLOT);
double maxLot = MarketInfo(sym, MODE_MAXLOT);
double lotStep = MarketInfo(sym, MODE_LOTSTEP);
lots = MathFloor(lots / lotStep) * lotStep;
lots = MathMax(lots, minLot);
lots = MathMin(lots, maxLot);
// 証拠金チェック
int cmd = isBuy ? OP_BUY : OP_SELL;
if(AccountFreeMarginCheck(sym, cmd, lots) < 0)
{
Print("証拠金不足: ロット縮小");
while(lots > minLot && AccountFreeMarginCheck(sym, cmd, lots) < 0)
lots -= lotStep;
}
return NormalizeDouble(lots, 2);
}5桁ブローカー対応
現在のFXブローカーの大半は5桁(USDJPY=110.123)/ 3桁(XAUUSD=1800.12)表示です。EA内でpips単位の計算をする場合、Point * 10 = 1pipとして扱う必要があります。Digits==3またはDigits==5で自動判定しましょう。
現在のFXブローカーの大半は5桁(USDJPY=110.123)/ 3桁(XAUUSD=1800.12)表示です。EA内でpips単位の計算をする場合、Point * 10 = 1pipとして扱う必要があります。Digits==3またはDigits==5で自動判定しましょう。
// グローバル変数
int PipMultiplier;
double PipSize;
int OnInit()
{
// 3桁/5桁ブローカーの自動判定
if(Digits == 3 || Digits == 5)
{
PipMultiplier = 10;
PipSize = Point * 10;
}
else
{
PipMultiplier = 1;
PipSize = Point;
}
Print("PipSize=", PipSize, " PipMultiplier=", PipMultiplier);
return INIT_SUCCEEDED;
}
// pips単位でSL/TP計算する例
double PipsToPrice(double pips)
{
return pips * PipSize;
}
// 使用例: 30pipsのSL
// double sl = Ask - PipsToPrice(30);- AccountFreeMarginCheck()で発注前に証拠金不足を検知できる。戻り値が負なら証拠金不足
- ロットステップ(MODE_LOTSTEP)に合わせてMathFloor()で切り捨てるのが安全
- JPYペアとUSDペアではTickValueが大きく異なるため、固定ロットは危険
- 口座通貨がJPYの場合、クロス円以外のTickValueは為替レートで変動する
- AccountFreeMarginCheck()で発注前に証拠金不足を検知できる。戻り値が負なら証拠金不足
- ロットステップ(MODE_LOTSTEP)に合わせてMathFloor()で切り捨てるのが安全
- JPYペアとUSDペアではTickValueが大きく異なるため、固定ロットは危険
- 口座通貨がJPYの場合、クロス円以外のTickValueは為替レートで変動する
Symbol関連関数
| 関数 | 説明 |
|---|---|
| Symbol() | 現在のチャートの通貨ペア名 |
| SymbolsTotal(bool selected) | 利用可能な通貨ペア数 |
| SymbolName(int pos, bool selected) | 指定位置の通貨ペア名 |
| SymbolSelect(string name, bool select) | 気配値表示への追加/削除 |
| SymbolInfoDouble() | 通貨ペアのdouble情報(ビルド600+) |
| SymbolInfoInteger() | 通貨ペアのint情報(ビルド600+) |
| SymbolInfoString() | 通貨ペアの文字列情報(ビルド600+) |
口座・マーケット情報関数一覧(MQL5対応表)
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| AccountBalance() | AccountInfoDouble(ACCOUNT_BALANCE) | 口座残高 |
| AccountEquity() | AccountInfoDouble(ACCOUNT_EQUITY) | 有効証拠金 |
| AccountFreeMargin() | AccountInfoDouble(ACCOUNT_MARGIN_FREE) | 余剰証拠金 |
| AccountMargin() | AccountInfoDouble(ACCOUNT_MARGIN) | 使用証拠金 |
| AccountProfit() | AccountInfoDouble(ACCOUNT_PROFIT) | 含み損益 |
| AccountLeverage() | AccountInfoInteger(ACCOUNT_LEVERAGE) | レバレッジ |
| AccountCurrency() | AccountInfoString(ACCOUNT_CURRENCY) | 口座通貨 |
| MarketInfo(sym, MODE_SPREAD) | SymbolInfoInteger(sym, SYMBOL_SPREAD) | スプレッド |
| MarketInfo(sym, MODE_STOPLEVEL) | SymbolInfoInteger(sym, SYMBOL_TRADE_STOPS_LEVEL) | ストップレベル |
| MarketInfo(sym, MODE_TICKVALUE) | SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_VALUE) | ティック価値 |
| MarketInfo(sym, MODE_MINLOT) | SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN) | 最小ロット |
| MarketInfo(sym, MODE_MAXLOT) | SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX) | 最大ロット |
| MarketInfo(sym, MODE_LOTSTEP) | SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP) | ロットステップ |
| AccountFreeMarginCheck() | OrderCalcMargin() | 証拠金事前チェック |
まとめ
MQL4の口座・マーケット情報関数は、EA開発のリスク管理において不可欠です。特に重要なポイントは以下の通りです。
- ロット計算にはMarketInfo()のTICKVALUE/TICKSIZEを使う — 通貨ペアごとに正確な損益を計算できる
- AccountFreeMarginCheck()で発注前に証拠金を確認する — 証拠金不足エラーを未然に防ぐ
- 5桁ブローカーの自動判定を入れる — Digits==3/5で判定し、PipSizeを動的に設定する
- MODE_STOPLEVELを確認してからSL/TPを設定する — ストップレベル未満ではOrderModifyが失敗する
次のステップとして、MQLリファレンス総合ガイドで取引関数やインジケーター関数と組み合わせた総合的なEA開発を学びましょう。





