Please help with my Trail Stop

 

Hi all,

Can someone please help me with my trailing stop?

I have three different levels:

1 - Stop loss following at Moving Average

2 - Locking in Pips

3- Trailing


The function works but seems to break at some point and only work if I reload the EA.


How can I ensure that the EA looks at all the IF statements as the OnTimer() function operates?


PS: I started programming 1 month ago so please reply in "easy mode"


void OnTimer(){
   int pt = PositionsTotal();
  
   for(int i=pt; i>=0; i--){
      
      ulong tick = PositionGetTicket(i);
      
      
      if(PositionSelectByTicket(tick)){
      
      Print(BreakEven);
            
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
                      
            {
               if ((BreakEven=="NotStarted")&&(PositionGetDouble(POSITION_SL)!=MASell_Array[0])&&(PositionGetDouble(POSITION_SL)!=PositionGetDouble(POSITION_PRICE_OPEN)+(PipsToLockIn*pips)))
                {
                      double tp = PositionGetDouble(POSITION_TP);
                      double sl = MABuy_Array[0];// Setting SL = to moving avarage
            
                      trade.PositionModify(tick,sl,tp);   
                      
                      Print("First if statement");
                }
             
                if((BreakEven=="NotStarted")&&(bid>=(PositionGetDouble(POSITION_PRICE_OPEN)+(WhenToLockIn*pips))))
               {
                      double tp = PositionGetDouble(POSITION_TP);
                      double sl = PositionGetDouble(POSITION_PRICE_OPEN)+(PipsToLockIn*pips);
            
                      trade.PositionModify(tick,sl,tp); 
                      
                      StringReplace(BreakEven,"NotStarted", "Started");
                      Print("Breakeven has started");
                      Comment("Breakeven has started - First instance");
                }
               if((BreakEven=="Started")&&(bid>=(PositionGetDouble(POSITION_PRICE_OPEN)+(WhenToTrail*pips)))&&((bid-(ByHowMuchToTrail*pips))>PositionGetDouble(POSITION_SL)))
                {
                      double tp = PositionGetDouble(POSITION_TP);
                      double sl = bid-(ByHowMuchToTrail*pips);
            
                      trade.PositionModify(tick,sl,tp); 
                                          
                      Print("Breakeven has started - Second instance");
                     
                }
            }//End of Buy position
            
           else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
            {
            
               if((BreakEven=="NotStarted")&&(PositionGetDouble(POSITION_SL)!=MABuy_Array[0])&&(PositionGetDouble(POSITION_SL)!=PositionGetDouble(POSITION_PRICE_OPEN)-(PipsToLockIn*pips)))
               {
                      double tp = PositionGetDouble(POSITION_TP);
                      double sl = MASell_Array[0];// Setting SL = to moving avarage
            
                      trade.PositionModify(tick,sl,tp); 
                    
                      Print("First If statement in Sell Modify");
               }
             if((BreakEven=="NotStarted")&&(ask<=(PositionGetDouble(POSITION_PRICE_OPEN)-(WhenToLockIn*pips))))
               {
                      double tp = PositionGetDouble(POSITION_TP);
                      double sl = PositionGetDouble(POSITION_PRICE_OPEN)-(PipsToLockIn*pips);
            
                      trade.PositionModify(tick,sl,tp); 
                      
                      StringReplace(BreakEven,"NotStarted", "Started");
                      Print("Breakeven has started");
                      Comment("Breakeven has started - First instance");
                }
              if((BreakEven=="Started")&&(ask<=(PositionGetDouble(POSITION_PRICE_OPEN)-(WhenToTrail*pips)))&&((ask+(ByHowMuchToTrail*pips))<PositionGetDouble(POSITION_SL)))
                {
                      double tp = PositionGetDouble(POSITION_TP);
                      double sl = ask+(ByHowMuchToTrail*pips);
            
                      trade.PositionModify(tick,sl,tp); 
                                           
                      Print("Breakeven has started - Second instance");
                     
                }
            }//End of Sell position
       
          }//End of ticket select
            Print("\n", "Select by ticket not working");
     
         
      }//End of for loop
         Print("\n", "Trailing NOT Triggered");
   }//End Timer Function
 
Jan-HarmZ63: The function works but seems to break at some point and only work if I reload the EA.
               if ((BreakEven=="NotStarted")&&(PositionGetDouble(POSITION_SL)!=MASell_Array[0])&
  1. 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 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 to recover, or persistent storage (GV+flush or files) of ticket numbers required.

  2. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?

  3. Why are you using OnTimer? If nothing has changed, why go through your logic. Wait for a new tick and then see.

  4. Your logic is unreadable and should be simplified. Just compute your new SL and then verify that it's above BE and above current SL by at least a point, then move it. No static/global variables required.
 
William Roeder:
  1. 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 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 to recover, or persistent storage (GV+flush or files) of ticket numbers required.

  2. Use the debugger or print out your variables, including _LastError and prices and find out why. Do you really expect us to debug your code for you?

  3. Why are you using OnTimer? If nothing has changed, why go through your logic. Wait for a new tick and then see.

  4. Your logic is unreadable and should be simplified. Just compute your new SL and then verify that it's above BE and above current SL by at least a point, then move it. No static/global variables required.

@William Roeder

Hi William,

Thank you for your response.

As I mentioned I am new to programming so much of these things are above me.

I will take the time to address your comments and post again.


Is there a pragmatic why to "Nullify" a IF statement without the use of global variables?

e.g. If I want to have a break even function as well as a trailing function - how do I ensure that the trailing SL do not revert back to BE when the price moves back to the point where the BE  IF statement conditions are true?

Are you open to Zoom sessions :-)

 
Jan-HarmZ63:

Hi all,

Can someone please help me with my trailing stop?

I have three different levels:

1 - Stop loss following at Moving Average

2 - Locking in Pips

3- Trailing


The function works but seems to break at some point and only work if I reload the EA.


How can I ensure that the EA looks at all the IF statements as the OnTimer() function operates?


PS: I started programming 1 month ago so please reply in "easy mode"


If you use the OnTimer() function block then the code will be executed every x seconds (you should set x in the OnInit() function block). It could be that the price has changed a lot during this x period.

Alternatively you can place your code in the OnTick() function block. In that case is your code executed every time when a new tick price arrives.

Reason: