[SOLVED] Magic Number Issue???

 

I think I am having issues with magic numbers and reading them.

I need multiple EAs are running on the same symbol(s) and therefore need to distinguish between open positions based on Magic number.

The code I've used is failing and I've copied similar solutions found on this forum and it's still not working. I've even tried using a different terminal and account to no resolve.

The following example of code is where the problem is. I want this to open 1 position at a time. What is annoying is that when I change the criteria to look for symbol of the position, it works (as in it opens only 1 position at a time and you can see the position count go up once a position is opened)

#include <Trade\Trade.mqh>
CTrade trade;


int OnInit()
  {
   trade.SetExpertMagicNumber(12345);
  }


void OnTick()
  {

   double Price_Ask    = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Price_Bid    = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);


   ulong Position_Count = 0;


   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      ulong  Position_Ticket = PositionGetInteger(POSITION_TICKET);
      
      if(PositionSelectByTicket(Position_Ticket))
        {
         ulong  Position_Magic_Number = PositionGetInteger(POSITION_MAGIC);
         
         if(Position_Magic_Number == 12345)
         Position_Count+=1;
        }

     }



   if(Position_Count < 1)
     {
      trade.Sell(Lot_Size,_Symbol,Price_Bid,NULL,NULL,NULL);
     }



   }

Thanks in advance to any replies :)

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Position Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Position Properties
  • www.mql5.com
Position ticket. Unique number assigned to each newly opened position. It usually matches the ticket of an order used to open the position except when the ticket is changed as a result of service operations on the server, for example, when charging swaps with position re-opening. To find an order used to open a position, apply the...
 
Marcus T-S:

I think I am having issues with magic numbers and reading them.

I need multiple EAs are running on the same symbol(s) and therefore need to distinguish between open positions based on Magic number.

The code I've used is failing and I've copied similar solutions found on this forum and it's still not working. I've even tried using a different terminal and account to no resolve.

The following example of code is where the problem is. I want this to open 1 position at a time. What is annoying is that when I change the criteria to look for symbol of the position, it works (as in it opens only 1 position at a time and you can see the position count go up once a position is opened)

Thanks in advance to any replies :)

Try setting the symbol name too then use both codes in the search. Peace!

ulong Magic=12345;
int OnInit()
{
        if(!m_symbol.Name(Symbol())) // sets symbol name
      return(INIT_FAILED);
                
//...
        m_trade.SetExpertMagicNumber(Magic);
//...
}
void OnTick()
{
        if( m_position.Magic()==Magic && m_position.Symbol()==Symbol())
      {
                ...code
      }

}
 
Nelson Wanyama:

Try setting the symbol name too then use both codes in the search. Peace!

Thanks, but that still ignores the magic number in process, meaning that having multiple EAs on the same symbol conflict with each other.
 

Ok I've finally found the issue (useful for anyone with a similar problem) after many backtests.

PositionGetSymbol has to be used before any "if"s for magic number. You don't have to use an "if" loop to check for the symbol, but for some reason the EA needs to know the Symbol of the position for the magic number to be checked properly (even if the symbol is not being checked in the "if" loop).


Following works (opening 1 position at a time):

#include <Trade\Trade.mqh>
CTrade trade;


int OnInit()
  {
   trade.SetExpertMagicNumber(12345);
  }


void OnTick()
  {

   double Price_Ask    = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
   double Price_Bid    = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);


   uchar Position_Count = 0;

   for(int i=PositionsTotal()-1; i>=0; i--)
     {
      ulong  Position_Symbol = PositionGetSymbol(i);
      ulong  Position_Magic_Number = PositionGetInteger(POSITION_MAGIC);
         
      if(Position_Magic_Number == 12345)
      Position_Count+=1;

     }



   if(Position_Count < 1)
     {
      trade.Sell(Lot_Size,_Symbol,Price_Bid,NULL,NULL,NULL);
     }



   }



It's a bit bizarre but there's the solution.
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Position Properties
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Position Properties
  • www.mql5.com
Position ticket. Unique number assigned to each newly opened position. It usually matches the ticket of an order used to open the position except when the ticket is changed as a result of service operations on the server, for example, when charging swaps with position re-opening. To find an order used to open a position, apply the...
 
Marcus T-S:
It's a bit bizarre but there's the solution.

No, this isn't bizarre. The reason is that a position needs to be selected(!) first before we can get meaningful information from PositionGetInteger, PositionGetDouble, etc.

PositionGetSymbol is just one method that already comes with this selection included. PositionSelect (in netting mode or for the position with the lowest ticket number in hedging mode) and PositionSelectByTicket would work, too.

 
Chris70:

No, this isn't bizarre. The reason is that a position needs to be selected(!) first before we can get meaningful information from PositionGetInteger, PositionGetDouble, etc.

PositionGetSymbol is just one method that already comes with this selection included. PositionSelect (in netting mode or for the position with the lowest ticket number in hedging mode) and PositionSelectByTicket would work, too.

In my first example I used PositionSelectByTicket and it didn't work, which is why I was orginally confused to what was going on.
 
Marcus T-S:
In my first example I used PositionSelectByTicket and it didn't work, which is why I was orginally confused to what was going on.

You've got it working now, so this is only on a sidenote: the contradiction in your example was that you can't use PositionGetInteger(POSITION_TICKET)) before the position is selected, but you also can't use PositionSelectByTicket() to select the position if you don't know the ticket in advance. This doesn't mean that PositionSelectByTicket is always useless; In other cases we might know the ticket because we worked with the same position earlier. Then PositionSelectByTicket() can be used to select the same position again.

 
Chris70:

You've got it working now, so this is only on a sidenote: the contradiction in your example was that you can't use PositionGetInteger(POSITION_TICKET)) before the position is selected, but you also can't use PositionSelectByTicket() to select the position if you don't know the ticket in advance. This doesn't mean that PositionSelectByTicket is always useless; In other cases we might know the ticket because we worked with the same position earlier. Then PositionSelectByTicket() can be used to select the same position again.

Ohhhh, i see now! Thanks for explaining! This was very useful to know.

 
This topic saved my time today. thank you all 
 
Chris70 #: This doesn't mean that PositionSelectByTicket is always useless; In other cases we might know the ticket because we worked with the same position earlier. Then PositionSelectByTicket() can be used to select the same position again.

EAs must be coded to recover. If the power fails, OS crashes, terminal or chart is accidentally closed, on the next tick, any static/global ticket variables will have been lost. You will have an open order/position but don't know it, so the EA will never try to close it, trail SL, etc. How are you going to recover?

Use a OrderSelect / Position select loop on the first tick, or persistent storage (GV+flush or files) of ticket numbers required.

Reason: