Opening both buy and sell EA does not work properly

 

Hello everyone, 

I wanted to code an EA that opens both buy and sell positions. When the first one reaches stop loss, it should wait for profit from the second one. As the first one closes, the stop loss of the second one gets modified to the initial Bid/Ask position. Although it works on some trades, it does not always modify the second order. It also gives me OrderModify Error 130 and OrderModify Error 4108. Do you know what is wrong with it?

extern double PriceAtProfitBuy;
extern double PriceAtLossBuy;
extern double PriceAtProfitSell;
extern double PriceAtLossSell;

extern double LotSize = 0.25;
extern int ticketBuy;
extern int ticketSell;

extern double StopLossZeroOnBuy;
extern double StopLossZeroOnSell;

extern bool Modified = true;

void CreateTakeProfitOnBuy(){

      PriceAtProfitBuy = Ask + (Ask/10000*11);
      StopLossZeroOnBuy= Ask;
   
      ObjectCreate("TakeProfitOnBuy", OBJ_HLINE, 0, 0, PriceAtProfitBuy);
      ObjectSet("TakeProfitOnBuy", OBJPROP_COLOR, Green);
      ObjectSet("TakeProfitOnBuy", OBJPROP_WIDTH, 0);
      ObjectSet("TakeProfitOnBuy", OBJPROP_STYLE, STYLE_SOLID);
      
    
}
void CreateStopLossOnBuy(){

      PriceAtLossBuy = Ask - (Ask/10000*10);

   
      ObjectCreate("StopLossOnBuy",OBJ_HLINE,0,0,PriceAtLossBuy);
      ObjectSet("StopLossOnBuy", OBJPROP_COLOR, Red);
      ObjectSet("StopLossOnBuy", OBJPROP_WIDTH, 0);
      ObjectSet("StopLossOnBuy", OBJPROP_STYLE, STYLE_SOLID);
           
}

void CreateTakeProfitOnSell(){

   PriceAtProfitSell = Bid - (Bid/10000*11);
   StopLossZeroOnSell = Bid;
   
   ObjectCreate("TakeProfitOnSell", OBJ_HLINE,0,0,PriceAtProfitSell);
   ObjectSet("TakeProfitOnSell", OBJPROP_COLOR, Blue);
   ObjectSet("TakeProfitOnSell", OBJPROP_WIDTH, 0);
   ObjectSet("TakeProfitOnSell", OBJPROP_STYLE, STYLE_SOLID);
}

void CreateTakeLossOnSell(){

   PriceAtLossSell = Bid + (Bid/10000*10);
   
   ObjectCreate("TakeLossOnSell", OBJ_HLINE, 0,0,PriceAtLossSell);
   ObjectSet("TakeLossOnSell", OBJPROP_COLOR, Purple);
   ObjectSet("TakeLossOnSell", OBJPROP_WIDTH, 0);
   ObjectSet("TakeLossOnSell", OBJPROP_STYLE, STYLE_SOLID);
   
}
void PlaceBuyTrade(){

   ticketBuy = OrderSend(Symbol(),OP_BUY,LotSize,Ask,3,NormalizeDouble(PriceAtLossBuy,5),NormalizeDouble(PriceAtProfitBuy,5),NULL,0,0,Yellow);
  
   
}
void PlaceSellTrade(){

   ticketSell = OrderSend(Symbol(),OP_SELL,LotSize,Bid,3,NormalizeDouble(PriceAtLossSell,5),NormalizeDouble(PriceAtProfitSell,5),NULL,0,0,Yellow);

}
void ModifyBuy(){

   OrderModify(ticketBuy,OrderOpenPrice(),NormalizeDouble(StopLossZeroOnBuy,5),OrderTakeProfit(),0,Orange);
   ObjectDelete("CreateTakeProfitOnBuy");ObjectDelete("CreateTakeProfitOnSell");
   ObjectDelete("CreateTakeStopLossOnBuy");ObjectDelete("CreateTakeStopLossOnBuy");
   Modified = false;
   }
   
void ModifySell(){


   OrderModify(ticketSell,OrderOpenPrice(),NormalizeDouble(StopLossZeroOnSell,5),OrderTakeProfit(),0,Orange);
   ObjectDelete("CreateTakeProfitOnBuy");ObjectDelete("CreateTakeProfitOnSell");
   ObjectDelete("CreateTakeStopLossOnBuy");ObjectDelete("CreateTakeStopLossOnSell"); 
   Modified = false;

}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {  

   if(OrdersTotal() == 0){
      
      CreateTakeProfitOnBuy();
      CreateStopLossOnBuy();
      CreateTakeProfitOnSell();
      CreateTakeLossOnSell();
      
      PlaceBuyTrade();
      PlaceSellTrade();
      Modified = true;
   }
   if(Modified = true){
      if(OrdersTotal() == 1){

         if(OrderType() == OP_SELL){
         ModifySell();
         }
         else if (OrderType() == OP_BUY){
         ModifyBuy();
         }
   }
  }
 }
  
 
Peter4410: Do you know what is wrong with it?
Why did you post your MT4 question in the Root / MT5 EA section instead of the MQL4 section (bottom of the Root page?) General rules and best pratices of the Forum. - General - MQL5 programming forum
  1. extern int ticketBuy;
    extern int ticketSell;
    
    extern double StopLossZeroOnBuy;
    extern double StopLossZeroOnSell;
    
    extern bool Modified = true;
    
    Why are these extern?
  2. EA's 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 (tickets and modified) will have been lost. You will have an open order 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 loop to recover, or persistent storage (GV+flush or files) of ticket numbers required.
  3. PriceAtProfitBuy = Ask + (Ask/10000*11);
    
    Ask is like 1.23456. divided by 10K gives ~1. Ask+11 is huge. Bid-11 is bogus (130). Don't hard code numbers. If you meant 11 pips, do it right. adjusting SL, TP, and slippage; for 4/5 digit brokers and for JPY pairs.
    double   pip          = StringFind(_Symbol,"JPY") < 00.010.0001;
    int      pipsToPoints = int(pip / _Point);
    int      pipDigits    = (int)MathLog10(pipsToPoints);
    int      slippage     = 3 * pipsToPoints;
  4. You can't move stops closer to the market than MODE_STOPLEVEL * _Point. Requirements and Limitations in Making Trades - Appendixes - MQL4 Tutorial
  5. You buy at the Ask and sell at the Bid. Therefor your buy order stops are relative to the Bid, and sell order stops the Ask.

  6. ticketBuy = OrderSend(Symbol(), OP_BUY, LotSize, Ask, 3, NormalizeDouble(PriceAtLossBuy,5), NormalizeDouble(PriceAtProfitBuy,5), NULL, 0, 0, Yellow);
    OrderModify(ticketBuy, OrderOpenPrice(), NormalizeDouble(StopLossZeroOnBuy,5), OrderTakeProfit(), 0, Orange);
    Do NOT use NormalizeDouble, EVER. For ANY Reason. It's a kludge, don't use it. It's use is always wrong
  7. Check your return codes What are Function return values ? How do I use them ? - MQL4 forum and Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
  8. Adjust slippage #2
  9. Fixed lot size. Fixed? stops.
    • You place the stop where it needs to be - where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
    • Account Balance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the SPREAD, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
    • Do NOT use TickValue by itself - DeltaPerLot
    • You must normalize lots properly and check against min and max.
    • You must also check FreeMargin to avoid stop out

  10. OrderModify(ticketBuy, OrderOpenPrice(), NormalizeDouble(StopLossZeroOnBuy,5), OrderTakeProfit(),0,Orange);
    You can not use any Trade Functions functions until you select an order. #3 #4
  11.    if(OrdersTotal() == 0){
    
    Using OrdersTotal directly and/or no Magic number filtering on your OrderSelect loop means your code is incompatible with every EA (including itself on other charts and manual trading.) Symbol Doesn't equal Ordersymbol when another currency is added to another seperate chart . - MQL4 forum