Using a Moving Average cross for take profit once target has been reached

 

Hi guys,

I am looking to improve my EA to try to let the profits run a little further. At the moment the TP is set at the time of trade entry along with the stop. Part of the entry signal is a simple MA crossover, so hoping to use the same MA's to exit.

For a sell trade for example...

What I would like to do is once price has moved past my TP target (TP()), if the Fast MA (MAf0) is still below the slow MA(MAs0), then don't close yet, but instead wait for the next cross where the Fast MA becomes higher than the slow MA.

However if price gets to the TP and the Fast MA (MAf0) isn't below the slow MA(MAs0) then just take profit here.

I also need to close the trade though if price falls back to my original TP target even if another cross doesn't happen, to lock in profit. - I was hoping to not move the stops up by modifying the trade, but rather just close the trade if price falls back to the TP.

I have tried to do this using if statements and also using a while loop (which just seemed to go into a permanent loop - or at least stop once the trade was entered) I seem to be having issues with specifying the cross once price has moved past the TP.

I have attached the code I have tried so far, and a chart example


(In the example - the light blue line is the original TP line (it was a late entry in this example, which is why it is so close to entry). I would like to close the trade where the moving average next crosses which can be seen in the blue box.)

else if   (OpenOrderType()=="SELL")
   {
   if (buyprice() < (TP()-pips2dbl-Spread()) && MAf0 > MAs0)
      {
      TakeProfit=true;
      }
      
      else if (buyprice() < (TP()-pips2dbl-Spread()) && MAf0 < MAs0)
         {
        Print("1st objective");
         if (MAf1 < MAs1 && MAf0 > MAs0)
            {
            Print ("tp");
            TakeProfit=true;
            
            }
        
        }
        
      /*
      else if (buyprice() < (TP()-pips2dbl-Spread()) && MAf1 > MAs1 && MAf0 > MAs0)
         {
         TakeProfit=true;
         }
         
      else if (MAf1 < MAs1 && MAf0 < MAs0 && buyprice() == TP()) 
         {
         TakeProfit=true;
         }
         */
      }
return (TakeProfit);  

and i tried with a while loop...

else if   (OpenOrderType()=="SELL")
   {
   if (buyprice() < (TP()-pips2dbl-Spread()) && MAf0 > MAs0)
      {
      TakeProfit=true;
      }
      
      while (buyprice() < (TP()-pips2dbl-Spread()) && MAf0 < MAs0)
         {
         TakeProfit=false;
         continue;
        Print("1st objective");
         if (MAf1 < MAs1 && MAf0 > MAs0)
            {
            Print ("tp");
            TakeProfit=true;
            break;
            }
        
        }

Am i on the right track? in which case what am i doing wrong? or is there a better way to achieve this?

thanks

Simon

 

If the trade has moved about your price target, modifying the stoploss to your target price is exactly what you should do (in my opinion). It's faster, simpler and less problematic than having your code first check that price has exceeded the target, and then check that price has gone back below the target. And I can see no reason why not to use stoploss.

As for how to do it, if you only have only one order open at once, you can set the TP price to a double variable when the order is opened (if you have more than one order open at once, you can use an array of double variables). Then at the beginning of the start function, have a little IF, checking if the price has exceeded the TP, if yes, this can trigger more code.. i.e, move the stoploss up to the target price and start checking for whatever crossover signals you want.

I haven't read your code in depth (I hate reading code!) but I think your use of while loops is a bit off. The entire Start function runs for each tick (when a new bid and ask price is received), and a while loop runs inside the start function. If new prices are received while the start function is running, they are ignored. You can't use while loops to wait for new prices to arrive.

 
alladir:

If the trade has moved about your price target, modifying the stoploss to your target price is exactly what you should do (in my opinion). It's faster, simpler and less problematic than having your code first check that price has exceeded the target, and then check that price has gone back below the target. And I can see no reason why not to use stoploss.

As for how to do it, if you only have only one order open at once, you can set the TP price to a double variable when the order is opened (if you have more than one order open at once, you can use an array of double variables). Then at the beginning of the start function, have a little IF, checking if the price has exceeded the TP, if yes, this can trigger more code.. i.e, move the stoploss up to the target price and start checking for whatever crossover signals you want.

I haven't read your code in depth (I hate reading code!) but I think your use of while loops is a bit off. The entire Start function runs for each tick (when a new bid and ask price is received), and a while loop runs inside the start function. If new prices are received while the start function is running, they are ignored. You can't use while loops to wait for new prices to arrive.


Thanks alladir.

I was trying to have this code in a function - and then call it in Start().

int start()
  {

if (TakeProfit()==true)
 {
 closeall();
 }   

the function looks like this... (though I am only working on the sell code at the mo...

//// Set TP to be dynamic based on MA crossover

bool TakeProfit ()
{
   if (OpenOrderType()=="BUY")
      {
       if (sellprice() > (TP()+pips2dbl+Spread()) && MAf1 > MAs1 && MAf0 < MAs0)
        {
         TakeProfit=true;
        }
      
      else if (sellprice() > (TP()+pips2dbl+Spread()) && MAf1 < MAs1 && MAf0 < MAs0)
         {
         TakeProfit=true;
         }
         
      else if (MAf1 > MAs1 && MAf0 > MAs0 && sellprice() == TP()) 
         {
         TakeProfit=true;
         }
         
      }
      
   else if   (OpenOrderType()=="SELL")
   {
   if (buyprice() < (TP()-pips2dbl-Spread()) && MAf0 > MAs0)
      {
      TakeProfit=true;
      }
      
      else if (buyprice() < (TP()-pips2dbl-Spread()) && MAf0 < MAs0)
         {
        Print("1st objective");
         if (MAf1 < MAs1 && MAf0 > MAs0)
            {
            Print ("tp");
            TakeProfit=true;
            
            }
        
        }
        
     
      }
return (TakeProfit);   
}

interesting to know that about while loops not waiting for prices - i didn't realise that.

yes I only have one order open at a time, and I guess I could modify the Stoploss, but I just need to make sure there is some breathing room. If i move the stop right upto the original target TP, I will likely get stopped out before price has had a chance to keep moving in the right direction.

The issue i think could be (in the example anyway), that once buyprice < TP, (it is only then that i want to check for the next cross), but I think that MAf1 < MAs1 is not true at this point. So I need to delay this check somehow. I could add if MAf1 and MAs1 are also < buyprice, but that could be too much of a delay.

I am not sure how best to specify the next MA cross after price has crossed the original target TP.

 

I can't read your code, there's too many sub functions that you haven't included.. also I don't want to!

It's easy to give breathing room. If price goes above your target of 1.50000, then set the stoploss at 1.49950, or whatever. Or make the trigger price at 1.50050, and the stoploss at 1.50000.

More sophisticated as the trailing stop: set the stoploss as Bid - 0.00050 and modify the order if that price is higher than the previous stoploss set. I have a system of reducing the 'breathing room' as the price gets closer to the target, but it took me a good while to write it. Generally speaking, the more complex you make things, the less return you get on your effort.. get the big simple things working first.

Have a good read of The Book, see the link at the top. It will explain the basics, like when the Start function is called. This will save you a huge amount of time in the long run. I just took it to the gym with me.. took a week to get through but well worth it.

 
alladir:

I can't read your code, there's too many sub functions that you haven't included.. also I don't want to!

It's easy to give breathing room. If price goes above your target of 1.50000, then set the stoploss at 1.49950, or whatever. Or make the trigger price at 1.50050, and the stoploss at 1.50000.

More sophisticated as the trailing stop: set the stoploss as Bid - 0.00050 and modify the order if that price is higher than the previous stoploss set. I have a system of reducing the 'breathing room' as the price gets closer to the target, but it took me a good while to write it. Generally speaking, the more complex you make things, the less return you get on your effort.. get the big simple things working first.

Have a good read of The Book, see the link at the top. It will explain the basics, like when the Start function is called. This will save you a huge amount of time in the long run. I just took it to the gym with me.. took a week to get through but well worth it.


thanks - i have been through some of the book already.

i think the problem could be related to the MA not updating, but I cant understand why this would be. I am running a visual test and can see the MA move with price as time progresses. But when i print the MA values, they remain static??? In the examples below you can see price changes over time, but the MA values don't - very odd

here's some examples..

2013.06.28 14:42 MA cross EURUSD,M15: 1st objective1.30183 TP =1.3066 MAf1 = 1.3086 MAs1 = 1.3079 MAf0 = 1.3079 MAs0 = 1.3079

2013.06.28 14:17 MA cross EURUSD,M15: 1st objective1.30176 TP =1.3066 MAf1 = 1.3086 MAs1 = 1.3079 MAf0 = 1.3079 MAs0 = 1.3079

2013.06.28 13:53 MA cross EURUSD,M15: 1st objective1.30447 TP =1.3066 MAf1 = 1.3086 MAs1 = 1.3079 MAf0 = 1.3079 MAs0 = 1.3079

 
not much we can suggest without the code........
 
alladir:
not much we can suggest without the code........


here's the code for the MA cross - this is part of the criteria used for entry. and is run in the start function..

if (MACheck ()== true)

///////   MA Check

// checks to see if there is a MA cross



bool MACheck ()
{
 MAf0 = iMA(NULL, ExtMATF, ExtFastMA,0,0,0,0);
 MAf1 = iMA(NULL, ExtMATF, ExtFastMA,0,0,0,1);
 MAs0= iMA(NULL, ExtMATF, ExtSlowMA,0,0,0,0);
 MAs1 = iMA(NULL, ExtMATF, ExtSlowMA,0,0,0,1);
 
 


   if (Trend == UpTrend)
   {
      
      if (MAf1 < MAs1 && MAf0 > MAs0)
      
      return (1);
      else return (0);
    } 
   if (Trend == DownTrend)
   {
      
      if (MAf1 > MAs1 && MAf0 < MAs0)
      return (1);
      else return (0);
   }
   
}

it seems to work well enough to get me into trades, and i was hoping to use the variables - MAf0, MAf1, MAs0,MAs1 in my other function for the takeprofit. I have just tried another trade example and still have the same issue with the MA values not changing.

 
simoncs:


here's the code for the MA cross - this is part of the criteria used for entry. and is run in the start function..

if (MACheck ()== true)

it seems to work well enough to get me into trades, and i was hoping to use the variables - MAf0, MAf1, MAs0,MAs1 in my other function for the takeprofit. I have just tried another trade example and still have the same issue with the MA values not changing.


solved the issue of the static variables. I had specified the values of MAf0, MAf1, MAs0,MAs1 in the MACheck function, but this was only being called as part of the trade entry criteria, so they became frozen the moment a trade was entered.

I moved them out into the start function, and now they update correctly.

I still have issues getting the trades to close after the appropriate cross though, which I am still working through. For some reason it doesn't seem to respect waiting until price has passed the original TP. Even if i take out the MA cross part, it still doesn't close correctly.

bool TakeProfit ()
{
  if (OpenOrderType()=="BUY")
      {
        if (sellprice() >= (TP()+pips2dbl+Spread()))
        {
         TakeProfit=true;
         CloseReason = 1;
        }

}
      
   else if   (OpenOrderType()=="SELL")
   {
   if (buyprice <= (TP()-pips2dbl-Spread())) 
      {   
      TakeProfit=true;
      CloseReason = 1;
      }
     
    }
      
     
return (TakeProfit);   
}
 
simoncs:


solved the issue of the static variables. I had specified the values of MAf0, MAf1, MAs0,MAs1 in the MACheck function, but this was only being called as part of the trade entry criteria, so they became frozen the moment a trade was entered.

I moved them out into the start function, and now they update correctly.

I still have issues getting the trades to close after the appropriate cross though, which I am still working through. For some reason it doesn't seem to respect waiting until price has passed the original TP. Even if i take out the MA cross part, it still doesn't close correctly.


I seem to have found the problem, or rather i think I can correct it, but I am not sure of the reason...

in my previous post the code for the TakeProfit() function was what I was hoping to use.

it was then going to close the trades by this code in the start function

if (TakeProfit()==true)      /// if the takeprofit function is true then close all trades.
 {
 while(IsTradeContextBusy()) Sleep(10);
RefreshRates();
 closeall();

however for some reason this does not seem to work. I added some print statements, and the trades were closing even if price was not passed the TP.

If i changed the TakeProfit() to include the closeall() directly then it worked.

So my thoughts are that there is an issue with the way I am using functions? What am i doing wrong?

 
alladir:
not much we can suggest without the code........
simoncs:


I seem to have found the problem, or rather i think I can correct it, but I am not sure of the reason...

in my previous post the code for the TakeProfit() function was what I was hoping to use.

it was then going to close the trades by this code in the start function

however for some reason this does not seem to work. I added some print statements, and the trades were closing even if price was not passed the TP.

If i changed the TakeProfit() to include the closeall() directly then it worked.

So my thoughts are that there is an issue with the way I am using functions? What am i doing wrong?

It's hard to say without seeing the relevant code . . .
 
RaptorUK:
It's hard to say without seeing the relevant code . . .



sure no problem, i thought it might be something fundamental, about the way functions should be used, so was hoping not to have to post loads of code for you to read, but here are the relevant parts of code below.

this assumes there is an open trade... and i have no issues with getting into the trade at the correct point. Just closing it.

calling the TakeProfit() running in Start.

if (TakeProfit()==true)      /// if the takeprofit function is true then close all trades.
 {
 while(IsTradeContextBusy()) Sleep(10);
RefreshRates();
 closeall();

then all my other functions are outside the Start function, and just referenced in start as necessary.

the closeall()

//CloseALL function - to close all trades if they are still open at the end of the week
void closeall()
{
int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNumber       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      //Print ("Closereason= ", CloseReason," BuyPrice=", DoubleToStr(buyprice(),Digits)," Ask =",DoubleToStr(Ask,Digits)," SellPrice=", DoubleToStr(sellprice(),Digits),
                  " Bid =",DoubleToStr(Bid,Digits), " BuyTP = ",DoubleToStr((TP()+pips2dbl+Spread()),Digits)," SellTP = ",DoubleToStr((TP()-pips2dbl-Spread()),Digits),
                    " MAf0=",DoubleToStr(MAf0,Digits)
      //," MAs0=",DoubleToStr(MAs0,Digits)," MAf1=",DoubleToStr(MAf1,Digits)," MAs1=",DoubleToStr(MAs1,Digits));
   } //  end of For loop
   
}

the TakeProfit() - why does this not close the trade after price has passed the TP?

bool TakeProfit ()
{
  if (OpenOrderType()=="BUY")
      {
      RefreshRates();
        if (sellprice() >= (TP()+pips2dbl+Spread()))
        {
      
         TakeProfit=true;
         //closeall();
         //CloseReason = 1;
        }
}

else if   (OpenOrderType()=="SELL")
   {
   RefreshRates();
   if (buyprice() <= (TP()-pips2dbl-Spread())) 
      { 
      TakeProfit=true;
      //closeall();
      //CloseReason = 1;
      }
      
    }
      
     
return (TakeProfit);   
}

Openordertyp() to determine if there is an open order, and what type it is.

/// Open Order Type 
string OpenOrderType()
{ 
if(OrdersTotal()!=0)
           {
           OrderSelect(0, SELECT_BY_POS);
           //TicketDate=OrderOpenTime();
           //StartTime=TicketDate; 
           TicketNumber=OrderTicket(); 
           TicketType=OrderType(); //OP_BUY OP_SELL
           if (TicketType == OP_BUY)
              {ordertyp = "BUY";}
           else if (TicketType == OP_SELL)
              {ordertyp = "SELL";}
            }     
return(ordertyp);
}

buyprice(), sellprice(), and spread() - I thought it could be related to the buyprice or sellprice functions so replace with Bid and Ask, but it made no difference.

///buyprice function

double buyprice ()
{
point_2 =Point/2;
return (Ask + point_2);
}

///sellprice function
double sellprice ()
{
point_2 =Point/2;
return (Bid +point_2);
}

////Spread function
double Spread ()
{
return (MarketInfo(Symbol(),MODE_SPREAD) * Point);
} 

TP()

/////Define TP function

double TP()
{

  TP = NormalizeDouble(MathAbs(Fib50Line),Digits); 
 }
return(TP);   
}

the question is why does Takeprofit() not close the trade when price moves past the TP if i set TakeProfit =true and then try to close it, as opposed to using closeall() inside the TakeProfit() which does work?

Reason: