Summary: This article exposes the undocumented broker practice of appending tags to OrderComment, breaking EA logic. It provides a battle-tested UUID mapping system and a multi-layered identification model to ensure robust trade management.




Let’s talk about the OrderComment(). It looks innocent enough. You throw a string in there when you call OrderSend(), and you feel smart because you can look at the history tab and see "Strategy_Alpha_Entry_01". You're a coding god.

Stop right there. You just built a house of cards.

The Broker's Silent Hijack



You know what happens when that order gets closed by Take Profit? Let me show you. You send OrderSend() with a comment: "Strategy_Alpha". You run your EA, it opens a trade, it hits the TP. You then do a Print(OrderComment()) in your history selection logic expecting "Strategy_Alpha". What do you get?

I got "Strategy_Alpha[tp]" .

And I'm not the only one. Another guy in the forums reports "0[tp]" . Some brokers add [sl], some add [br] (breakeven?), some might even strip your comment entirely. The point is: Your comment is not your comment once it hits the broker's server.

"Not a good idea to use comments, brokers can change comments, including complete replacement."


This is a massive, massive problem because a huge number of "advanced" EAs use OrderComment as a primary filter for multi-strategy management. They loop through orders and do if(OrderComment() == "Strategy_A"). They are literally praying their broker doesn't change the text.

The "Unique Strategy" Mirage



I used to run an EA with three sub-strategies: a trend follower, a mean-reversion scalper, and a grid hedger. I used comments to distinguish them. It worked flawlessly in backtesting. In forward testing? Disaster.

The mean-reversion scalper hit its TP, the broker appended [tp]. Now the comment is "Scalper[tp]". My main loop checks if(OrderComment() == "Scalper"). It's false. The EA loses track of the trade. It can't manage the trailing stop for that specific ticket anymore because it doesn't know which "group" it belongs to.

The "Ticket" Trap



You might think, "Okay, I'll just use the ticket number." Sure, that identifies the order, but it doesn't solve the grouping problem. How do you know what strategy a ticket belongs to if the comment is corrupt?

The MagicNumber vs. Comment Debate



Some purists say, "Just use MagicNumber for everything." You can assign a unique MagicNumber to each strategy. For example, Trend = 1001, Scalper = 1002. This is objectively the correct and safest way to filter from a technical standpoint .

So why do we even use Comment?

Because MagicNumber is a horror show for human readability. Imagine running 5 EAs on 3 symbols. Your MagicNumber list looks like a spreadsheet vomit. You stare at the Trade tab in MT4, and you see MagicNumber 1001 and 1002. You have no idea what those mean unless you check the EA code. The OrderComment is for us, the humans, so we can glance at the history and understand what happened without pulling out a reference sheet .

Reference: As noted in the MQL4 community, "use the 'magic number' to identify a basket or group of trades" is the fundamental best practice . The comment is auxiliary data .

The Solution: The UUID Mapping Layer



You need to stop treating OrderComment as a reliable piece of data. Treat it as a volatile, read-only human annotation.

I developed a system I call the "UUID Mapping Layer."

Here is the core of the system:

``cpp
//+------------------------------------------------------------------+
//| UUID_Manager.mq4 |
//| The Fix for Comment Corruption |
//+------------------------------------------------------------------+
#property strict

// We map a Unique ID (ticket) to a Strategy Group.
struct StrategyMapping {
int ticket;
int groupID; // Our internal strategy group ID
string originalComment; // Just for logging, don't rely on it!
};

StrategyMapping map[];

//+------------------------------------------------------------------+
//| Open a trade using the mapping system |
//+------------------------------------------------------------------+
int OpenTradeWithUUID(string symbol, int cmd, double volume, double price, int slippage, double sl, double tp, int groupID, string comment) {
// 1. Send the order. We include a base comment but we don't care what happens to it.
int ticket = OrderSend(symbol, cmd, volume, price, slippage, sl, tp, comment, 1000 + groupID, 0, clrNONE);
// The MagicNumber is now 1000 + groupID. It is our primary KEY for filtering.
// The comment is just for visual reference.

if(ticket > 0) {
// 2. Store the mapping in our array.
ArrayResize(map, ArraySize(map) + 1);
map[ArraySize(map)-1].ticket = ticket;
map[ArraySize(map)-1].groupID = groupID;
map[ArraySize(map)-1].originalComment = comment;
Print("Order placed: ", ticket, " | Group: ", groupID);
}
return ticket;
}

//+------------------------------------------------------------------+
//| Get Strategy Group ID for a Ticket |
//+------------------------------------------------------------------+
int GetGroupIDByTicket(int ticket) {
for(int i = 0; i < ArraySize(map); i++) {
if(map[i].ticket == ticket) return map[i].groupID;
}
return -1; // Not found
}

//+------------------------------------------------------------------+
//| Main Loop: Checking Orders |
//+------------------------------------------------------------------+
void CheckOrders() {
for(int i = OrdersTotal() - 1; i >= 0; i--) {
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
// STEP 1: Filter by MagicNumber to only get our EAs orders.
// Remember, MagicNumber is safe and cannot be modified by the broker!
if(OrderMagicNumber() >= 1000 && OrderMagicNumber() < 2000) {
int groupID = OrderMagicNumber() - 1000;

// STEP 2: We don't use OrderComment() at all for logic.
// We use the MagicNumber to determine the group.
switch(groupID) {
case 1: ManageTrendStrategy(OrderTicket()); break;
case 2: ManageScalperStrategy(OrderTicket()); break;
}
}
}
}
}
`

Why this works:
  • <strong>MagicNumber is a pure integer.</strong> The broker cannot modify it. Ever. It is the only reliable filter for identifying an order's source or "group" .

  • <strong>We use MagicNumber as our primary grouping key.</strong> We don't rely on the string comparison that fails when the broker appends [tp] or [sl].

  • <strong>The Comment is purely for display.</strong> If the broker changes it, I don't care. My EA logic ignores it.


  • The Advanced "Four-Dimensional" Model



    For high-frequency or high-density EAs (like grid systems), I've upgraded this model to what I call the "4-Dimensional Identification Model" :

  • Dimension 1: MagicNumber. The absolute primary key.

  • Dimension 2: OrderOpenTime(). To isolate specific sessions or batches.

  • Dimension 3: OrderType(). To separate Buy vs. Sell within the same group.

  • Dimension 4: Custom Hash (Optional). If you must use a comment for some reason, use StringFind(OrderComment(), "MyPrefix") != -1 rather than == so you can handle the broker's appended garbage .


  • My Pragmatic Conclusion



    Stop overcomplicating your EA. Stop trying to use
    OrderComment as a logical identifier. It's a text field meant for your eyes, not your code's logic. Use MagicNumber for machine filtering. Use OrderComment for human reading.

    I've burned weeks fixing bugs that were caused by brokers modifying
    OrderComment. The fix was simple: I stripped the comment out of my logic entirely and used a layered MagicNumber system. It's boring. It's simple. It works.

    Reference: The official MQL4 documentation and developer community consensus is clear:
    OrderMagicNumber() is the designated function for identification . Deviating from this by using OrderComment()` as a primary key is an anti-pattern.

    本文首发于FXEAR.com,原创内容,未经授权禁止转载。