MetaTrader4 で、口座情報、証拠金状況情報、時刻情報、マーケット情報、商品情報を取得するスクリプトを作りました。
AccountXxx() や MarketInfo() を使って情報を取得するスクリプトはけっこうあちこちで見掛ける、珍しくもなんともないものなのですが、一応いくつか特徴があります。
AccountXxx() や MarketInfo() を使って情報を取得するスクリプトはけっこうあちこちで見掛ける、珍しくもなんともないものなのですが、一応いくつか特徴があります。
- コード値を返すものは、その意味が分かるようなメッセージにしている
- 日付・時刻はフォーマットしている
- サーバ時刻とローカル時刻の時差を計算している
- 単位のある数値は、単位を表記するようにしている
- point とか % とか
- 例えば JPY 口座で USDCHF の情報を見ているときに、各種金額が JPY なのか USD なのか CHF なのかを明示している
- おそらく MetaTrader5 由来だと思うのですが、AccountInfoXxx() や SymbolInfoXxx() でしか拾えない情報があるので、それらも表示するようにしている
仕様
まず、MQL4\Scripts に置いてコンパイルします。
そうしたら、ナビゲーターのスクリプトから選んで、チャートにドラッグ&ドロップすれば実行されます。
実行すると、アラートウィンドウに結果が表示されます。メッセージダイアログだとコピーできなかったので、アラートにしました。
ソースコード
#property copyright "Copyright 2020, VIRTUE LLC Japan"
#property link "https://www.virtue.llc"
#property version "1.00"
#property description "Get Account, Margin, Time, Market and Symbol information."
int start() {
string msg = "=== Account information ===\n";
msg += "Company/Server=" + AccountCompany() + " / " + AccountServer() + "\n";
// msg += "Number=" + AccountNumber() + "\n";
// msg += "Name=" + AccountName() + "\n";
msg += "TradeAllowed=" + B(AccountInfoInteger(ACCOUNT_TRADE_ALLOWED)) + "\n";
msg += "TradeExpertAllowed=" + B(AccountInfoInteger(ACCOUNT_TRADE_EXPERT)) + "\n";
msg += "LimitOrders=" + AccountInfoInteger(ACCOUNT_LIMIT_ORDERS) + "\n";
string ccy = AccountCurrency();
msg += "Currency=" + ccy + "\n";
msg += "Leverage=" + AccountLeverage() + "\n";
string stopout;
if (AccountStopoutMode() == 0) {
stopout = "%";
} else {
stopout = ccy;
}
msg += "MarginCallLevel=" + AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL) + stopout + "\n";
msg += "StopoutLevel=" + AccountStopoutLevel() + stopout + "\n";
msg += "=== Margin status ===\n";
msg += "Balance=" + AccountBalance() + " " + ccy + "\n";
msg += "Credit=" + AccountCredit() + " " + ccy + "\n";
msg += "Profit/Loss=" + AccountProfit() + " " + ccy + "\n";
msg += "Equity=" + AccountEquity() + " " + ccy + "\n";
msg += "Margin=" + AccountMargin() + " " + ccy + "\n";
int freeMarginMode = AccountFreeMarginMode();
string freeMarginModeString = "";
switch (freeMarginMode) {
case 0:
freeMarginModeString = "Floating P/L is not used";
break;
case 1:
freeMarginModeString = "Floating P/L is used";
break;
case 2:
freeMarginModeString = "Only floating profit is used";
break;
default:
freeMarginModeString = "Only floating loss is used";
}
msg += "FreeMargin=" + AccountFreeMargin() + " " + ccy + " (" + freeMarginModeString + ")\n";
msg += "=== Time information ===\n";
datetime loc = TimeLocal();
datetime cur = TimeCurrent();
string offset = DoubleToString(MathRound((loc - cur) / 1800.0) / 2.0, 1);
msg += "Local/ServerTime(Offset)=" + T(loc) + " / " + T(cur) + " (" + offset + ")\n";
msg += "=== Current market information ===\n";
msg += "Symbol=" + Symbol() + "\n";
string symbolBaseCcy = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_BASE);
string symbolProfitCcy = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_PROFIT);
string symbolMarginCcy = SymbolInfoString(Symbol(), SYMBOL_CURRENCY_MARGIN);
int digits = MarketInfo(Symbol(), MODE_DIGITS);
datetime bar = MarketInfo(Symbol(), MODE_TIME);
bool spreadFloat = SymbolInfoInteger(Symbol(), SYMBOL_SPREAD_FLOAT);
msg += "TickTimestamp/Bid/Ask(Spread)=" + T(bar) + " " + DoubleToString(MarketInfo(Symbol(), MODE_BID), digits) + "/" + DoubleToString(MarketInfo(Symbol(), MODE_ASK), digits) + "(" + MarketInfo(Symbol(), MODE_SPREAD) + "/" + (spreadFloat ? "variable" : "fixed") + ")\n";
msg += "Low/High=" + DoubleToString(MarketInfo(Symbol(), MODE_LOW), digits) + "/" + DoubleToString(MarketInfo(Symbol(), MODE_HIGH), digits) + "\n";
int swapMode = MarketInfo(Symbol(), MODE_SWAPTYPE);
string swapModeString;
switch (swapMode) {
case 0:
swapModeString = "point";
break;
case 1:
swapModeString = symbolBaseCcy;
break;
case 2:
swapModeString = "%";
break;
default:
swapModeString = symbolMarginCcy;
}
msg += "SwapLong/Short=" + MarketInfo(Symbol(), MODE_SWAPLONG) + "/" + MarketInfo(Symbol(), MODE_SWAPSHORT) + " " + swapModeString + "\n";
msg += "=== Symbol information ===\n";
double point = MarketInfo(Symbol(), MODE_POINT);
msg += "TradeAllowed=" + B(MarketInfo(Symbol(), MODE_TRADEALLOWED)) + "\n";
msg += "CloseByAllowed=" + B(MarketInfo(Symbol(), MODE_CLOSEBY_ALLOWED)) + "\n";
// msg += "TradeCalcMode=" + SymbolInfoInteger(Symbol(), SYMBOL_TRADE_CALC_MODE) + "\n";
int tradeMode = SymbolInfoInteger(Symbol(), SYMBOL_TRADE_MODE);
string tradeModeString;
switch (tradeMode) {
case SYMBOL_TRADE_MODE_DISABLED:
tradeModeString = "disabled";
break;
case SYMBOL_TRADE_MODE_LONGONLY:
tradeModeString = "long only";
break;
case SYMBOL_TRADE_MODE_SHORTONLY:
tradeModeString = "short only";
break;
case SYMBOL_TRADE_MODE_CLOSEONLY:
tradeModeString = "close only";
break;
default:
tradeModeString = "full";
}
msg += "TradeMode=" + tradeMode + " (" + tradeModeString + ")\n";
int tradeExeMode = SymbolInfoInteger(Symbol(), SYMBOL_TRADE_EXEMODE);
string tradeExeModeString;
switch (tradeExeMode) {
case SYMBOL_TRADE_EXECUTION_REQUEST:
tradeExeModeString = "request";
break;
case SYMBOL_TRADE_EXECUTION_INSTANT:
tradeExeModeString = "instant";
break;
case SYMBOL_TRADE_EXECUTION_MARKET:
tradeExeModeString = "market";
break;
default:
tradeExeModeString = "exchange";
}
msg += "ExecutionMode=" + tradeExeMode + " (" + tradeExeModeString + ")\n";
msg += "Digits/Point=" + digits + " / " + point + " " + symbolProfitCcy + "\n";
msg += "LotSize=" + MarketInfo(Symbol(), MODE_LOTSIZE) + " " + symbolMarginCcy + "\n";
msg += "LotStep=" + MarketInfo(Symbol(), MODE_LOTSTEP) + "\n";
msg += "MinLot=" + MarketInfo(Symbol(), MODE_MINLOT) + "\n";
msg += "MaxLot=" + MarketInfo(Symbol(), MODE_MAXLOT) + "\n";
msg += "TickSize=" + MarketInfo(Symbol(), MODE_TICKSIZE) + " " + symbolProfitCcy + "\n";
msg += "TickValue=" + MarketInfo(Symbol(), MODE_TICKVALUE) + " " + ccy + "\n";
msg += "MarginRequired=" + MarketInfo(Symbol(), MODE_MARGINREQUIRED) + " " + ccy + "\n";
msg += "MarginInit=" + MarketInfo(Symbol(), MODE_MARGININIT) + " " + ccy + "\n";
msg += "MarginMaintenance=" + MarketInfo(Symbol(), MODE_MARGINMAINTENANCE) + " " + ccy + "\n";
msg += "MarginHedged=" + MarketInfo(Symbol(), MODE_MARGINHEDGED) + " " + ccy + "\n";
double stopLevel = MarketInfo(Symbol(), MODE_STOPLEVEL);
msg += "StopLevel=" + stopLevel + " point (" + DoubleToString(stopLevel * point, digits) + ")\n";
double freezeLevel = MarketInfo(Symbol(), MODE_FREEZELEVEL);
msg += "FreezeLevel=" + freezeLevel + " point (" + DoubleToString(freezeLevel * point, digits) + ")\n";
msg += "Starting/Expiration=" + MarketInfo(Symbol(), MODE_STARTING) + "/" + MarketInfo(Symbol(), MODE_EXPIRATION) + "\n";
int profitCalcMode = MarketInfo(Symbol(), MODE_PROFITCALCMODE);
string profitCalcModeString;
switch (profitCalcMode) {
case 0:
profitCalcModeString = "Forex";
break;
case 1:
profitCalcModeString = "CFD";
break;
default:
profitCalcModeString = "Futures";
}
msg += "ProfitCalcMode=" + profitCalcMode + " (" + profitCalcModeString + ")\n";
int marginCalcMode = MarketInfo(Symbol(), MODE_MARGINCALCMODE);
string marginCalcModeString;
switch (marginCalcMode) {
case 0:
marginCalcModeString = "Forex";
break;
case 1:
marginCalcModeString = "CFD";
break;
case 2:
marginCalcModeString = "Futures";
break;
default:
marginCalcModeString = "CFD for indices";
}
msg += "MarginCalcMode=" + marginCalcMode + " (" + marginCalcModeString + ")\n";
Alert(msg);
return(0);
}
string B(const bool b) {
return b ? "true" : "false";
}
string T(const datetime t) {
return TimeToString(t, TIME_DATE | TIME_SECONDS);
}
実行結果例
=== Account information === Company/Server=*** / *** TradeAllowed=true TradeExpertAllowed=true LimitOrders=200 Currency=JPY Leverage=888 MarginCallLevel=50% StopoutLevel=20% === Margin status === Balance=4998160 JPY Credit=0 JPY Profit/Loss=-14082 JPY Equity=4984078 JPY Margin=6551.61309959 JPY FreeMargin=4977526.38690041 JPY (Floating P/L is used) === Time information === Local/ServerTime(Offset)=2020.05.16 04:44:38 / 2020.05.15 22:44:37 (6.0) === Current market information === Symbol=USDCHF TickTimestamp/Bid/Ask(Spread)=2020.05.15 22:44:32 0.97241/0.97259(18/variable) Low/High=0.96972/0.97436 SwapLong/Short=-0.35/-5.01 point === Symbol information === TradeAllowed=true CloseByAllowed=true TradeMode=2 (full) ExecutionMode=2 (market) Digits/Point=5 / 0.00001 CHF LotSize=100000 USD LotStep=0.01 MinLot=0.01 MaxLot=10000 TickSize=0.00001 CHF TickValue=110.261 JPY MarginRequired=12077.59 JPY MarginInit=0 JPY MarginMaintenance=0 JPY MarginHedged=0 JPY StopLevel=50 point (0.00050) FreezeLevel=0 point (0.00000) Starting/Expiration=0/0 ProfitCalcMode=0 (Forex) MarginCalcMode=0 (Forex)