Summary: A practical walkthrough of building a dedicated message window for MT4 using custom indicators. Covers persistent alert history, color coding, and performance considerations.




I got tired of missing alerts. Not because I wasn't paying attention, but because the standard Comment() function in MT4 is basically useless for anything beyond a one-liner. You write a message, it shows up in the top-left corner, then the next tick wipes it out. And Alert() is even worse – a popup that disappears after a few seconds, or a sound that you might not even hear if you're in another room.

Last month I was testing a new EA and kept missing important status updates during backtesting. I'd leave the backtest running, come back an hour later, and have no idea what happened in the middle. No history, no log, just the final result. That's when I dove into the MQL4 documentation and found something most people skip over – the #property indicator_separate_window directive and the ObjectCreate() function for labels .

The Problem With Default Alert Methods



Before I explain the solution, let me break down why the default options suck for anyone running serious backtests or multi-strategy setups.

Comment() displays text in the chart corner. It's simple, but it only shows the last thing you wrote. One tick later, it's gone. If your EA does multiple things in a single tick – opens a trade, modifies a stop, logs an error – you'll only see the final message. Everything before that is lost.

Alert() gives you a popup. Popups are disruptive and they don't stack. If your EA generates three alerts in rapid succession, you might see one and miss the other two.

Print() writes to the Experts tab in the terminal. That's actually useful, but you have to scroll through the log manually, and it's mixed with all the other terminal noise.

What I wanted was something that persists, stacks messages like a chat log, and doesn't require me to scroll through a terminal tab that's filling up with random junk from other EAs.

The Custom Indicator Message Window



The MQL4 documentation actually has a section on this in the "Creation of a Normal Program" chapter. It describes building a custom indicator that exists solely to create a subwindow for displaying text messages using graphical objects . The indicator doesn't do any calculations – it just sits there as a container.

Here's the core idea:
  • You create a custom indicator with #property indicator_separate_window

  • The indicator has no calculations in its OnCalculate() function

  • A separate include file (Inform.mqh) manages the graphical objects that display messages

  • Each new message gets pushed into a vertical list, with older messages moving up


  • The official MQL4 tutorial provides a template. The function Inform() accepts a message number and optional integer/real parameters. It creates a label object for each message, stores the name in an array, and shifts existing messages up by adjusting their Y coordinates .

    Step 1: Create the Container Indicator



    First, create a new custom indicator in MetaEditor. Name it Inform.mq4. Here's the minimal code:

    ``mql4
    //--------------------------------------------------------------------
    // Inform.mq4
    // The code should be used for educational purpose only.
    //--------------------------------------------------------------------
    #property indicator_separate_window // Separate indicator window
    //--------------------------------------------------------------------
    int start() // Special function start()
    {
    }
    //--------------------------------------------------------------------
    `

    That's it. The indicator does nothing on its own. Its sole purpose is to create a subwindow where messages can be displayed. The
    start() function is empty because all the work happens in the include file .

    Step 2: Build the Message Management Logic



    The real work happens in
    Inform.mqh. The MQL4 tutorial provides a full implementation that manages up to 30 message lines, with messages scrolling up as new ones arrive .

    The key functions:

    Inform(0) – called every tick to check if messages have timed out. After 15 seconds without new messages, all displayed messages turn gray. This is a nice touch – it visually indicates when the EA has gone quiet.

    Inform(-1) – deletes all graphical objects when the EA is deinitialized. Cleanup is important because MT4 doesn't automatically delete labels you create.

    Inform(Mess_Number, Number, Value) – the main function. Creates a new message line based on the Mess_Number parameter. Each number corresponds to a specific message template, like "Closed order Buy" or "Not enough money for X lots" .

    The messaging system uses labels stored in an array
    Name_Grf_Txt[30]. When a new message arrives, the function:
  • Deletes the 29th (oldest) message

  • Shifts messages 28 down to 0 up one position

  • Creates a new label at the bottom of the list


  • This gives you a persistent scrollback of the last 30 messages, color-coded by type.

    Step 3: Integrating the Message System Into Your EA



    To use this in your own EA, copy
    Inform.mq4 to your MQL4/Indicators folder and compile it. Then place Inform.mqh in your MQL4/Include folder.

    In your EA, add:

    `mql4
    #include
    `

    And call
    Inform() whenever you want to log something:

    `mql4
    Inform(1, ticket); // "Closed order Buy X"
    Inform(11, 0, lots); // "Not enough money for X lots" (red text)
    `

    The function uses
    PlaySound() alongside the visual message, so you get audio alerts with persistent visual context .

    Why This Is Better Than Anything Else



    This approach solves the "what happened while I was away" problem. When you come back to your trading station after an hour, the message window shows you a complete history of your EA's activity. No scrolling through terminal logs, no wondering if an alert fired that you didn't hear.

    I've been using this for the past three weeks across three different EAs. Each EA has its own message window, so I can monitor each strategy separately without cross-contamination. During backtesting, I can see the entire sequence of events without stopping the test to check logs.

    The Performance Consideration



    One thing to watch out for – creating and deleting graphical objects constantly can slow down your EA if you're generating dozens of messages per second. The MQL4 tutorial's implementation handles up to 30 messages and reuses existing objects instead of creating new ones every time . That keeps performance overhead minimal.

    For high-frequency strategies, you might want to reduce the number of stored messages to 10 or 15. Just adjust the array size and the loop limits in
    Inform.mqh.

    A Real-World Example



    Last week, I was debugging an EA that kept closing trades prematurely. I added
    Inform() calls at every decision point – entry conditions, stop loss triggers, take profit hits. Instead of guessing why the EA was exiting early, I could see the exact sequence in the message window. Turned out to be a logic error in the trailing stop calculation. Without the message history, I would have been debugging blind for hours.

    The official MQL4 book has a full example in the "Combined Use of Programs" chapter that demonstrates this approach alongside
    iCustom()` for indicator-based trading decisions .

    References: MQL4 Documentation – Creation of a Normal Program (book.mql4.com), MQL4 Reference – Custom Indicators (docs.mql4.com), MQL4 Book – Combined Use of Programs (book.mql4.com).

    This article is originally published on FXEAR.com, original content, reproduction without authorization is prohibited.