MQL5 Printf, PrintFormat & Comment: Logging & Chart Displays
Guide to MQL5 printf, PrintFormat, StringFormat, and Comment functions. Format floating-point numbers, output structured logs, and build on-chart dashboards.
What this MQL5 guide covers
In MQL5, printf() is a direct functional alias for PrintFormat(); both print formatted strings into the Experts terminal log.
Use format specifiers such as %.5f for currency quotes, %I64u for 64-bit tickets, %s for text, and TimeToString followed by %s for datetime display.
StringFormat() formats text into a string variable without printing, making it the standard choice for multi-line status HUDs.
The Comment() function writes text directly into the upper-left corner of the chart, and calling Comment("") clears the display on deinit.
Print vs PrintFormat vs printf in MQL5
The standard Print() function in MQL5 concatenates parameters separated by commas with default type formatting. While simple, it provides little control over decimal precision, alignment, or leading zeros.
PrintFormat() and its alias printf() bring C-style format strings to MQL5. They accept a format specification string followed by argument values, outputting directly to the terminal Experts tab.
| Format Specifier | Target Data Type | Example Output |
|---|---|---|
| %d or %i | int, short, char | 14, -200 |
| %u | uint, ushort, uchar | 500 |
| %I64u / %I64d | ulong (ticket, magic), long | 12004589211 |
| %.2f | double (percentage, currency) | 1250.50 |
| %.5f | double (forex exchange rate) | 1.08452 |
| %s | string | EURUSD |
| %s with TimeToString | formatted datetime string | 2026.10.01 14:30 |
Constructing On-Chart Status Panels with Comment()
The Comment() function projects text onto the upper-left region of the chart window. It serves as an accessible display tool for displaying real-time EA status without creating complex graphical panel objects.
To build multi-line dashboards, combine StringFormat() with newline escape sequences (\n). Update the comment inside OnTick() or on a timer event.
- Each call to Comment() replaces the previous chart comment completely.
- Passing an empty string Comment("") clears the chart display.
- Programs share one chart-comment surface; the latest Comment call replaces the previous text, regardless of attachment order.
Formatting Memory vs Terminal Output: StringFormat
While printf() sends text straight to the log, StringFormat() generates and returns a formatted string without producing terminal I/O. Use StringFormat() whenever you need to save text into files, send Telegram alerts, or render chart labels.
StringFormat gives explicit type and precision control. No benchmark here establishes that it is faster than concatenation; the specifiers and argument types must match.
Production Logging and Terminal Performance
Excessive logs can add overhead and obscure diagnostics. Terminal Expert logs are stored under MQL5/Logs; tester logs have their own agent context. Measure the actual workload rather than assuming a fixed performance penalty.
Use a verbosity toggle and event-based logging for normal runs. The official PrintFormat documentation states that it does not work during tester optimization, so do not depend on per-pass printed output as an optimization record.
Implementation details & mechanics
Core implementation pattern
The example prints a configuration banner and displays account balance, equity, floating profit and a count of processed OnTick events. Its risk-percent and magic inputs are display examples only: no order, sizing or signal logic uses them. Currency labels come from the account.
Error handling & safety rules
OnDeinit clears the shared chart comment. That can also clear another program’s most recent text; use uniquely named objects if independent ownership matters. The example does not record closing deals or compute lifetime P/L. A complete trade ledger needs deal history and costs beyond a floating account value.
MQL5 Code Implementation
//+------------------------------------------------------------------+
//| PrintfPrintFormatCommentGuide.mq5|
//| Copyright 2026, Pineify Guides Series |
//| https://pineify.app |
//+------------------------------------------------------------------+
#property copyright "Pineify Guides Series"
#property link "https://pineify.app/mql5/printf-printformat-comment-guide"
#property version "1.00"
#property strict
//--- Input parameters
input double InpRiskPercent = 1.5; // Display-only example (%)
input ulong InpMagicNumber = 884400; // Expert Magic Number
input bool InpVerboseLog = true; // Enable Detailed Logging
//--- State tracking
ulong g_tickCounter = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// printf() and PrintFormat() are identical in MQL5
printf("=== Pineify EA Initialized: %s ===", _Symbol);
PrintFormat("Settings -> Risk: %.1f%% | Magic: %I64u | Digits: %d | Point: %.5f",
InpRiskPercent, InpMagicNumber, _Digits, _Point);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clear on-chart HUD comment
Comment("");
PrintFormat("EA removed from %s. Cleared HUD. Reason code: %d", _Symbol, reason);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
g_tickCounter++;
// Gather real-time account and market metrics
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double equity = AccountInfoDouble(ACCOUNT_EQUITY);
double profit = AccountInfoDouble(ACCOUNT_PROFIT);
// Build multi-line on-chart dashboard via StringFormat
string hudText = StringFormat(
"------------------------------------------\n" +
" PINEIFY DASHBOARD: %s\n" +
"------------------------------------------\n" +
" Ask: %.*f | Bid: %.*f | Spread: %d pts\n" +
" Account currency: %s | Balance: %.2f | Equity: %.2f\n" +
" Floating PnL: %.2f\n" +
" Processed OnTick events: %I64u\n" +
" Server Time: %s\n" +
"------------------------------------------",
_Symbol,
_Digits, ask, _Digits, bid, spread,
AccountInfoString(ACCOUNT_CURRENCY), balance, equity,
profit,
g_tickCounter,
TimeToString(TimeCurrent(), TIME_DATE|TIME_SECONDS)
);
// Update chart display
Comment(hudText);
// Output formatted log on every 100th tick if verbose mode enabled
if(InpVerboseLog && (g_tickCounter % 100 == 0))
{
PrintFormat("[Tick #%I64u] %s Spread: %d pts | Floating: %.2f %s",
g_tickCounter, _Symbol, spread, profit, AccountInfoString(ACCOUNT_CURRENCY));
}
}
Copy this code into MetaEditor, save it in your MQL5 folder (Experts, Scripts, or Include), and compile with F7.
Generate custom MQL5 code with Pineify AI
Describe the trade execution, indicator calculations, risk management, or data processing logic you need. Pineify generates editable MQL5 source code. Review its logic, request a syntax check, and compile and test the final file in MetaEditor.
Frequently Asked Questions
Related MQL5 pages
Technical references
Risk and testing note
These educational examples require independent compilation and testing. A compile pass or an illustrative setting does not establish execution correctness or profitability. Any reported performance must be supported by reproducible data and test settings; past results do not predict future returns. Trading involves significant risk of loss. This content is not financial advice.