Position comments are a seemingly small detail in algorithmic trading, yet they play a crucial role in post-trade analysis, strategy debugging, and record-keeping. In MQL5, unlike MQL4’s order-centric approach, trading operations revolve around positions. Understanding how to manage position comments is essential for any serious MQL5 developer.
Introduction to Position Comments in MQL5
What are Position Comments?
Position comments are custom text strings attached to trading positions in the MetaTrader 5 terminal. They are visible in the ‘Trade’ tab (for open positions) and ‘Account History’ tab (for closed positions) of the terminal. This field provides a flexible way to store arbitrary textual information related to a specific position.
Importance of Position Comments in Trading Strategies
For developers running multiple strategies or instances of the same strategy, position comments are invaluable. They can be used to:
- Identify the specific Expert Advisor or strategy that opened the position.
- Record entry conditions, signal sources, or trading plan details.
- Store parameters or state information relevant to the position’s management.
- Mark positions for specific analysis during backtesting or live trading review.
- Associate positions with external systems or databases using unique identifiers.
Effectively using comments significantly streamlines the process of analyzing trading performance and debugging complex EAs.
Default Position Comment Behavior
When a position is opened in MQL5, the default comment is automatically generated by the trading server. This default comment typically includes the source of the operation, such as ‘manual’, ‘expert’, ‘script’, or the name of the MQL5 program (.ex5 filename) that initiated the entry order that resulted in the position opening. While this default is useful, it’s often insufficient for detailed strategy tracking.
Methods for Changing Position Comments in MQL5
In MQL5, modifying an open position’s characteristics, including its comment, is primarily achieved through the PositionModify() function.
Using PositionModify() Function
PositionModify() is the core function used to alter parameters of an existing open position. Its signature is:
bool PositionModify(
ulong ticket, // Position ticket
double sl, // New Stop Loss price
double tp, // New Take Profit price
string comment // New comment
);
To change only the comment without altering Stop Loss or Take Profit, you must provide the current SL and TP values for the position. These can be retrieved using PositionGetDouble(POSITION_SL) and PositionGetDouble(POSITION_TP) after selecting the position with PositionSelectByTicket() or PositionSelect(). If you pass 0 for SL or TP when the position has an SL/TP, those levels will be removed. Conversely, if you pass non-zero values for SL/TP when the position does not have them, they will be added. Therefore, careful retrieval of current values is necessary if you only intend to modify the comment.
The comment parameter accepts a string value which will replace the existing comment for the position.
Understanding POSITION_PROPERTY_COMMENT Identifier
While PositionModify() is the function to set the comment, you retrieve the current comment using the PositionGet...() functions, specifically PositionGetString(). The relevant identifier is POSITION_COMMENT.
string currentComment = PositionGetString(POSITION_COMMENT);
This is used before calling PositionModify() if you need to preserve other properties or log the original comment, and also after modification to verify the change or use the new comment elsewhere.
Limitations of Changing Comments
The primary limitation when changing a position comment is the maximum length of the comment string. The maximum length is defined by the POSITION_COMMENT_MAXLEN constant, which is typically 31 characters. Any string longer than this limit will be truncated. It’s crucial to handle this in your code to avoid unexpected truncation of important information.
Another potential limitation is the frequency at which you can modify a position. While there isn’t a strict platform-wide limit on comment-only modifications different from price modifications, excessive calls to PositionModify() (e.g., on every tick for multiple positions) can generate significant server load and might lead to performance issues or requotes, although comment changes themselves don’t typically require requotes.
Practical Examples of Changing Position Comments
Let’s look at some code examples illustrating how to change position comments.
Changing Comment Based on Trading Logic
This example shows how to update a position’s comment after it has been opened, perhaps adding information about a trailing stop activation or a break-even adjustment.
void UpdatePositionComment(ulong positionTicket, string newComment)
{
// Select the position
if (!PositionSelectByTicket(positionTicket))
{
Print("Error selecting position ", positionTicket, ": ", GetLastError());
return;
}
// Get current SL and TP to pass to PositionModify (if you don't want to change them)
double currentSL = PositionGetDouble(POSITION_SL);
double currentTP = PositionGetDouble(POSITION_TP);
// Ensure comment doesn't exceed max length
string finalComment = newComment;
if (StringLen(finalComment) > POSITION_COMMENT_MAXLEN)
{
finalComment = StringSubstr(finalComment, 0, POSITION_COMMENT_MAXLEN);
Print("Warning: Comment truncated to ", POSITION_COMMENT_MAXLEN, " characters.");
}
// Modify the position comment
if (!PositionModify(positionTicket, currentSL, currentTP, finalComment))
{
Print("Error modifying position ", positionTicket, " comment: ", GetLastError());
}
else
{
Print("Position ", positionTicket, " comment updated to: ", finalComment);
}
}
// Example usage within an EA's OnTick or other event handler:
// Assuming 'ticket' is the ticket of an open position needing a comment update
// UpdatePositionComment(ticket, "Trailing activated @" + DoubleToString(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits));
Updating Comments with Order Information
Although MQL5 positions consolidate multiple orders, you might want to embed information about the initial entry order or subsequent scaling-in orders in the position comment. You could retrieve the ticket of the order that opened the position from the HistoryOrders collection and include it in the comment upon position opening, or update the comment later.
// This function assumes you have just received a deal that opened or modified a position
void HandleDeal(ulong dealTicket)
{
HistoryDealSelect(dealTicket);
ulong positionTicket = HistoryDealGetULong(DEAL_POSITION_ID);
string orderComment = HistoryDealGetString(DEAL_ORDER_COMMENT); // Get comment from the order/deal
// Select the position
if (!PositionSelectByTicket(positionTicket))
{
Print("Error selecting position from deal ", dealTicket, ": ", GetLastError());
return;
}
// Get current position details
double currentSL = PositionGetDouble(POSITION_SL);
double currentTP = PositionGetDouble(POSITION_TP);
string currentPosComment = PositionGetString(POSITION_COMMENT);
// Create a new comment, perhaps combining existing info and order info
string newComment = "OpenedByOrder:" + HistoryDealGetULong(DEAL_ORDER_ID) + "|" + currentPosComment;
// Handle max length
if (StringLen(newComment) > POSITION_COMMENT_MAXLEN)
{
newComment = StringSubstr(newComment, 0, POSITION_COMMENT_MAXLEN);
}
// Modify the position
if (!PositionModify(positionTicket, currentSL, currentTP, newComment))
{
Print("Error modifying position comment after deal ", dealTicket, ": ", GetLastError());
} else {
Print("Position ", positionTicket, " comment updated with order info.");
}
}
// This would typically be called from OnTrade() or OnTradeTransaction() event handlers.
// Example: In OnTradeTransaction, check for DEAL_ENTRY_IN/OUT deals and call HandleDeal
Error Handling When Modifying Comments
As shown in the examples, it’s crucial to check the return value of PositionModify(). If it returns false, use GetLastError() to diagnose the issue. Common errors might include:
ERR_INVALID_PARAMETER(e.g., invalid ticket, SL/TP issues, comment too long – although truncation should prevent the latter).ERR_TRADE_DISABLED(Trading is disabled on the account or symbol).ERR_POSITION_NOT_FOUND(The position ticket is invalid or position closed).
Proper error logging is vital for debugging EAs in live environments.
Best Practices and Considerations
Using position comments effectively requires adhering to certain best practices.
Comment Length Restrictions
Always be mindful of the POSITION_COMMENT_MAXLEN limit (31 characters). Design your comment format to be concise. Use abbreviations or codes if necessary. Attempting to set a longer comment will result in silent truncation by the terminal, which can lead to loss of information if not handled explicitly in your code.
Performance Implications of Frequent Comment Changes
Avoid modifying comments excessively, especially on symbols with high tick frequency or when managing many positions. Each call to PositionModify() is a trading operation that communicates with the server. While less impactful than price modifications, frequent calls can still add latency and load. Update comments only when necessary, such as significant state changes (e.g., break-even set, partial close) rather than on every tick.
Maintaining Consistency in Commenting Style
Establish a consistent format for your comments across different strategies or even within the same strategy. For example, [StrategyName]_[Version]_[SignalID]_[State] or using key-value pairs like Ver:1.2|Sig:EURUSD-M15-Buy|State:BE. This makes it much easier to parse and analyze comments programmatically during post-trade analysis or in external reporting tools.
Conclusion
Recap of Changing Position Comments
Changing a position’s comment in MQL5 is achieved using the PositionModify() function. You must select the target position, retrieve its current Stop Loss and Take Profit values (if you don’t intend to change them), and then call PositionModify() with the position ticket, current SL, current TP, and the desired new comment string. Always check the function’s return value and handle potential errors using GetLastError(). Be aware of the 31-character length limit for comments.
Further Exploration of MQL5 Trading Functions
Mastering PositionModify() is just one part of robust MQL5 programming. Explore other position management functions like PositionClose(), PositionClosePartial(), and the various PositionGet...() functions. Deeply understanding trade request structures and how orders, deals, and positions relate in MQL5 is fundamental for developing sophisticated and reliable trading systems.