Lock In Profit EA

 

Hello, I programmed this EA to lock in profit at various levels. The idea is to have a jumping stop when certain profit levels are hit. Once 61 pips are hit then a trailing stop is activated at 70%.

I am finding it difficult to code the logic to stop the EA from moving the stop backwards. I try various ideas and no luck.

The other problem I believe is a small one related to the magic number. The EA will show stop levels for other currency pairs and act like its running a calculation when adjusting the stop loss.

Help appreciated.

//+------------------------------------------------------------------+
//|                                                    BlueprintV1.8.mq4 |
//|                                                 Not working|
//|                                   campbell_congdon@hotmail.com |
//+------------------------------------------------------------------+
#property copyright "not working"
#property link      "notworking@hotmail.com"
extern double InitialTrailingStop = 10; 
extern double trailing_stop_level1 = 3;
extern double SecTrailingStop = 20;
extern double trailing_stop_level2 = 8;
extern double ThirdTrailingStop = 30;
extern double trailing_stop_level3 = 15;
extern double FourthTrailingStop = 40;
extern double trailing_stop_level4 = 24;
extern double FifthTrailingStop = 60;
extern double trailing_stop_level5 = 42;
extern double TrailPercent = 70;
extern double Trail_From   = 61.0;
// Set it to some value above 0 to activate stop-loss   
extern double StopLoss = 0;     

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {double PointValue;
  for (int i = 0; i < OrdersTotal(); i++) 
  {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      //Calculate the point value in case there are extra digits in the quotes
      if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.00001) PointValue = 0.0001;
      else if (MarketInfo(OrderSymbol(), MODE_POINT) == 0.001) PointValue = 0.01;
      else PointValue = MarketInfo(OrderSymbol(), MODE_POINT);
      //Normalize trailing stop value to the point value
      double TSTP = InitialTrailingStop * PointValue;
      double TSTP2 = SecTrailingStop * PointValue;
      double TSTP3 = ThirdTrailingStop * PointValue;
      double TSTP4 = FourthTrailingStop * PointValue;
      double TSTP5 = FifthTrailingStop * PointValue;
      double Trail_From = Trail_From * PointValue;
      double sl = OrderStopLoss();
      double My_Profit;
      double My_Trail;
      double My_SL;
     
     
       
      if (OrderType() == OP_BUY)
      {
         if (((InitialTrailingStop> 0) && (Bid - OrderOpenPrice() >= TSTP) && (Bid - OrderOpenPrice() < TSTP2)))
         
        { OrderModify (OrderTicket(), OrderOpenPrice(),OrderOpenPrice()+ trailing_stop_level1 * PointValue, OrderTakeProfit(), Red);
              }
              }
          { if (((SecTrailingStop> 0) && (Bid - OrderOpenPrice() >= TSTP2) && (Bid - OrderOpenPrice() <TSTP3)))
         
          { OrderModify (OrderTicket(), OrderOpenPrice(),OrderOpenPrice() + trailing_stop_level2 * PointValue, OrderTakeProfit(), Red); 
           }
           }
         
                    
         { if (((ThirdTrailingStop  > 0) && (Bid - OrderOpenPrice() >= TSTP3)&& (Bid - OrderOpenPrice() <TSTP4)))
          
          { OrderModify (OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+trailing_stop_level3 * PointValue, OrderTakeProfit(), Red); 
              }
              }
             
         {if ((( FourthTrailingStop  > 0) && (Bid - OrderOpenPrice() >= TSTP4)&& (Bid - OrderOpenPrice() <TSTP5)))
        
          { OrderModify (OrderTicket(), OrderOpenPrice(),OrderOpenPrice()+trailing_stop_level4 * PointValue, OrderTakeProfit(), Red); 
               }
               }
               
               
         {if (( FifthTrailingStop  > 0) &&  (Bid - OrderOpenPrice() >= TSTP5) && (Bid - OrderOpenPrice() < Trail_From))
          
          { OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() + trailing_stop_level5 * PointValue, OrderTakeProfit(), Red); 
          
          }
          }
           My_Profit = MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice();
           My_Trail = MathMin(My_Profit * TrailPercent/100,Digits);
         { if (Bid - OrderOpenPrice() > TSTP5)
         { if(OrderStopLoss()< Bid  - My_Trail * PointValue)
         { OrderModify(OrderTicket(),OrderOpenPrice(),Bid - My_Trail*PointValue,OrderTakeProfit(),0, Red);
        
        }
          }
       }
       }
  if ((OrderStopLoss() != Bid - StopLoss * PointValue) && (StopLoss != 0))
            OrderModify(OrderTicket(), OrderOpenPrice(), Bid - StopLoss * PointValue, OrderTakeProfit(), Red);
       
       if (OrderType() == OP_SELL)
     
         { if (((InitialTrailingStop> 0) && (OrderOpenPrice() - Ask >= TSTP) && (OrderOpenPrice() - Ask < TSTP2)))
           
          {OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-trailing_stop_level1 * PointValue, OrderTakeProfit(), Red);
       }
       }
       
       {  if ((( SecTrailingStop > 0) && (OrderOpenPrice() - Ask >= TSTP2) && (OrderOpenPrice() - Ask < TSTP3)))
          
         {OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()- trailing_stop_level2 * PointValue, OrderTakeProfit(), Red);
                 
       }
       }
            
    {    
      if (((ThirdTrailingStop > 0) && (OrderOpenPrice() - Ask >= TSTP3) && (OrderOpenPrice() - Ask < TSTP4)))
          
          {OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-trailing_stop_level3 * PointValue, OrderTakeProfit(), Red);
          
        }
        }
    {   
     if (((FourthTrailingStop > 0) && (OrderOpenPrice() - Ask >= TSTP4) && (OrderOpenPrice() - Ask < TSTP5)))
         
         {OrderModify(OrderTicket(), OrderOpenPrice(),OrderOpenPrice() - trailing_stop_level4 * PointValue , OrderTakeProfit(), Red);
        
        }
        }
        
     
        {if (( FifthTrailingStop  > 0) &&  (OrderOpenPrice() - Ask >= TSTP5) && (OrderOpenPrice() - Ask < Trail_From))
        
         {OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice() - trailing_stop_level5 * PointValue, OrderTakeProfit(), Red);
         
         }
         }
         
         My_Profit = OrderOpenPrice() - MarketInfo(OrderSymbol(), MODE_ASK);
         My_Trail = MathMin(My_Profit * TrailPercent/100,Digits);
        {if((OrderOpenPrice()-Ask)> TSTP5)
        {if((OrderStopLoss()>(Ask+My_Trail*PointValue)) || (OrderStopLoss()==0))
        { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+My_Trail*PointValue,OrderTakeProfit(),0,Red);
         }
         }
                                
        }
   
if ((OrderStopLoss() != Ask + StopLoss * PointValue) && (StopLoss != 0))
            OrderModify(OrderTicket(), OrderOpenPrice(), Ask + StopLoss * PointValue, OrderTakeProfit(), Red);

//----
   
//----
   return(0);
}
//+------------------------------------------------------------------
 
Angof1497:

Hello, I programmed this EA to lock in profit at various levels. The idea is to have a jumping stop when certain profit levels are hit. Once 61 pips are hit then a trailing stop is activated at 70%.

I am finding it difficult to code the logic to stop the EA from moving the stop backwards. I try various ideas and no luck.

The other problem I believe is a small one related to the magic number. The EA will show stop levels for other currency pairs and act like its running a calculation when adjusting the stop loss.

Help appreciated.


Here is the EA
Files:
 

You are using Bid and Ask . . they are the Bid and Ask for the pair that the EA is running on . . if you want to modify Orders on other pairs you cant use Bid and Ask . . use MarketInfo instead, with MODE_BID & MODE_ASK

You don't seem to e checking the Magic number at all . . nor do you check if your OrderSelect has actually worked . . . and you never check if your OrderModify works . . why not ? don't you want to know if it has failed and what the error was ?

 
I guess you're not interested in programming. I've already given you some samples https://www.mql5.com/en/forum/136964. Yet, it seems you want us to fix someone else's badly indented codes. Perhaps you should pay someone to fix your SL manager.
 

Hi Ubzen - like I said I couldn't figure out the logic to recognise the highest profit. That is my real problem. Your samples unfortunately did not address that problem. You mentioned I would need logic to get the highest profit. That is my issue and has been. What I had posted on that forum was a percentage trail idea that I realised was unnecessary due to using orderopenprice + the stop level I desire in the order modify. The Magic number etc I can figure out.

My real problem is how to make the EA recognise that the highest profit has been hit and adjust the stop level for the profit. Its my code, my idea - not someone elses. The use of the term TSTP is not mine and this part " My_Profit = MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice();
My_Trail = MathMin(My_Profit * TrailPercent/100,Digits);" The other items regarding order select is not mine but would seem standard on every EA. The rest is mine, I am the guy mentioned in the EA. That is my email. Yes, Campbell is my first name. Order functions I am not that familiar with and still learning. Once I have this logic then I can modify it and learn from there. I am not just some other lazy git and I spend a few hours each night trying to figure this out. I don't want to pay and would like to figure this out. But in the end to get the result I will pay and learn from there. I have been modifying EAs for about 5-6 months. Mostly to add indicators and make the EA do what I want. That was easy and this Order aspect is new for me since I first posted here and you replied.

Raptor - thanks for replying. I haven't really worried about the magic number bit yet as I would like to find the logic on how to make the stop level from going backwards. I believe my EA when running on other currency pairs at the same time is checking through stop levels because there is no magic number however the stop levels it was showing on one EA were correct just that they kept moving backwards. Order checking etc I am not that familiar with and would like to do second once I can get the stop level from moving backward. I am placing the EA on the currency pair chart thinking it will work for just that currency pair however due to no specific magic number it is doing some kind of checklist. I read where to stop this I would need a specific magic number for each currency pair within the EA or on the EA i place on the chart.

 
Angof1497:

I am placing the EA on the currency pair chart thinking it will work for just that currency pair however due to no specific magic number it is doing some kind of checklist. I read where to stop this I would need a specific magic number for each currency pair within the EA or on the EA i place on the chart.

To work on a specific pair you don't need to use Magic Number just check the OrderSymbol if you are working on different TFs on the same symbol then yes, use a Magic Number, or if you are mixing manual trades and EA placed trades then yes, use a Magic Number . . or if you are running different EAs on the same platform then you should use a Magic Number.

OrderSelect and OrderModify both return a value to tell you if they worked or not . . capture that value and act accordingly . . get into the habit of doing it and it will help you loads in the future . . .

 

Ok, sorry for my assumption that it's probably not your code. As to your problems, (since you're doing things your own way, which is good).

This code:

OrderSelect(i, SELECT_BY_POS, MODE_TRADES);

outside an if() statement is a bad idea. Take RaptorUK advice and place within an if() statement.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

My real problem is how to make the EA recognise that the highest profit has been hit and adjust the stop level for the profit.... for something like this, I'd track it by looking at the value of the Trailing-Stop. Example: if( mathAbs( OrderClosePrice-OrderStopLoss) < It_Should_Be_For_This_Level_Of_Profit){ OrderModify(....); }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Other Suggestions: ( if you care to take it)

Use OrderSelect Loops which looks something like this. So that you can easily filter out, magic, symbol, type, profit, etc.

    for(i=His-1; i>His-iSample; i--){
        if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)
        //&& OrderMagicNumber()==iMagic
        //&& OrderSymbol()==iSymbol_
        //&& OrderType()==iType
        ){
                do-whatever
        }

Always count down .. i--, instead of i++,

    for(i=OrdersTotal()-1; i>=0; i--){
        if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){

Choose a nice format with standard 3-space indent (i perfer 4 or more).

Example1:

    while(found<=5){
        if(iCustom(iSymbol_,PERIOD_M5,"ZigZag",0,i)!=0){
            ZigZagPrices[found]=iCustom(iSymbol_,PERIOD_M5,"ZigZag",0,i);
            found++;
        }i++;
    }

Example2:

    while(found<=5)
    {
        if(iCustom(iSymbol_,PERIOD_M5,"ZigZag",0,i)!=0)
        {
            ZigZagPrices[found]=iCustom(iSymbol_,PERIOD_M5,"ZigZag",0,i);
            found++;
        }i++;
    }

Example3:

    while(found<=5)
        {
        if(iCustom(iSymbol_,PERIOD_M5,"ZigZag",0,i)!=0)
            {
                ZigZagPrices[found]=iCustom(iSymbol_,PERIOD_M5,"ZigZag",0,i);
                found++;
            }i++;
        }

This will make your codes easier to read and determine where the problem is by others.

 

Last night I did a version 1.9 where I placed a normalize double NewSL between the code:

it went something like: Normalizedouble NewSL = OrderOpenPrice() + trailing_stop_level3*Pointvalue

{ if (((ThirdTrailingStop > 0) && (Bid - OrderOpenPrice() >= TSTP3)&& (Bid - OrderOpenPrice() <TSTP4)))
Placed here ------->
for each level

Then I did if (NewSL> trailing_stop_level2*PointValue) OrderModify etc.....for each level. Thinking now maybe if this had been (NewSL>Orderstoploss) ?

This didn't work unfortunately as I believe the program just verified code as true or possibly ignored it and continued on backwards and forwards as the price fluctuated.

In your suggestion the OrderCloseprice is the close price of the current order so for example we open order at 1.3110 it is now 1.3150 - the order close price even though its the bid it would read as 1.3150 less the stop loss from the previous function? looking at MQl4 definition this Orderclose price returns the close price of the order. I would think that means the price that we closed the order at?! i am not sure what price this would return.

If not we would now have 40 pips unrealized profit -in my EA the previous stop level or locked in profit would have been at 15 pips ( 30 pips unrealized profit) so in this case it would be 1.3150-1.3125 (open order of 1.3110+15pips) = 25pips but the stop level would be 24pips. Not sure this would work.

Maybe something like - if(OrderOpenPrice + Bid > third trailing stop) ordermodify...

but then the EA could just read each level and move the orderstoploss accordingly backwards and forwards. Somehow I have to fix the orderstoploss to stay like a dog in his kennel until the next level of unrealized profit.

 

looking at MQl4 definition this Orderclose price returns the close price of the order. I would think that means the price that we closed the order at?...OrderClosePrice() returns the (Bid for Buy orders) and (Ask for Sell orders). It helps simplify the codes from you writing one logic for Buy and then another logic for Sells as you're currently doing.

In your suggestion the OrderCloseprice is the close price of the current order so for example we open order at 1.3110 it is now 1.3150 - the order close price even though its the bid it would read as 1.3150 less the stop loss from the previous function? Lets think only about Buy orders for now: We Buy@Ask and Sell@Bid...Other-words Buy-A, Sell-B. Or simply AB (thats how I remember). If we Buy at 1.3110 and current Bid is 1.3150 then the profit will be the Math Absolute Value of 150-110=40 Pips. For the sake of consistency we work in Pips(4-digit brokers) and Not-Points (5-digit brokers).

If not we would now have 40 pips unrealized profit -in my EA the previous stop level or locked in profit would have been at 15 pips ( 30 pips unrealized profit) so in this case it would be 1.3150-1.3125 (open order of 1.3110+15pips) = 25pips but the stop level would be 24pips. Not sure this would work... Ok, so far we're on the same page and understand that we're talking about 40 Pips in profit. But I don't understand why you're talking about level-3(30 Pips-Profit) instead of level-4(40 Pips-Profit). But lets entertain level 3 for a moment because we cannot get to level 4 unless we pass through level 3.

So when you hit level-3 which would have been 1.3110+0.0030=1.3140. You would have done an order-modify to Lock-in 15-Pips, 1.3110+0.0015=1.3125 or the New_StopLoss_Price. ***I think you're getting confused here because you're still thinking in Bid and Ask. Your brain wants to think of it as Bid-Bid so that it equals 25 pips. But thats not the case simply because the Broker would NEVER let you buy Low :) they'll make you wait til Ask drop down by 1-Pip before they let you make that Purchase. So instead of thinking about it as Bid vs Ask (again) think of it as OrderOpenPrice vs OrderClosePrice. Working with Bid/Ask had me Twisting like a Pretzel so I know how it feels. Price is just Price, broker already have their spreads so they don't care.

Anyways getting back on track, your New_StopLoss_Price=1.3125, this is the price you'll feed to the order-modify function because it only eat prices. Now if price goes up one more Pip from 1.3140->1.3141, if your code is trying to modify the order again with a new stop-price of 1.3126 this is where you have to tell it no. The It_Should_Be_For_This_Level_Of_Profit=1.3125 and you already know how to get that value so I'm not going into it again. Just compare the 1.3126 is clearly >(greater than) 1.3125 so then don't modify.

Other things to take Into Account:

- Do the Highest Profit Levels.....First. Then use the Break and Continue Commands to get out of the OrderSelect Loop or Move to the Next Order respectively. If you're not familiar with these commands then read the mql4 Book and don't skip chapters thinking its gonna make your learning faster or easier.

- As for the going back-wards instead of forward, you can use the same trick listed above. I also solved that problem within the codes I wrote in your first thread. It goes something like if(NewStopLoss > OldStopLoss)<---Newbie Version for Buy Orders. A more Advanced Version is

if( OrderStopLoss()==0 || (New_StopLoss_Price-OrderStopLoss())*Direction >iPoint2Pip ){

Where Direction= -1 or 1. To represent Buy or Sell.

And iPoint2Pip... Converts points into Standard Pip of 0.0001 or 0.01.

- You'll want to start doing order modify pre-checks to avoid Error#1. Search for order modify pre-check. or Error#1.

- You'll want to start considering Stop_Levels and Freeze_Levels to avoid setting the Stops closer than Broker Allows. Search for Error 130.

- You'll want to look at this article about cutting down the EA's codes.

- Don't depend on NormalizeDouble() for things like this. The > and < sign is the only friend you've got. Sometimes prices example Open[5] will = 1.4321000000000000000000000000000001. NormalizeDouble(to-5-digits) will give you 1.4321 for stuff like Printing, but not for comparing to other doubles. You'll be better off asking if(Open[5] < 1.43211){then do something;}

- Dont use == or >= or <= when working with doubles (except for maybe 0, if(Double==0)). Pretty much any equality or in-equality. Doubles may look == but usually they never are, and sometimes have a floating number hiding on the far right side where you cannot see it. If you're gonna ask to close all orders when Price==1.54321 then you might as well forget about it.

Reason: