MQL4の共通関数・変換関数を体系的にまとめました。Alert()・Comment()・Print()・PrintFormat()による出力関数、Sleep()による待機、GetTickCount()によるミリ秒計測、SendMail()・SendNotification()・PlaySound()による通知、IsStopped()・UninitializeReason()によるEA状態確認、型変換関数(NormalizeDouble, DoubleToStr, IntegerToString等)、色・日時・列挙型の変換まで、MT4 EA開発に必要な共通処理のすべてをコード付きで解説します。
目次
MQL4とMQL5の共通関数の違い
| 機能 | MQL4 | MQL5 |
|---|---|---|
| アラート | Alert() | Alert() |
| チャートコメント | Comment() | Comment() |
| ログ出力 | Print() | Print() |
| フォーマット出力 | PrintFormat()(ビルド600+) | PrintFormat() |
| メール送信 | SendMail() | SendMail() |
| プッシュ通知 | SendNotification() | SendNotification() |
| サウンド | PlaySound() | PlaySound() |
| 型変換(double) | DoubleToStr() | DoubleToString() |
| 型変換(str→num) | StrToDouble(), StrToInteger() | StringToDouble(), StringToInteger() |
出力関数
Print / PrintFormat
void OutputExamples()
{
// Print — エキスパートタブに出力
Print("メッセージ: ", Symbol(), " Price=", Ask);
// 複数引数を連結して出力
Print("Balance=", AccountBalance(),
" Equity=", AccountEquity(),
" Margin=", AccountMargin());
// PrintFormat — printf形式(ビルド600+)
PrintFormat("Ticket: %d, Price: %.5f, Lots: %.2f",
12345, Ask, 0.1);
PrintFormat("[%s] %s %s %.2f @ %.5f",
TimeToStr(TimeCurrent(), TIME_MINUTES),
Symbol(), "BUY", 0.1, Ask);
}Comment
void UpdateComment()
{
string text = "";
text += "=== EA Status ===\n";
text += "Time: " + TimeToStr(TimeCurrent(), TIME_DATE|TIME_SECONDS) + "\n";
text += "Balance: " + DoubleToStr(AccountBalance(), 2) + "\n";
text += "Equity: " + DoubleToStr(AccountEquity(), 2) + "\n";
text += "Spread: " + IntegerToString((int)MarketInfo(Symbol(), MODE_SPREAD)) + " pts\n";
text += "Positions: " + IntegerToString(OrdersTotal()) + "\n";
Comment(text); // チャートの左上に表示
// クリアする場合
// Comment("");
}Alert
void CheckAlertCondition()
{
static datetime lastAlert = 0;
// 1時間に1回だけアラート
if(TimeCurrent() - lastAlert < 3600)
return;
double dd = (AccountBalance() - AccountEquity()) / AccountBalance() * 100;
if(dd > 10) // ドローダウン10%超
{
Alert("警告: ドローダウン ", DoubleToStr(dd, 1), "% - ",
Symbol(), " Balance=", AccountBalance());
lastAlert = TimeCurrent();
}
}出力関数の使い分け
- Print(): エキスパートタブに出力。デバッグに最適。パフォーマンスへの影響は小さい
- Comment(): チャートの左上に表示。リアルタイムモニタリングに最適。最大1行あたり約250文字
- Alert(): ダイアログ表示+サウンド。重要な通知のみに使用。OnTick内で多用するとパフォーマンスが劣化
- PrintFormat(): printf形式。複雑なログ出力に便利(ビルド600+)
出力関数の使い分け
- Print(): エキスパートタブに出力。デバッグに最適。パフォーマンスへの影響は小さい
- Comment(): チャートの左上に表示。リアルタイムモニタリングに最適
- Alert(): ダイアログ表示+サウンド。重要な通知のみに使用
- PrintFormat(): printf形式。複雑なログ出力に便利(ビルド600+)
通知関数
// メール送信(ツール→オプション→Eメールで設定が必要)
void SendTradeEmail(string action, int ticket, double lots, double price)
{
string subject = StringFormat("[%s] %s %s", action, Symbol(), TimeToStr(TimeCurrent()));
string body = StringFormat(
"Action: %s\nSymbol: %s\nTicket: %d\nLots: %.2f\nPrice: %.5f\nBalance: %.2f",
action, Symbol(), ticket, lots, price, AccountBalance()
);
if(!SendMail(subject, body))
Print("メール送信失敗: ", GetLastError());
}
// プッシュ通知(ツール→オプション→通知で設定が必要)
void SendPushNotification(string message)
{
if(!SendNotification(message))
Print("プッシュ通知失敗: ", GetLastError());
}
// サウンド再生
void PlayTradeSound(bool isEntry)
{
if(isEntry)
PlaySound("alert.wav");
else
PlaySound("ok.wav");
}Sleep / GetTickCount
// Sleep — ミリ秒単位の待機
// ※ OnTick()内での使用は推奨されない(ティック処理がブロックされる)
void WaitAndRetry()
{
Sleep(1000); // 1秒待機
RefreshRates();
}
// GetTickCount — ミリ秒精度のタイマー
void MeasureExecutionTime()
{
uint startTime = GetTickCount();
// 計測したい処理
for(int i = 0; i < 1000; i++)
double ma = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, i);
uint elapsed = GetTickCount() - startTime;
Print("処理時間: ", elapsed, "ms");
}EA状態チェック関数
| 関数 | 戻り値 | 説明 |
|---|---|---|
| IsStopped() | bool | EA停止が要求されているか |
| IsTradeAllowed() | bool | 自動売買が許可されているか |
| IsConnected() | bool | サーバーに接続されているか |
| IsDemo() | bool | デモ口座か |
| IsTesting() | bool | バックテスト中か |
| IsOptimization() | bool | 最適化中か |
| IsVisualMode() | bool | ビジュアルモードか |
| IsExpertEnabled() | bool | EA実行が有効か |
| IsTradeContextBusy() | bool | 取引コンテキストがビジーか |
| IsLibrary() | bool | ライブラリとして実行中か |
| UninitializeReason() | int | 終了理由コード |
| TerminalInfoInteger() | long | ターミナル情報(ビルド600+) |
bool CheckEAReady()
{
if(IsStopped())
{
Print("EA停止が要求されました");
return false;
}
if(!IsTradeAllowed())
{
Print("自動売買が許可されていません");
return false;
}
if(!IsConnected())
{
Print("サーバー未接続");
return false;
}
if(IsTradeContextBusy())
{
Print("取引コンテキストビジー");
return false;
}
return true;
}
// テスト環境の判定
void DetectEnvironment()
{
if(IsTesting())
{
if(IsOptimization())
Print("最適化モード");
else if(IsVisualMode())
Print("ビジュアルバックテスト");
else
Print("通常バックテスト");
}
else
{
if(IsDemo())
Print("デモ口座でライブ稼働");
else
Print("本番口座でライブ稼働");
}
}テスト環境での注意
- IsTesting()中はSendMail/SendNotification/Alert/PlaySoundが実行されても実際には送信されない(サイレント)
- Sleep()はバックテスト中は無視される(0ミリ秒で即座に完了)
- IsVisualMode()がtrueの場合のみ、Comment()やオブジェクト描画が表示される
- 最適化中(IsOptimization())はPrint()すらパフォーマンスに影響するため、最小限に抑える
テスト環境での注意
- IsTesting()中はSendMail/SendNotification/Alert/PlaySoundが実行されても実際には送信されない(サイレント)
- Sleep()はバックテスト中は無視される(0ミリ秒で即座に完了)
- IsVisualMode()がtrueの場合のみ、Comment()やオブジェクト描画が表示される
- 最適化中(IsOptimization())はPrint()すらパフォーマンスに影響するため、最小限に抑える
型変換関数
| 関数 | 変換 | 例 |
|---|---|---|
| NormalizeDouble(v, d) | double → 正規化double | NormalizeDouble(1.23456, 3) = 1.235 |
| DoubleToStr(v, d) | double → string | DoubleToStr(1.5, 2) = “1.50” |
| IntegerToString(v) | int → string | IntegerToString(42) = “42” |
| StrToDouble(s) | string → double | StrToDouble(“1.5”) = 1.5 |
| StrToInteger(s) | string → int | StrToInteger(“42”) = 42 |
| TimeToStr(t, mode) | datetime → string | TimeToStr(now) = “2024.06.15 14:30” |
| StrToTime(s) | string → datetime | StrToTime(“2024.06.15”) = datetime |
| ColorToString(c) | color → string | ColorToString(clrRed) = “255,0,0” |
| StringToColor(s) | string → color | StringToColor(“255,0,0”) = clrRed |
| CharToStr(c) | int → string | CharToStr(65) = “A” |
| StringGetChar(s, p) | string → int | StringGetChar(“A”, 0) = 65 |
RefreshRates()はMQL4特有の重要関数です。MQL5では不要ですが、MQL4ではSleep()後やリトライ前に呼ばないと古い価格でOrderSendしてしまいERR_REQUOTE(138)が発生します。OrderSendのリトライループには必ずRefreshRates()を入れましょう。
RefreshRates()はMQL4特有の重要関数です。MQL5では不要ですが、MQL4ではSleep()後やリトライ前に呼ばないと古い価格でOrderSendしてしまいERR_REQUOTE(138)が発生します。OrderSendのリトライループには必ずRefreshRates()を入れましょう。
その他の共通関数
| 関数 | 説明 |
|---|---|
| ExpertRemove() | EAを自動的にチャートから削除 |
| TerminalClose(reason) | ターミナルを終了 |
| MessageBox(text, caption, flags) | メッセージボックス表示(ライブのみ) |
| RefreshRates() | 最新レートを再取得 |
| MarketInfo() | マーケット情報取得 |
| GetTickCount() | ミリ秒タイマー |
| MathRand() | 乱数生成 |
実践: 総合的な通知システム
enum NOTIFY_LEVEL
{
NOTIFY_LOG, // Printのみ
NOTIFY_ALERT, // Alert + Print
NOTIFY_PUSH, // Push通知 + Print
NOTIFY_ALL // 全通知
};
input NOTIFY_LEVEL NotifyLevel = NOTIFY_ALERT;
void Notify(string message, NOTIFY_LEVEL level = NOTIFY_LOG)
{
// 常にPrint
Print("[", Symbol(), "] ", message);
if(IsTesting()) return; // テスト中は通知しない
if(level >= NOTIFY_ALERT && NotifyLevel >= NOTIFY_ALERT)
Alert(message);
if(level >= NOTIFY_PUSH && NotifyLevel >= NOTIFY_PUSH)
SendNotification(Symbol() + ": " + message);
if(NotifyLevel >= NOTIFY_ALL)
{
string subject = "[EA] " + Symbol();
SendMail(subject, message);
}
}
// 使用例
void OnTradeEvent(string action, int ticket)
{
string msg = StringFormat("%s ticket=%d lots=%.2f profit=%.2f",
action, ticket, OrderLots(), OrderProfit());
Notify(msg, NOTIFY_ALERT);
}共通関数一覧(MQL5対応表)
| MQL4関数 | MQL5対応 | 説明 |
|---|---|---|
| Alert() | Alert() | アラートダイアログ |
| Comment() | Comment() | チャートコメント |
| Print() | Print() | エキスパートログ出力 |
| PrintFormat() | PrintFormat() | フォーマット出力 |
| SendMail() | SendMail() | メール送信 |
| SendNotification() | SendNotification() | プッシュ通知 |
| PlaySound() | PlaySound() | サウンド再生 |
| Sleep() | Sleep() | ミリ秒待機 |
| GetTickCount() | GetTickCount() | ミリ秒タイマー |
| IsTesting() | MQLInfoInteger(MQL_TESTER) | テスト中判定 |
| IsOptimization() | MQLInfoInteger(MQL_OPTIMIZATION) | 最適化中判定 |
| IsTradeAllowed() | MQLInfoInteger(MQL_TRADE_ALLOWED) | 取引許可判定 |
| IsConnected() | TerminalInfoInteger(TERMINAL_CONNECTED) | 接続状態判定 |
| IsDemo() | AccountInfoInteger(ACCOUNT_TRADE_MODE)==DEMO | デモ口座判定 |
| RefreshRates() | 不要(自動更新) | レート再取得 |
| ExpertRemove() | ExpertRemove() | EA自動削除 |
| DoubleToStr() | DoubleToString() | double→文字列 |
| StrToDouble() | StringToDouble() | 文字列→double |
| StrToInteger() | StringToInteger() | 文字列→int |
まとめ
MQL4の共通関数はEA開発の基盤となる機能を提供します。重要なポイントは以下の通りです。
- Print()でデバッグ、Comment()でリアルタイム表示 — 開発中はPrint()、本番ではComment()を使い分ける
- IsTesting()でテスト/本番を分岐 — 通知やSleep()はテスト中にスキップする
- RefreshRates()はリトライ前に必ず呼ぶ — MQL5では不要だがMQL4では必須
- DoubleToStr()→DoubleToString()の名称変更に注意(MQL5移植時)
全13カテゴリの学習は、MQLリファレンス総合ガイドを起点に進めましょう。MQL4の基本を押さえたら、実際のEA開発に取り組んでみてください。





