Magic Numbers on Filled Orders

 

I'm currently writing an EA that places a buy stop or sell stop (using Ctrade) and then sets the SL and TP once the pending order has been filled.

I'm trying to use magic numbers to keep track of the trades placed by this EA so that when the orders are filled, the EA only updates the SL and TP of the pending orders that it placed.

I've been using OnTradeTransaction to detect when an order has been filled however it seems that once the order is filled it loses it's magic number (stored in request.magic).

How can I tell apart positions that are a result of pending orders from a specific EA? Is there a better way to do this?

void OnTick()
  {
  
   if(!HasRun)
   {
      int numDigits = Digits();
      double askPrice = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
      double bidPrice = SymbolInfoDouble(Symbol(), SYMBOL_BID);
      double entryLevelPip = EntryLevel / MathPow(10,numDigits);
      double buyPrice = askPrice + entryLevelPip;
      double sellPrice = bidPrice - entryLevelPip;
      double stopLevelPip = (StopLevel + ((double)(SymbolInfoInteger(_Symbol, SYMBOL_SPREAD)))) / MathPow(10, numDigits);
      double tierOne = TierOne / MathPow(10, numDigits);
      double tierTwo = TierTwo / MathPow(10, numDigits);
      double tierThree = TierThree /MathPow(10, numDigits);
      
      trade.SetExpertMagicNumber(Expert_ID);
      
      trade.BuyStop(Lot, askPrice + entryLevelPip, Symbol(), askPrice + entryLevelPip - stopLevelPip, askPrice + entryLevelPip + tierOne);
      trade.BuyStop(Lot, askPrice + entryLevelPip, Symbol(), askPrice + entryLevelPip - stopLevelPip, askPrice + entryLevelPip + tierTwo); 
      trade.BuyStop(Lot, askPrice + entryLevelPip, Symbol(), askPrice + entryLevelPip - stopLevelPip, askPrice + entryLevelPip + tierThree); 
      trade.SellStop(Lot, bidPrice - entryLevelPip, Symbol(), bidPrice - entryLevelPip + stopLevelPip, askPrice - entryLevelPip - tierOne);
      trade.SellStop(Lot, bidPrice - entryLevelPip, Symbol(), bidPrice - entryLevelPip + stopLevelPip, askPrice - entryLevelPip - tierTwo);
      trade.SellStop(Lot, bidPrice - entryLevelPip, Symbol(), bidPrice - entryLevelPip + stopLevelPip, askPrice - entryLevelPip - tierThree);
      
      HasRun = true;
      
      Print(Symbol());
   }
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   if (request.magic == Expert_ID && trans.type == TRADE_TRANSACTION_ORDER_UPDATE)
   {
      //Update SL/TP
   }
  }
//+-----
 

You can get the magic number:

ulong magic_number=OrderGetInteger(ORDER_MAGIC);

But you need to specify a position of which you want to retrieve the magic number.

See here https://www.mql5.com/en/docs/trading/ordersend

For some related examples.

//--- declare and initialize the trade request and result of trade request
   MqlTradeRequest request;
   MqlTradeResult  result;
   int total=PositionsTotal(); // number of open positions   
//--- iterate over all open positions
   for(int i=0; i<total; i++)
     {
      //--- parameters of the order
      ulong  position_ticket=PositionGetTicket(i);// ticket of the position
      string position_symbol=PositionGetString(POSITION_SYMBOL); // symbol 
      int    digits=(int)SymbolInfoInteger(position_symbol,SYMBOL_DIGITS); // number of decimal places
      ulong  magic=PositionGetInteger(POSITION_MAGIC); // MagicNumber of the position
      double volume=PositionGetDouble(POSITION_VOLUME);    // volume of the position
      double sl=PositionGetDouble(POSITION_SL);  // Stop Loss of the position
      double tp=PositionGetDouble(POSITION_TP);  // Take Profit of the position
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);  // type of the position
      //--- output information about the position
      PrintFormat("#%I64u %s  %s  %.2f  %s  sl: %s  tp: %s  [%I64d]",
                  position_ticket,
                  position_symbol,
                  EnumToString(type),
                  volume,
                  DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN),digits),
                  DoubleToString(sl,digits),
                  DoubleToString(tp,digits),
                  magic);
      //--- if the MagicNumber matches, Stop Loss and Take Profit are not defined
      if(magic==EXPERT_MAGIC && sl==0 && tp==0)
        { 
         //--- calculate the current price levels
         double price=PositionGetDouble(POSITION_PRICE_OPEN);
         double bid=SymbolInfoDouble(position_symbol,SYMBOL_BID);
         double ask=SymbolInfoDouble(position_symbol,SYMBOL_ASK);
         int    stop_level=(int)SymbolInfoInteger(position_symbol,SYMBOL_TRADE_STOPS_LEVEL);
         double price_level;
         //--- if the minimum allowed offset distance in points from the current close price is not set
         if(stop_level<=0)
            stop_level=150; // set the offset distance of 150 points from the current close price
         else
            stop_level+=50; // set the offset distance to (SYMBOL_TRADE_STOPS_LEVEL + 50) points for reliability
 
         //--- calculation and rounding of the Stop Loss and Take Profit values
         price_level=stop_level*SymbolInfoDouble(position_symbol,SYMBOL_POINT);
         if(type==POSITION_TYPE_BUY)
           {
            sl=NormalizeDouble(bid-price_level,digits);
            tp=NormalizeDouble(bid+price_level,digits);
           }
         else
           {
            sl=NormalizeDouble(ask+price_level,digits);
            tp=NormalizeDouble(ask-price_level,digits);
           }
         //--- zeroing the request and result values
         ZeroMemory(request);
         ZeroMemory(result);
         //--- setting the operation parameters
         request.action  =TRADE_ACTION_SLTP; // type of trade operation
         request.position=position_ticket;   // ticket of the position
         request.symbol=position_symbol;     // symbol 
         request.sl      =sl;                // Stop Loss of the position
         request.tp      =tp;                // Take Profit of the position
         request.magic=EXPERT_MAGIC;         // MagicNumber of the position
         //--- output information about the modification
         PrintFormat("Modify #%I64d %s %s",position_ticket,position_symbol,EnumToString(type));
         //--- send the request
         if(!OrderSend(request,result))
            PrintFormat("OrderSend error %d",GetLastError());  // if unable to send the request, output the error code
         //--- information about the operation   
         PrintFormat("retcode=%u  deal=%I64u  order=%I64u",result.retcode,result.deal,result.order);
        }
     }

Here are some more example when you scroll to the bottom.

https://www.mql5.com/en/docs/constants/structures/mqltraderequest

Documentation on MQL5: Trade Functions / OrderSend
Documentation on MQL5: Trade Functions / OrderSend
  • www.mql5.com
[in,out]  Pointer to a structure of MqlTradeResult type describing the result of trade operation in case of a successful completion (if true is returned). parameter are filled out correctly. If there are no errors, the server accepts the order for further processing. If the order is successfully accepted by the trade server, the OrderSend...