Help me with this breakeven EA issue

 
Could you guys please help me find out what's wrong with this MQL5 EA. So basically the original of this EA is an EA that helps you move SL to the A1 point after the price moves to an A2 price point. I did some modifies this EA to move the SL one more time, SL at the A1 point will move to the B1 point (B1>A1) if the price moves to a B2 price (B2>A2), but unfortunately, it didn't work, SL just moves to A1 and that all.

Here is the code Of Buy function only, please take a look.
input int        PlusPoints_breakeven   = 500;                          // plus points, A2
input int        StepSL_plus_breakeven  = 200;                          // step breakeven, A1
input int        PlusPoints_breakeven1  = 500;                          // plus points,  B2
input int        StepSL_plus_breakeven1 = 200;                          // step breakeven, B1
enum checkSymb
  {
   CurrentSymbol, // Current Symbol
   AllSymbols,    // All Symbols
  };
string TXT,BTtxt;
bool   Breakeven;
bool   Trailing;
input checkSymb  WorkSymb               = CurrentSymbol;                   // work symbol
 long       MagicNumber            = 0;     
int OnInit()
  {
   TXT=""; Breakeven=true; 
//--- check input parameters
   if(PlusPoints_breakeven<=0 || StepSL_plus_breakeven==0) Breakeven=false;
   if(PlusPoints_breakeven>0 && PlusPoints_breakeven<=StepSL_plus_breakeven) { Alert("Plus points for breakeven must be more step breakeven!"); return(INIT_FAILED);}
   }
   
void fBreakeven()
  {
   int _tp=PositionsTotal();
   for(int i=_tp-1; i>=0; i--)
     {
      string _p_symbol=PositionGetSymbol(i);
      if(WorkSymb==CurrentSymbol && _p_symbol!=_Symbol) continue;
      if(MagicNumber>=0 && MagicNumber!=PositionGetInteger(POSITION_MAGIC)) continue;
      double _s_point = SymbolInfoDouble(_p_symbol, SYMBOL_POINT);
      long   _s_levSt = SymbolInfoInteger(_p_symbol, SYMBOL_TRADE_STOPS_LEVEL);
      int    _s_dig   = (int)SymbolInfoInteger(_p_symbol,SYMBOL_DIGITS);
      double _p_sl    = PositionGetDouble(POSITION_SL);
      double _p_tp    = PositionGetDouble(POSITION_TP);
      double _p_op    = PositionGetDouble(POSITION_PRICE_OPEN);
      if(_p_sl==0) _p_sl=_p_op;
      //---
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         if(_p_sl>=_p_op+StepSL_plus_breakeven*_s_point) continue;
         double Bid=SymbolInfoDouble(_p_symbol,SYMBOL_BID);
         if(_p_op+PlusPoints_breakeven*_s_point<=Bid)
           {
            double _new_sl=_p_op+StepSL_plus_breakeven*_s_point;
            if(Bid-_new_sl<_s_levSt*_s_point) _new_sl=Bid-_s_levSt*_s_point;
            _new_sl=NormalizeDouble(_new_sl,_s_dig);
            if(_new_sl<=_p_sl)continue;
            trade.PositionModify(_p_symbol,_new_sl,_p_tp);
            }
           
         if(_p_op+PlusPoints_breakeven1*_s_point<=Bid) // Where I added my modification
           {
            double _new_sl=_p_op+StepSL_plus_breakeven1*_s_point;
            if(Bid-_new_sl<_s_levSt*_s_point) _new_sl=Bid-_s_levSt*_s_point;
            _new_sl=NormalizeDouble(_new_sl,_s_dig);
            if(_new_sl<=_p_sl)continue;
            trade.PositionModify(_p_symbol,_new_sl,_p_tp);
           }
        }}


Note:

A1 is StepSL_plus_breakeven; A2 is PlusPoints_breakeven;
B1 is StepSL_plus_breakeven1; B2 is PlusPoints_breakeven1;
Thank you so much for your time
 
Hello anyone could help me with this issue?
 

sounds like a trail stop; albeit it is rather over complicated code.

But a suggestion to try: Move the code that you added, the line ending "Where I added my Modification", and the brackets; to be above the previous brackets, and below the line ending with "SYMBOL_BID"

Also note that most ppl are away on festivities.

 
Good that you are programming on your holidays, this should be an example for most.

First of all, you modify Position in the same time twice on the same tick, because you just sent the order in a queue.
Therefore I don't know if Editing PositionModify twice, will react to your second call.  Look at the debugger of CTrade:
trade.LogLevel(2)


Does CTrade log in your debuger mentions your call twice of your PositionModify ?:

trade.PositionModify(_p_symbol,_new_sl,_p_tp)
trade.PositionModify(_p_symbol,_new_sl,_p_tp)

Second part is that use Print function to verify your call:
//-- This function call returns boolean right?
bool  PositionModify(
   const string  symbol,     // symbol
   double        sl,         // Stop Loss price
   double        tp          // Take Profit price
   )

Not used bit, is a wasted bit:
if (trade.PositionModify(_p_symbol,_new_sl,_p_tp)) {
        Print("Return Code Test: ", trade,ResultRetcode());
}
Return codes and their meaning: https://www.mql5.com/en/docs/constants/errorswarnings/enum_trade_return_codes

My guess is that you can't call twice something which is a request to your broker.


The code is very complicated to read due to non standard variable names. You mix aesthetics of code.
Pick one, and stick to it, if you are lazy to put comments, use your variable names as comments, which will self explain what is happening, don't be scared to use long variable names.
camelCase or PascalCase or snake_case

Example camelCase:
      double positionSL   = PositionGetDouble(POSITION_SL);
      double positionTP    = PositionGetDouble(POSITION_TP);
      double positionPriceOpen    = PositionGetDouble(POSITION_PRICE_OPEN);
Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings / Trade Server Return Codes
Documentation on MQL5: Constants, Enumerations and Structures / Codes of Errors and Warnings / Trade Server Return Codes
  • www.mql5.com
Trade Server Return Codes - Codes of Errors and Warnings - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5