チェックアップのIsDemo()について、MQL4とMQL5のソースコード共通化する方法を説明しています。
関数定義
MQL4の定義
bool IsDemo();
MQL5の定義
定義なし
MQL5にデモ口座かを取得する関数はありません。ただしAccountInfoInteger()を使う事で同等の処理を行うことが出来ます。
その処理を利用して、MQL4とMQL5のソースコード共通化を行います。
共通化方法
ソース共通化
対処方法
共通化するためにMQL5用の定義をします。
#ifdef __MQL5__ ~ #endifを使用することでMQL5のコンパイルにのみ有効となります。
MQL4の場合は「__MQL4__」を使用しますが、今回使用していないためMQL4は既存で組み込まれた組込み関数が利用されます。
#ifdef __MQL5__
#define IsDemo() ((bool)AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_DEMO)
#endif
MQL5ではAccountInfoInteger()を利用することで口座の状態を取得することができるため、デモ口座かどうかの判断を行います。
デモ口座かどうかを判定して、EAを動かすかどうかの判定に利用するユースケースがありますが、MT4とMT5のデモ口座には使用期限が存在しています。
使用期限が存在しているとデモ口座として認識することができますが、あるブローカーではデモ口座の申請で入手した口座でもデモ口座と判断されないケースがあるので注意してください。
デモ口座と判断されないケースが使用期限のない口座である傾向が多いと感じます。
とあるブローカーではデモ口座の使用期限をなくしてもらえるらしいのですが、そのデモ口座がデモ口座と判断されなかった経験があります。
使用例
このソースコードは私が作成するEA、インジケーターのすべてに組み込むログ出力のマクロ(#define)です。
以下の用途で、表示条件や表示内容を変えてログに出力するための定義です。
- エラー発生をログに出力したい
- テスト時にログに出力したい
- 情報をログに出力(常時、デモ口座時)したい(※IsDemo())
///////////////////////////////////////////////////////////////////////////////
// ログ出力マクロ
#define LOG(Message, Val) (Error(__FUNCTION__ + "(" + IntegerToString(__LINE__) + ") : " + Message, Val, 0))
#define INF(Message, Val) (Error(__FUNCTION__ + "(" + IntegerToString(__LINE__) + ") : " + Message, Val, 1))
#define ERR(Message, Val) (Error(__FUNCTION__ + "(" + IntegerToString(__LINE__) + ") : " + Message, Val, 2, true))
void Error(const string strError, double dVal, int iKind, bool bIsErr = false)
{
if (bIsErr) {
int iError = GetLastError();
Print("■■ ERR : #", iError, " :", strError, " :", dVal);
} else {
if (1 == iKind) {
Print("●○ INF : ", strError, " :", dVal);
} else if (IsTesting() || IsDemo()) {
Print("●● LOG : ", strError, " :", dVal);
}
}
}
以下の関数については別途説明します。
ログマクロの使い方
int OnInit()
{
#ifdef __MQL5__
Print("これはMT5で動作しています");
#else //__MQL4__
Print("これはMT4で動作しています");
#endif
return(INIT_SUCCEEDED);
}
void OnTick()
{
int iOrderTicket = 12345;
INF("iOrderTicket", iOrderTicket);
bResult = OrderDelete(iOrderTicket);
if (!bResult) {
ERR("OrderDelete()", iOrderTicket);
}
LOG("OrderDelete()終了", iOrderTicket);
}
MT5での実行結果
INF()、ERR()、LOG()を使い分けている例です。
LOG()はデモ口座とバックテスト中しか出力されないログですので、あくまでも実際の運用前のデバック用としてログ出力します。
ERR()、INF()はいつでも出力したいログです。
コメント