Generate code in 3 minutes
Enter your idea and AI generates runnable code.
In MQL4, there is no dedicated "metadata" field for orders. However, you can save extra information using two specific properties of an order:
int): The most robust method. It is a unique integer identifier assigned by the EA. Brokers do not modify this value.string): A text field. While easier to read, it is unreliable because brokers often overwrite comments (e.g., during partial closes or stop-loss triggers).The best practice is to use the Magic Number to identify the strategy logic and map that number to a name within your code.
The following code demonstrates a robust framework. It defines unique IDs for different strategies, assigns them when opening orders, and includes a helper function to read that ID and return the human-readable strategy name.
//+------------------------------------------------------------------+
//| StrategyIdentifier_Demo.mq4|
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//--- 1. Define Unique IDs for your strategies
#define STRATEGY_TREND_FOLLOWING 1001
#define STRATEGY_MEAN_REVERSION 1002
#define STRATEGY_SCALPER 1003
//--- Input parameters
input double Lots = 0.1;
input int StopLoss = 50;
input int TakeProfit = 100;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Example: Open two trades with different Strategy IDs for testing
// Note: In a real EA, this would happen based on logic in OnTick
if(OrdersTotal() == 0)
{
// Open a Buy using the Trend Strategy ID
OpenTrade(OP_BUY, STRATEGY_TREND_FOLLOWING);
// Open a Sell using the Mean Reversion Strategy ID
OpenTrade(OP_SELL, STRATEGY_MEAN_REVERSION);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Periodically check open orders to see which strategy opened them
ReportOpenOrders();
}
//+------------------------------------------------------------------+
//| Helper: Open a trade with a specific Magic Number (Strategy ID) |
//+------------------------------------------------------------------+
void OpenTrade(int type, int strategyID)
{
double price, sl, tp;
if(type == OP_BUY)
{
price = Ask;
sl = (StopLoss > 0) ? price - StopLoss * Point : 0;
tp = (TakeProfit > 0) ? price + TakeProfit * Point : 0;
}
else
{
price = Bid;
sl = (StopLoss > 0) ? price + StopLoss * Point : 0;
tp = (TakeProfit > 0) ? price - TakeProfit * Point : 0;
}
// --- CRITICAL STEP ---
// The 'strategyID' is passed as the 'magic' parameter (2nd to last)
int ticket = OrderSend(_Symbol, type, Lots, price, 3, sl, tp, "Trade Comment", strategyID, 0, clrNONE);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
else
{
Print("Order Opened. Ticket: ", ticket, " | Strategy ID: ", strategyID);
}
}
//+------------------------------------------------------------------+
//| Helper: Convert Magic Number ID to String Name |
//+------------------------------------------------------------------+
string GetStrategyName(int magicNumber)
{
switch(magicNumber)
{
case STRATEGY_TREND_FOLLOWING: return("Trend Following");
case STRATEGY_MEAN_REVERSION: return("Mean Reversion");
case STRATEGY_SCALPER: return("Scalper");
default: return("Unknown/Manual");
}
}
//+------------------------------------------------------------------+
//| Logic: Loop through orders and identify their origin |
//+------------------------------------------------------------------+
void ReportOpenOrders()
{
int total = OrdersTotal();
for(int i = 0; i < total; i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
// 1. Get the Magic Number
int magic = OrderMagicNumber();
// 2. Translate it to a name
string stratName = GetStrategyName(magic);
// 3. Print the info
Print("Ticket #", OrderTicket(),
" | Symbol: ", OrderSymbol(),
" | Magic: ", magic,
" | Strategy: ", stratName);
}
}
}
//+------------------------------------------------------------------+
#define Constants:
We define readable names for integer IDs (e.g., STRATEGY_TREND_FOLLOWING is 1001). This prevents "magic number" confusion in the code.
OrderSend Parameter:
The OrderSend function signature is:
OrderSend(symbol, cmd, volume, price, slippage, sl, tp, comment, magic, expiration, arrow_color)
We pass our Strategy ID into the 9th parameter (magic).
OrderMagicNumber():
When looping through orders using OrderSelect, this function retrieves the integer we saved during OrderSend.
GetStrategyName():
Since the order only stores an integer (1001), we use a switch statement to map that integer back to a human-readable string ("Trend Following") for logging or on-screen display.
You can pass a string to the 8th parameter of OrderSend (the comment field).
OrderSend(_Symbol, OP_BUY, Lots, Ask, 3, 0, 0, "TrendStrategy", 0, 0, clrNONE);
And read it back using:
string comment = OrderComment();
Why this is dangerous:
If you perform a partial close (e.g., closing 0.5 lots of a 1.0 lot position), the broker/server will automatically change the comment of the remaining position to something like "from #123456". Your original strategy tag ("TrendStrategy") will be deleted, and your code will lose track of the trade. Magic Numbers persist through partial closes.
Q: Can I change the Magic Number of an open trade?
A: No. The Magic Number is assigned when the order is created and cannot be modified via OrderModify. It is immutable for the life of the order.
Q: Can I store more complex data, like the value of an indicator at the time of entry?
A: Not directly in the order. To do this, you must use the Magic Number as a "Key". You would write the complex data to a CSV file or a Global Variable using the Order Ticket or Magic Number as the reference ID, and look it up later.
Q: What happens if I restart the terminal?
A: Magic Numbers are stored on the trade server. If you restart your terminal or move to a different computer, OrderMagicNumber() will still retrieve the correct ID.
Q: How do I handle manual trades?
A: Manual trades usually have a Magic Number of 0. You can handle this in your GetStrategyName function (as shown in the default case in the code above).