EA - MQL5 - managing different position opening on different TF

 

Hello,


New here, I slowly learn how to code my EA on MQL5, but now I'm stuck on a problem and I don't find the solution.


I made an EA and this EA can open a trade on different TF, but only one trade at a time per TF. So, it's running and analyze the TF 1min, 2min, 3min, 4min and 5min. It can open 5 trades on the 5 different times frames, but it can't open 2 trades on the same TF.


The problem is : if I simply use the code : PositionSelect(_Symbol) == true I only get the answer to "is there a position opened on this asset", if it's a yes it's will not allow the EA to take any others trade no matter on which TF this trade have been opened.


So, I tried to change the command I used to open a trade (before I was using : PositionOpen(_Symbol,ORDER_TYPE_BUY,Size,currentprice,StopLose,TakeProfit)) and use this kind of position opener instead


Here my first code (with  "PositionOpen" and "PositionSelect") :



#include <Trade\Trade.mqh>
CTrade myTradingControlPanel;
double currentAsk;
double StopLose, StopLoseP, TakeProfit, TakeProfitP, Size;

  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {

   ///////-------list of condition and the last condition is "Is there an open position that's have been opened on this TF?" -----

               if(PositionSelect(_Symbol) == false) // Don't have an open position ------> problem is : it's check if there is a position but not look from which TF this position have been opened
                 {
                  StopLose = xxxx // Stop Lose price
                  StopLoseP = xxxx // Stop Lose %
                  TakeProfitP = xxxx  // Take Profit %
                  TakeProfit = xxxx // Take Profit price
                  Size = xxxx  // Size of the position

                  myTradingControlPanel.PositionOpen(_Symbol,ORDER_TYPE_BUY,Size,currentAsk,StopLose,TakeProfit); // Open Position
                  }

  }


Here is my attempt with the MqlTradeRequest :


#include <Trade\Trade.mqh>
CTrade myTradingControlPanel; 
double currentBid, currentAsk;
double StopLose, StopLoseP, TakeProfit, TakeProfitP, Size;


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
  ////////////---------- list of condition and the last condition is "is there an open position that's have been opened on this TF?" ------

               if(?????? no idea what to code here ???????) // Don't have an open position
                 {
                  StopLose = xxxx // Stop Lose price
                  StopLoseP = xxxx // Stop Lose %
                  TakeProfitP = xxxx // Take Profit %
                  TakeProfit = xxxx // Take Profit price
                  Size = xxxx // Size of the position
                  
                  MqlTradeRequest request;
                  request.action = TRADE_ACTION_DEAL;
                  request.magic = 11;
                  request.symbol = _Symbol;
                  request.volume = Size;
                  request.type = ORDER_TYPE_BUY;
                  request.price = currentAsk;
                  request.sl = StopLose;
                  request.tp = TakeProfit;
                  MqlTradeResult result;
                  
                  myTradingControlPanel.OrderSend(request,result);
                  }
  }


In both case I just repeat the same code 5 times (1min, 2min, 3min, 4min and 5min TF) , changing only the TF data.


I try to use that in order to have the "magic number" that could theoretically allow me to know from which TF each position have been opened and so allow other TF to open a trade but not allow the same TF to open one if her "magic number" is in use in a opened position. But I have no idea of what code i should write in order to do so. And also, when I ran a test on this EA (just for try), I get an error on the order send, so I guess something is wrong in the way i wrote it also... I'm confuse on this part of coding. The "PositionOpen" and "PositionSelect" was so easy before, it's hard to do the switch to this other way of sending order. ^^ If you have some tuto or example I could study, I will be very glad.


Thank you.

Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Trade Operation Types
Documentation on MQL5: Constants, Enumerations and Structures / Trade Constants / Trade Operation Types
  • www.mql5.com
Trade Operation Types - Trade Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Please edit your post and use the code button (Alt+S) when pasting code.
EDIT your original post, please do not just post the code correctly in a new post.

 
Keith Watford #:
Please edit your post and use the code button (Alt+S) when pasting code.
EDIT your original post, please do not just post the code correctly in a new post.


I tried to edit my original post, I hope it's clearer like that.

 
CrokCrypto: I try to use that in order to have the "magic number" that could theoretically allow me to know from which TF each position have been opened and so allow other TF to open a trade but not allow the same TF to open one if her "magic number" is in use in a opened position. But I have no idea of what code i should write in order to do so.

Convert the timeframe (ENUM_TIMEFRAMES) to a compact form (my TF) and add it to a base Magic number.
          Why are MT5 ENUM_TIMEFRAMES strange? - General - MQL5 programming forum - Page 2 #11 (2020)

 

But how to use the magic number for identifying a position ?


Other problem, the result.retcode I get from the ordersend request is : 10013 invalid request, Not hep much too find what is wrong. ^^

EDIT : problem solve about the result.retcode → a mandatory field wasn't filled.

 

So, I figured out that I can make 5 different EA each one taking care of one specific TF and then give to each EA a MAGIC_NUMBER in order to identify each position (which one have been opened by which EA) to be sure that each EA take care only of their own opened position.

I rewrote my code, it's looking like that (see under). But the issue now, is that this code doesn't open any position anymore (there is no error tho on the back test, it just doesn't open any trade).


#include <Trade\Trade.mqh>
#define EXPERT_MAGIC 1
CTrade myTradingControlPanel;
double currentAsk;
double StopLose, TakeProfit, TakeProfit, Size;


//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   
   currentAsk = SymbolInfoDouble(_Symbol,SYMBOL_ASK); // Get latest Ask Price

   if(all the conditions needed for opening a trade)
               {
               int total = PositionsTotal();
               for(int i=0; i<total; i++)
                  {
                  ulong magic = PositionGetInteger(POSITION_MAGIC);
                  if(magic == EXPERT_MAGIC) // Have position opened on this TF
                     {
                     }
                  else // Don't have position opened on this TF
                     {
                     StopLose= xxxx; // Stop Lose price
                     TakeProfit = xxx; // Take Profit price
                     Size = xxxx; // Size of the position
                     
                     MqlTradeRequest request;
                     request.action = TRADE_ACTION_DEAL;
                     request.magic = EXPERT_MAGIC;
                     request.symbol = _Symbol;
                     request.volume = Size;
                     request.type = ORDER_TYPE_BUY;
                     request.type_filling = ORDER_FILLING_FOK; 
                     request.price = currentAsk;
                     request.sl = StopLose;
                     request.tp = TakeProfit;
                     MqlTradeResult result;
                     
                     myTradingControlPanel.OrderSend(request,result);
                     }
  }
//+------------------------------------------------------------------+


What do I miss? 

 
William Roeder #: Convert the timeframe (ENUM_TIMEFRAMES) to a compact form (my TF) and add it to a base Magic number.
CrokCrypto #: But how to use the magic number for identifying a position ?
  1. Instead of a single MN, you have a range. MN_Base+TF_M1 .. MN_BASE_TF_MN1.
  2. MT5: first select a position via CPositionInfo, directly, or by 'MT4Orders' library (2016)
 
William Roeder #:
  1. Instead of a single MN, you have a range. MN_Base+TF_M1 .. MN_BASE_TF_MN1.
  2. MT5: first select a position via CPositionInfo, directly, or by 'MT4Orders' library (2016)


To be honest, I didn't understand your answer, but I checked more documentations and asked more questions. Now I arrived to this code, which seems correct to me (to do what I intend to do) but it's obviously not because when i run a test with it, this EA doesn't open any position at all (no error signaled tho).

For me, this code should do what I want : checking if there is an open position with a specific magic number and if there isn't one, it can open a position.

Where I'm wrong, what should I code instead?


#include <Trade\Trade.mqh>
#define EXPERT_MAGICM1 1
#define EXPERT_MAGICM2 2
CTrade myTradingControlPanel;
double currentAsk;
double StopLose, TakeProfit, Size;

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
                   
   currentAsk = SymbolInfoDouble(_Symbol,SYMBOL_ASK); // Get latest Ask Price
   

   if(bunch of condition and then the last one is : no position already opened with this specific magic number)
               {
               for(int v = PositionsTotal() - 1;v >= 0; v--)
                  {
                  ulong positionticket = PositionGetTicket(v);
                  if(PositionSelectByTicket(positionticket))
                     {
                     if(PositionGetInteger(POSITION_MAGIC) != EXPERT_MAGICM1) // Don't have an opened position with this magic number
                        {
                        StopLose = xxx;
                        TakeProfit = xxx;
                        Size = xxx; 

                        MqlTradeRequest request;
                        request.action = TRADE_ACTION_DEAL;
                        request.magic = EXPERT_MAGICM1;
                        request.symbol = _Symbol;
                        request.volume = Size;
                        request.type = ORDER_TYPE_BUY;
                        request.type_filling = ORDER_FILLING_FOK; 
                        request.price = currentAsk;
                        request.sl = StopLose;
                        request.tp = TakeProfit;
                        MqlTradeResult result;
                  
                        myTradingControlPanel.OrderSend(request,result);
                        }
                 }
             }
         }

   if(another bunch of condition and then the last one is : no position already opened with this specific magic number)
               {
               for(int v = PositionsTotal() - 1;v >= 0; v--)
                  {
                  ulong positionticket = PositionGetTicket(v);
                  if(PositionSelectByTicket(positionticket))
                     {
                     if(PositionGetInteger(POSITION_MAGIC) != EXPERT_MAGICM2) // Don't have an opened position with this magic number
                        {
                        StopLose = xxx;
                        TakeProfit = xxx;
                        Size = xxx; 

                        MqlTradeRequest request;
                        request.action = TRADE_ACTION_DEAL;
                        request.magic = EXPERT_MAGICM2;
                        request.symbol = _Symbol;
                        request.volume = Size;
                        request.type = ORDER_TYPE_BUY;
                        request.type_filling = ORDER_FILLING_FOK; 
                        request.price = currentAsk;
                        request.sl = StopLose;
                        request.tp = TakeProfit;
                        MqlTradeResult result;
                  
                        myTradingControlPanel.OrderSend(request,result);
                        }
                  }
              }
         }
  }
//+------------------------------------------------------------------+
 

I think there is a problem with logic here – because you go in a loop for all opened positions – but perform the function on every position that it’s not opened with this magic number (from this timeframe). So, In this case – if you would have position from M1, M5, H1 – and want to open a new on H4 – in a loop you will be checking each of this positions in order. And on every on them – magic won’t be matching with you H4 magic number so you’ll try to open a trade on H4 – I think it would end up opening 3 more trades on H4.

So, you should fix this – go in a loop on all trades and set a flag – foundMagic true/false. And outside the loop: If you found H4 trade do not open a trade, but if you haven’t found such trade – only then open a new trade on H4 with this magic.

And you can use your Ctrade calss and PositionOpen function – just before you use the function call a function which set up the magic number for the class:

SetExpertMagicNumber(Magic);

As someone recommended you can do this in the one EA – no need to use 5 of them – just need to include TF as number in the magic like: magic for H4 would be for example magic+240, magic for H1 would be magic+60 etc.

 Good luck with coding!

 
Marzena Maria Szmit #:

I think there is a problem with logic here – because you go in a loop for all opened positions – but perform the function on every position that it’s not opened with this magic number (from this timeframe). So, In this case – if you would have position from M1, M5, H1 – and want to open a new on H4 – in a loop you will be checking each of this positions in order. And on every on them – magic won’t be matching with you H4 magic number so you’ll try to open a trade on H4 – I think it would end up opening 3 more trades on H4.

So, you should fix this – go in a loop on all trades and set a flag – foundMagic true/false. And outside the loop: If you found H4 trade do not open a trade, but if you haven’t found such trade – only then open a new trade on H4 with this magic.

And you can use your Ctrade calss and PositionOpen function – just before you use the function call a function which set up the magic number for the class:

SetExpertMagicNumber(Magic);

As someone recommended you can do this in the one EA – no need to use 5 of them – just need to include TF as number in the magic like: magic for H4 would be for example magic+240, magic for H1 would be magic+60 etc.

 Good luck with coding!


Okay, so I try to code something as you said. No error on the compilation, but when I run it in the strategy tester, I get an "invalid request" error. But I didn't change anything on my OrderSend() request, and it was working perfectly fine before.


Obviously I'm still missing something, what is it?


#include <Trade\Trade.mqh>
#define EXPERT_MAGICM1 1
#define EXPERT_MAGICM2 2
CTrade myTradingControlPanel;
double currentAsk;
double StopLose, TakeProfit, Size;
bool HavePosition;

  
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
                   
   currentAsk = SymbolInfoDouble(_Symbol,SYMBOL_ASK);


            if (bunch of condition)
               {
               for(int v = PositionsTotal() - 1;v >= 0 || HavePosition == true ; v--)
                  {
                  ulong positionticket = PositionGetTicket(v);
                  if(PositionSelectByTicket(positionticket))
                     {
                     if(PositionGetInteger(POSITION_MAGIC) == EXPERT_MAGICM1)
                        {
                        HavePosition = true;
                        }
                     else
                        {
                        HavePosition = false;
                        }
                     }
                   }
                if(HavePosition == false)
                  {
                  StopLose = xxx;
                  TakeProfit = xxx; 
                  SizeB = xxx; 

                  MqlTradeRequest request;
                  request.action = TRADE_ACTION_DEAL;
                  request.magic = EXPERT_MAGICM1;
                  request.symbol = _Symbol;
                  request.volume = Size;
                  request.type = ORDER_TYPE_BUY;
                  request.type_filling = ORDER_FILLING_FOK; 
                  request.price = currentAsk;
                  request.sl = StopLose;
                  request.tp = TakeProfit;
                  MqlTradeResult result;
                  
                  myTradingControlPanel.OrderSend(request,result);
                  }
               }


            if (bunch of condition)
               {
               for(int v = PositionsTotal() - 1;v >= 0 || HavePosition == true; v--)
                  {
                  ulong positionticket = PositionGetTicket(v);
                  if(PositionSelectByTicket(positionticket))
                     {
                     if(PositionGetInteger(POSITION_MAGIC) == EXPERT_MAGICM2)
                        {
                        HavePosition = true;
                        }
                     else
                        {
                        HavePosition = false;
                        }
                     }
                   }
                if(HavePosition == false)
                  {
                  StopLose = xxx;
                  TakeProfit = xxx; 
                  SizeB = xxx; 
                  
                  MqlTradeRequest request;
                  request.action = TRADE_ACTION_DEAL;
                  request.magic = EXPERT_MAGICM2;
                  request.symbol = _Symbol;
                  request.volume = Size;
                  request.type = ORDER_TYPE_SELL;
                  request.type_filling = ORDER_FILLING_FOK; 
                  request.price = currentAsk;
                  request.sl = StopLose;
                  request.tp = TakeProfit;
                  MqlTradeResult result;
                  
                  myTradingControlPanel.OrderSend(request,result);
                  }
               }
  }
//+------------------------------------------------------------------+
Reason: