why my EA occasionally place 2 orders at the exact same time

 

why my EA  occasionally place 2 orders at the exact same time

It just occasionally occurs this situation.

what is wrong with the code ? 

 

//+------------------------------------------------------------------+
//|                                                    EMA2cross.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"

#include <Trade/Trade.mqh>
#include <Trade/SymbolInfo.mqh>
#include <Trade/PositionInfo.mqh>
CTrade Trade;
CPositionInfo Pos;

input int magic_number = 3344;
input double lots = 0.5;
input int slippage = 20; //points 
input double stoploss  =300;  //points 
input double takeprofit = 490; //points 

int handle1 = INVALID_HANDLE;
int handle2 = INVALID_HANDLE;

double ma1[2],ma2[2];


int PositionsCounter(){
      int counter =0;
      if(Pos.Select(_Symbol)){
            if(Pos.Magic()==magic_number)counter++;
      }
      
      return(counter);
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
          
       
          handle1 = iMA(_Symbol,_Period,50,0,MODE_EMA,PRICE_CLOSE);
          handle2 = iMA(_Symbol,_Period,150,0,MODE_EMA,PRICE_CLOSE);
         
            Trade.SetExpertMagicNumber(magic_number);
            Trade.SetDeviationInPoints(slippage);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
         IndicatorRelease(handle1);
         IndicatorRelease(handle2);
         
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
          if(handle1==INVALID_HANDLE || handle2==INVALID_HANDLE ) return;          
           if(CopyBuffer(handle1,0,0,2,ma1)<=0 || CopyBuffer(handle2,0,0,2,ma2)<=0 )return;
           
           //
           //
           //  ready for place order ...
           if(PositionsCounter()==0){
           
               // place buy order 
               if(ma1[1]>ma2[1]&&ma1[0]<ma2[0]){
                  if(Trade.Buy(lots))return;            
               }
               
               // place sell order 
               if(ma1[1]<ma2[1]&&ma1[0]>ma2[0]){
                  if(Trade.Sell(lots))return;
               }               
           }
           
           //
           //
           // set stoploss and takeprofit 
           double sl=0,tp=0;
            if(PositionsCounter()==1){     
                               
                if(Pos.PositionType()==POSITION_TYPE_SELL){                     
                      if(stoploss>0){sl = Pos.PriceOpen() + stoploss*_Point;sl = NormalizeDouble(sl,_Digits);}
                      if(takeprofit>0){tp = Pos.PriceOpen()  - takeprofit*_Point;tp = NormalizeDouble(tp,_Digits);}                                       
                      if((Pos.StopLoss()==0&&sl>0) || (Pos.TakeProfit()==0&&tp>0) )
                          { if(Trade.PositionModify(_Symbol,sl,tp))return;}
                }
               
                 if(Pos.PositionType()==POSITION_TYPE_BUY){                     
                      if(stoploss>0){sl = Pos.PriceOpen() - stoploss*_Point;sl = NormalizeDouble(sl,_Digits);}
                      if(takeprofit>0){tp = Pos.PriceOpen()  + takeprofit*_Point;tp = NormalizeDouble(tp,_Digits);}                                       
                      if((Pos.StopLoss()==0&&sl>0) || (Pos.TakeProfit()==0&&tp>0) )
                          { if(Trade.PositionModify(_Symbol,sl,tp))return;}
                }
                   
               
               
            }
           
   
  }
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Tester function                                                  |
//+------------------------------------------------------------------+
double OnTester()
  {
//---
   double ret=0.0;
//---

//---
   return(ret);
  }
//+------------------------------------------------------------------+
 
greentreen:

why my EA  occasionally place 2 orders at the exact same time

It just occasionally occurs this situation.

what is wrong with the code ? 

 

 

1. How do you know about "... at the exact same time" ?

2. And how much the total lot in currently opened position ?

3. BTW, there are several err with your code :( 

 
phi.nuts:

1. How do you know about "... at the exact same time" ?

2. And how much the total lot in currently opened position ?

3. BTW, there are several err with your code :( 

Thank you Phi,

1. The history record  shows there are 2 positon at the same minutue. of course it is impossible at the exact same time :)

2. I set input lots = 0.1, the history shows two 0.1 positions  ,and 0.2 for out. 

3 Please point out the error in my codes.

 

thank you !

 

Files:
 

Hi greentreen,

what is ma1[0] for example: 

 

// place buy order 
               if(ma1[1]>ma2[1]&&ma1[0]<ma2[0]){ 


If it is value of indicator on open bar so it may be the reason why you have 2 trades instead of 1.
May be - it will help.
If not - I am sorry as I am not a coder.

 

 
greentreen:

Thank you Phi,

1. The history record  shows there are 2 positon at the same minutue. of course it is impossible at the exact same time :)

2. I set input lots = 0.1, the history shows two 0.1 positions  ,and 0.2 for out. 

3 Please point out the error in my codes.

 

thank you !

 

Hi greenteen,

1. I try to solve this but so far I could not come up with the convincing answer :(. My guess is PositionsCounter() function does not return correctly. In your code, the Pos.Select in PositionsCounter() is actually using mql5 function PositionSelect, please read its explanation there.

There is some topic in the past (with older build MT5) that some users were unable to modify position right after the position was opened. To solved that, they add Sleep after open a position and before modifying it. From there, since you said that this is only happen occasionally, I guess PositionSelect were not updated right away and that may the cause problem to your EA.

Here's the topic that I could find "what is the problem occuring when i run my ea on Alpari MT5?

2. Sorry I have to ask this . What TP/SL you set and what broker(s) did you use when running this EA ?

3. The errors I was talking about, are not directly related to the problem of this EA.

3.1. If there is INVALID_HANDLE when opening indicator, we should return and try again in OnTick, some user advice that sleep is needed in this case

void OnTick()
  {
//---
   if(handle1 == INVALID_HANDLE) handle1 = iMA(_Symbol,_Period, 50,0,MODE_EMA,PRICE_CLOSE);
   if(handle2 == INVALID_HANDLE) handle2 = iMA(_Symbol,_Period,150,0,MODE_EMA,PRICE_CLOSE);       

   if(handle1==INVALID_HANDLE || handle2==INVALID_HANDLE ) { Sleep (100); return;}

3.2. In your code, your position will be closed by SL or TP, even though the MAs is already showing opposite direction, this could lead to your position being closed at loss by SL. You should re-write the logic, so if there's opened position and MA is showing for opposite position, your EA should close the current position and open opposite position.

3.3. It's not good idea to use SL and TP. There are several report by forumer that some broker does not accept SL/TP even that we send them several times. Its better to use opposite pending orders as SL and TP. For example when we have open buy, use buylimit as SL and buystop as TP . 

 
newdigital:

Hi greentreen,

what is ma1[0] for example: 

 


If it is value of indicator on open bar so it may be the reason why you have 2 trades instead of 1.
May be - it will help.
If not - I am sorry as I am not a coder.

 

Thank you.

The value of indicator is based close price.

Documentation on MQL5: Standard Constants, Enumerations and Structures / Indicator Constants / Price Constants
Documentation on MQL5: Standard Constants, Enumerations and Structures / Indicator Constants / Price Constants
  • www.mql5.com
Standard Constants, Enumerations and Structures / Indicator Constants / Price Constants - Documentation on MQL5
 
phi.nuts:

Hi greenteen,

1. I try to solve this but so far I could not come up with the convincing answer :(. My guess is PositionsCounter() function does not return correctly. In your code, the Pos.Select in PositionsCounter() is actually using mql5 function PositionSelect, please read its explanation there.

There is some topic in the past (with older build MT5) that some users were unable to modify position right after the position was opened. To solved that, they add Sleep after open a position and before modifying it. From there, since you said that this is only happen occasionally, I guess PositionSelect were not updated right away and that may the cause problem to your EA.

Here's the topic that I could find "what is the problem occuring when i run my ea on Alpari MT5?

2. Sorry I have to ask this . What TP/SL you set and what broker(s) did you use when running this EA ?

3. The errors I was talking about, are not directly related to the problem of this EA.

3.1. If there is INVALID_HANDLE when opening indicator, we should return and try again in OnTick, some user advice that sleep is needed in this case

3.2. In your code, your position will be closed by SL or TP, even though the MAs is already showing opposite direction, this could lead to your position being closed at loss by SL. You should re-write the logic, so if there's opened position and MA is showing for opposite position, your EA should close the current position and open opposite position.

3.3. It's not good idea to use SL and TP. There are several report by forumer that some broker does not accept SL/TP even that we send them several times. Its better to use opposite pending orders as SL and TP. For example when we have open buy, use buylimit as SL and buystop as TP . 

 

The broker is Alpari UK

Your advice of 3.1,3.2,and 3.3 are helpful.

I will take some time to read the docs about MT5 programming on this forum.

Anyway,thank you!

 

 

 

During backtest,the first order number is  2 instead of 1,why?

and what is "exchange"  ? 

 

 

 

 

 
greentreen:

During backtest,the first order number is  2 instead of 1,why?

and what is "exchange"  ? 

1. Have no idea why it start with 2 :(.

2. Seach for exchange in MT5 help file (open MT5 press F1), you will find this Exchange Execution

 

Hi, I think the problem is caused by the long processing time of trade server.

if trade condition is satisfied, buy or sell order was sent to the trade server. When your EA gets true from the server, it does not mean  the success creation of position. It only means your order was accepted and waiting for further process. So for these codes to modify the position:

       // set stoploss and takeprofit
           double sl=0,tp=0;
            if(PositionsCounter()==1)

they are immediately executed just after the sending of order. At this time, the position may be not created by the server. the result of executing " if(PositionsCounter()==1) " may be false. At this situation, the position modification should be executed during the coming of next tick if position was created by the server then.

The worst situation is that when the next tick comes,  the server does not create the position. Just here your EA send one more order you don't wish.

 
fhjtiger:

Hi, I think the problem is caused by the long processing time of trade server.

if trade condition is satisfied, buy or sell order was sent to the trade server. When your EA gets true from the server, it does not mean  the success creation of position. It only means your order was accepted and waiting for further process. So for these codes to modify the position:

       // set stoploss and takeprofit
           double sl=0,tp=0;
            if(PositionsCounter()==1)

they are immediately executed just after the sending of order. At this time, the position may be not created by the server. the result of executing " if(PositionsCounter()==1) " may be false. At this situation, the position modification should be executed during the coming of next tick if position was created by the server then.

The worst situation is that when the next tick comes,  the server does not create the position. Just here your EA send one more order you don't wish.

If we are using OrderSendAsync then there is no way of telling whether position is opened or not. However since user greenteen and his code above was sending order using CTrade Class which using OrderSend, then we could easily tell whether the position is opened or not by simply checking OrderSend result and return code.  
Reason: