Every MQL developer hits a wall: your Expert Advisor opens trades at the wrong price, your indicator paints lines that don't match the chart, or your script silently does nothing. You stare at the code, re-read the logic, and still can't see the bug. The fastest way to find it isn't a complex debugger — it's the humble Print() function and the Experts journal tab. This guide teaches you a systematic print-debugging workflow that works identically in MQL4 and MQL5, turning the journal into your personal code inspector.
What You Will Achieve
By the end of this guide you will be able to trace any MQL program's execution flow, inspect variable values at runtime, detect logic errors in conditions, and log the exact sequence of events leading to a bug. You'll learn to use Print(), Comment(), Alert(), and the MQLInfoInteger() function to build a debug output system that works in both live trading and the Strategy Tester. You will also master the Experts journal — the tab most traders ignore but every developer depends on.
Prerequisites
- MetaTrader 4 or 5 — any build from 2020 or newer. MT4 uses the MQL4 compiler; MT5 uses MQL5. The
Print()function syntax is identical in both. - MetaEditor — the built-in code editor. Open it from Tools → MetaQuotes Language Editor (MT4) or Tools → MetaEditor (MT5).
- An MQL project — any EA, indicator, or script you want to debug. If you have none, create a new empty EA: File → New → Expert Advisor → Next → Name it "DebugDemo" → Finish.
- A demo account — never debug on a live account. Use the Strategy Tester or a demo account for safe testing.
Step-by-Step: The MQL Print Debugging Workflow
1. Understand the Experts Journal
The Experts tab is in the Terminal window (View → Terminal, or Ctrl+T). It has two parts: the main pane shows messages from your MQL programs, and the dropdown at the bottom lets you filter by program name. Every Print() statement sends text here. The journal also shows compilation errors, order execution results, and system messages. Clear it before each test run by right-clicking → Clear.
2. The Core Debugging Commands
MQL provides four output functions. Use them deliberately:
| Function | Output Location | Best Use |
|---|---|---|
| Print() | Experts journal | Persistent log of values and events. Use for tracing execution flow. |
| Comment() | Top-left corner of chart | Real-time display of current values. Overwrites every tick. |
| Alert() | Popup dialog box | Critical breakpoints that pause your attention. Use sparingly. |
| SendNotification() | Mobile push (MT4/MT5 app) | Remote debugging when you can't watch the terminal. |
3. Insert Strategic Print Statements
Open your MQL file in MetaEditor. Find the OnTick() function (for EAs) or OnCalculate() (for indicators). Insert Print() at key decision points. For example, to see when your EA thinks it should enter a trade:
// Inside OnTick()
double currentRSI = iRSI(NULL, 0, 14, PRICE_CLOSE, 0);
Print("Tick: Time=", TimeCurrent(), " Bid=", Bid, " RSI=", currentRSI);
if(currentRSI < 30)
{
Print("RSI below 30 — checking for trade entry");
// ... entry logic ...
}
else
{
Print("RSI above 30 — no entry");
}
Compile the code (F7 in MetaEditor). Attach the EA to a chart or run it in the Strategy Tester. Open the Experts tab — you will see a timestamped log of every tick with the RSI value and the decision path.
4. Use String Formatting for Clarity
Raw numbers are hard to scan. Format your output with labels and separators. Use the StringFormat() function for clean alignment:
Print(StringFormat("Bid=%.5f | Ask=%.5f | Spread=%d | RSI14=%.2f", Bid, Ask, (int)(Ask-Bid)/Point, currentRSI));
This prints: Bid=1.12345 | Ask=1.12367 | Spread=2 | RSI14=28.45. Much easier to read than a jumble of numbers.
5. Trace the Full Execution Path
For complex EAs with multiple conditions, add a unique identifier to each Print() so you can follow the flow. Use a simple counter or the __LINE__ macro:
// MQL4 and MQL5 support __LINE__ macro
Print("[DEBUG Line ", __LINE__, "] Entered OnTick for symbol ", _Symbol);
This immediately tells you which line of code generated the message. Combine with __FUNCTION__ for even more context:
Print("[", __FUNCTION__, ":", __LINE__, "] Checking moving average crossover");
6. Debug in the Strategy Tester
The Strategy Tester is the best environment for print debugging because you can replay history. Run a single backtest with Every tick mode (MT5) or Control points (MT4) and watch the Experts journal fill up. To slow down the output, add a Sleep(100) inside the tester — but note that Sleep() only works in the tester, not live. For MT4, use:
if(IsTesting()) Sleep(100);
7. Use Conditional Compilation to Toggle Debug Output
Never leave debug prints in a production EA — they slow it down and fill the journal. Use a #define flag to turn debugging on and off:
// At the top of your EA
#define DEBUG_MODE // Comment this line to disable all debug prints
// In OnTick()
#ifdef DEBUG_MODE
Print("Debug: Balance=", AccountBalance());
#endif
When DEBUG_MODE is defined, all Print() inside #ifdef blocks compile. Comment it out, recompile, and the debug code disappears from the executable entirely — zero performance cost.
Tips and Best Practices from Experience
- Always print the timestamp. Use
TimeCurrent()(live) orTime[0](tester) so you can correlate log entries with chart bars. - Use
Comment()for live charts. It updates every tick and doesn't fill the journal. Perfect for monitoring real-time values without scrolling. - Don't print inside loops without a guard. A loop over 10,000 bars will generate 10,000 journal entries per tick. Add a condition like
if(i % 100 == 0)to print every 100th iteration. - Clear the journal before each test. Right-click the Experts tab → Clear. Old entries can confuse you.
- Use
MQLInfoInteger(MQL_DEBUG)to check if you're running in MetaEditor's debug mode (MT5 only). This lets you have debug code that only runs during a debugging session. - Log order operations immediately. After
OrderSend()(MT4) orPositionOpen()(MT5), print the ticket number and the result code. This catches silent failures.
Common Mistakes and Troubleshooting
Mistake 1: Print() doesn't appear in the Experts journal
Cause: The EA or indicator isn't running. Check the chart's top-right corner — you should see a smiley face (for EAs) or the indicator name. If you see a red X, the program has errors. Open the Experts journal and look for red error lines.
Fix: Recompile the code. Ensure AutoTrading is enabled (the AutoTrading button in MT4/MT5). For indicators, ensure you attached them to the correct chart timeframe.
Mistake 2: The journal fills up too fast and slows the terminal
Cause: Printing on every tick in a fast market, or printing inside a loop without a limit.
Fix: Add a print throttle. Track the last print time and only print every N seconds:
static datetime lastPrint = 0;
if(TimeCurrent() - lastPrint >= 1) // Print once per second
{
Print("Current spread: ", (Ask-Bid)/Point);
lastPrint = TimeCurrent();
}
Mistake 3: Print() output is truncated or garbled
Cause: The Experts journal has a character limit per line (typically 1024 characters in MT4, 4096 in MT5). Long strings get cut off.
Fix: Break long messages into multiple Print() calls. Use StringConcatenate() or StringFormat() to build strings efficiently, but keep each call under the limit.
Mistake 4: Forgetting to remove debug prints from the final EA
Cause: Rushing to deploy after debugging. The debug prints remain in the compiled EX4/EX5 file and will fill the user's journal.
Fix: Use the conditional compilation technique (#ifdef DEBUG_MODE) described above. Before compiling the release version, comment out the #define DEBUG_MODE line and recompile. Verify no debug output appears in a quick test.
Summary and Next Steps
Print debugging is the most accessible and effective way to understand what your MQL code is actually doing. By strategically placing Print() statements, formatting the output for readability, and using conditional compilation, you can diagnose any logic error, order execution failure, or indicator miscalculation. The Experts journal is your window into the runtime behavior of your programs — treat it as your primary diagnostic tool.
Next steps: Practice on a simple EA. Add a deliberate bug (e.g., an incorrect price comparison) and use print statements to find it. Then try the same exercise in the Strategy Tester with a 1-minute timeframe and 10,000 ticks. Once comfortable, explore MetaEditor's built-in debugger (MT5 only) for step-through debugging — but you'll find that a well-placed Print() often solves the problem faster than setting breakpoints.
Frequently Asked Questions
Can I use Print() inside an indicator's OnCalculate() function?
Yes, absolutely. It works the same as in EAs. Each time OnCalculate() is called (on each tick or bar update), your Print() statements write to the Experts journal. For indicators that recalculate on every tick, consider using a print throttle to avoid excessive log entries.
How do I print an array or a struct in MQL4?
MQL4 does not have a built-in array-to-string function. Loop through the array and print each element: for(int i=0; i

