Complete MQL5 guide & code

MQL5 Magic Number Guide: Multi-EA Isolation & CTrade Implementation

Complete guide to MQL5 Magic Numbers. Learn what magic numbers are, how to set them with CTrade::SetExpertMagicNumber, filter positions, and isolate multiple Expert Advisors on one account.

What this MQL5 guide covers

A Magic Number is a unique ulong identifier assigned to orders and positions to distinguish them from other EAs and manual trades.

CTrade::SetExpertMagicNumber(magic) automatically injects your identifier into every order placed by that CTrade instance.

Looping through PositionsTotal() requires checking PositionGetInteger(POSITION_MAGIC) == InpMagicNumber before closing or modifying trades.

Magic numbers persist across terminal restarts, VPS migrations, and broker reconnections within MT5 trade history.

What is a Magic Number in MetaTrader 5?

A Magic Number is a numeric tag (stored as an unsigned 64-bit integer, ulong) stamped onto orders, positions, and deals created by an Expert Advisor. The broker and trading server maintain this value unchanged throughout the trade lifecycle.

Without magic numbers, an EA cannot distinguish its own positions from trades opened manually by the trader, or from trades opened by another automated system running on the same account.

Trade PropertyTypeAccess FunctionPurpose
POSITION_MAGICulong / longPositionGetInteger(POSITION_MAGIC)Identifies the owning EA of an open position
ORDER_MAGICulong / longOrderGetInteger(ORDER_MAGIC)Identifies the owning EA of an active pending order
DEAL_MAGICulong / longHistoryDealGetInteger(deal, DEAL_MAGIC)Identifies the owning EA in historical deal logs
trade.SetExpertMagicNumber(n)voidCTrade methodSets internal magic number for all subsequent CTrade requests

Configuring Magic Numbers with CTrade and MqlTradeRequest

When using the standard CTrade class, you configure the magic number once inside OnInit() by calling trade.SetExpertMagicNumber(InpMagicNumber).

If you construct low-level MqlTradeRequest structs manually for OrderSend(), assign the value directly to request.magic = InpMagicNumber.

  • CTrade assignment: trade.SetExpertMagicNumber(202601);
  • MqlTradeRequest assignment: request.magic = 202601;
  • Convention: Use distinct magic numbers for each currency pair and timeframe combination.

Multi-EA Filtering Pattern

When writing trailing stops, trade counters, or close-all routines, always filter by both _Symbol and POSITION_MAGIC.

This ensures that an EA managing EURUSD on H1 never accidentally modifies a position opened on EURUSD by a scalper on M5, or a manual discretionary trade.

Implementation details & mechanics

Core implementation pattern

In OnInit(), assign the input magic number: trade.SetExpertMagicNumber(InpMagicNumber). When evaluating entry criteria, query CountOpenPositionsByMagic(InpMagicNumber). If the count is below the maximum allowed positions for this EA, place a new order with trade.Buy() or trade.Sell().

Error handling & safety rules

When checking exit conditions or applying trailing stops, loop through open positions with PositionsTotal(). Call PositionGetTicket(i) and verify PositionGetInteger(POSITION_MAGIC) == InpMagicNumber. Only modify or close tickets that match your magic number.

MQL5 Code Implementation Code

//+------------------------------------------------------------------+
//|                                             MagicNumberGuide.mq5 |
//|                             Copyright 2026, Pineify Guides Series |
//|                                              https://pineify.app |
//+------------------------------------------------------------------+
#property copyright "Pineify Guides Series"
#property link      "https://pineify.app/mql5/magic-number-guide"
#property version   "1.00"
#property strict

#include <Trade\Trade.mqh>

//--- Input parameters
input group "--- EA Identification ---"
input ulong  InpMagicNumber   = 884401; // Unique Magic Number
input double InpLotSize       = 0.10;   // Lot Size
input int    InpMaxPositions  = 1;      // Max Positions For This EA

//--- Global trade instance
CTrade trade;

//+------------------------------------------------------------------+
//| Helper: Count open positions belonging to this EA & Symbol       |
//+------------------------------------------------------------------+
int CountOpenPositionsByMagic(ulong magic, const string symbol)
  {
   int count = 0;
   int total = PositionsTotal();

   for(int i = 0; i < total; i++)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0)
         continue;

      // Filter by symbol
      if(PositionGetString(POSITION_SYMBOL) != symbol)
         continue;

      // Filter by magic number
      if((ulong)PositionGetInteger(POSITION_MAGIC) == magic)
         count++;
     }
   return count;
  }

//+------------------------------------------------------------------+
//| Helper: Close only positions belonging to this EA & Symbol       |
//+------------------------------------------------------------------+
void CloseAllPositionsForThisEA(ulong magic, const string symbol)
  {
   int total = PositionsTotal();
   // Iterate backwards when closing positions to maintain valid index alignment
   for(int i = total - 1; i >= 0; i--)
     {
      ulong ticket = PositionGetTicket(i);
      if(ticket == 0)
         continue;

      if(PositionGetString(POSITION_SYMBOL) == symbol &&
         (ulong)PositionGetInteger(POSITION_MAGIC) == magic)
        {
         if(trade.PositionClose(ticket))
           {
            PrintFormat("Closed position #%I64u belonging to Magic %I64u", ticket, magic);
           }
         else
           {
            PrintFormat("Failed to close position #%I64u: %s",
                        ticket, trade.ResultRetcodeDescription());
           }
        }
     }
  }

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Set magic number for all orders placed through CTrade
   trade.SetExpertMagicNumber(InpMagicNumber);
   PrintFormat("EA Initialized on %s with Magic Number: %I64u", _Symbol, InpMagicNumber);
   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // Count only this EA's active positions
   int myPositions = CountOpenPositionsByMagic(InpMagicNumber, _Symbol);

   // If no positions exist for this EA, place an order
   if(myPositions < InpMaxPositions)
     {
      double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      trade.Buy(InpLotSize, _Symbol, ask, 0.0, 0.0, "Pineify Magic Demo");
     }
  }

Copy this code into MetaEditor, save it in your MQL5 folder (Experts, Scripts, or Include), and compile with F7.

Generate custom MQL5 code with Pineify AI

Describe the trade execution, indicator calculations, risk management, or data processing logic you need. Pineify produces clean, typed MQL5 source code ready to compile in MetaEditor.

Frequently Asked Questions

Related MQL5 pages

Technical references

Risk and testing note

Past performance is not indicative of future results. Backtest statistics are based on historical data and do not guarantee future profits. Trading involves significant risk of loss. This content is for educational purposes only and does not constitute financial advice.