MT4 - Solved a problem I had with writing a trailing stop function, wondering what people think.

 

Hi all :) 


Making my own EA according to the No Nonsense Forex method. One of the points in that method is to use a trailing stop based on the ATR score at the time of making the order. 

My own code was taking the current ATR value instead (Timeframe daily). Largely because i couldnt find how to 'record' and hold the value in any way. The trailing stop worked perfectly - but the problem is that when volatility drops, the ATR usually drops too - and that made my trailing stops smaller (or bigger if the opposite happened). Not ideal. 

old code: 

double buysl =Bid-iATR(NULL,0,14,1)*AtrSlTs;

(where AtrSlTs is 1.5) 

my solution is a little convoluted so im including the whole chunk. Sorry if its hard to read :P

First when placing an order my code injects the current ATR value into the order as magic number. Had to convert to int, hence the MathFloor and *10000. 

==============================================

int magicAtr(){int cream = MathFloor((iATR(NULL,0,14,1))*10000);return cream;}

   

bool TradeEntry(int type)

{if(type==0){double bsl1=Ask-iATR(NULL,0,14,1)*AtrSl;if(OrderSend(Symbol(),OP_BUY,Volume_,Ask,10,bsl1,0,NULL,magicAtr(),0,clrGreen)){return true;}}

 if(type==1){double ssl1=Bid+iATR(NULL,0,14,1)*AtrSl;if(OrderSend(Symbol(),OP_SELL,Volume_,Bid,10,ssl1,0,NULL,magicAtr(),0,clrRed)){return true;}}

return false;}

==============================================

Then after the order reaches a take profit point (1*ATR) it closed half, after which point it becomes valid for the trailing stop function. 

==============================================

void trailing()

{

   for (int i=0; i<=OrdersTotal(); i++)

   {

      if(OrderSelect(i, SELECT_BY_POS,MODE_TRADES))

      {

         double magicAtr2 =OrderMagicNumber();

         double creamConversion = (magicAtr2/10000)*AtrSlTs;

         double buysl = Bid-creamConversion; //dont ask me about the naming here.. its random :P

         double sellsl = Ask+creamConversion;

         double ordOp =OrderOpenPrice();

         double ordSl =OrderStopLoss();

         double ordTp =OrderTakeProfit();

         int ordTick =OrderTicket();

         int ordType =OrderType();            

         double ordVolume =OrderLots();



         if(ordVolume == 0.01 && ordType == OP_BUY)

         {  

            double newBSl = buysl;

            if(newBSl > ordSl)

            {int mod=OrderModify(ordTick,ordOp,newBSl,ordTp,0,clrYellow);}

         }

         if(ordVolume == 0.01 && ordType==OP_SELL)

         {  

            double newSSl = sellsl;

            if(newSSl < ordSl)

            {int mod=OrderModify(ordTick,ordOp,newSSl,ordTp,0,clrYellow);}

         }

}}}

==============================================

As you can see i simply extract the magic number and divide by 10000 again to get the pip value. The system then simply passes it as an OrderModify. The code nags about data conversion, which is fair, but it works! 

Most of you will realize that this wont work for any pair that goes with the JPY, because the pips are different there. I could make a separate EA for those pairs, or just make a menu entry where you put in either which pair to trade or what the multiplication factor is. Those arent ideal, but thats how far i got with this idea. 

I would love to hear what you think :) Have a nice day! 

Edit: Changed my code sections with the code button. Didnt know that was a thing, still learning! 

Extract profit down to the last pip
Extract profit down to the last pip
  • www.mql5.com
The article describes an attempt to combine theory with practice in the algorithmic trading field. Most of discussions concerning the creation of Trading Systems is connected with the use of historic bars and various indicators applied thereon. This is the most well covered field and thus we will not consider it. Bars represent a very artificial entity; therefore we will work with something closer to proto-data, namely the price ticks.
 
Good work…. BUT… Why 10000 ? You only plan to use it on 5 digits only? What if you place on JPY pairs… or NonFX… your cream VALUE will fail. Also… Why use magic Numbers to Store a VALUE … use global variables … 
 
DannyBass #:
Good work…. BUT… Why 10000 ? You only plan to use it on 5 digits only? What if you place on JPY pairs… or NonFX… your cream VALUE will fail. Also… Why use magic Numbers to Store a VALUE … use global variables … 

Hi DannyBass, thank you for replying! 

Well the 10k is to make the ATR into an int, otherwise i cant store it in the magic number. Im aware it creates a problem for the jpy pairs, but i could simply copy paste my EA into an JPY friendly version by changing the 10k into 1k (or 100, didnt fully check what pips were there). The main point in using magic numbers is because theyre persistent during the whole process. 

Im totally into using more conventional methods, but apart from vaguely conceptualizing an array storing the ATR values at the time a trade is made and then somehow connecting the numbers in the array to the orders made.. i got nothing. Also, when i test my EA over 10 or 15 years its going to have a loooot of trades, not sure if that goes well with arrays, need to look into that. 

I shouldve maybe said im just a crazy idiot writing while he discovers how all this beautiful coding stuff works, so if you have something more specific, like how i could use those global variables you mention, i'd be happy to hear what youre thinking. 

 
I am using a similar code but I use percentage of TakeProfit to modify the order. The closing half orders is interesting. So you have half orders with a wider TakeProfit so that it's not closed when the TakeProfit price is hit?
 
William William #:
I am using a similar code but I use percentage of TakeProfit to modify the order. The closing half orders is interesting. So you have half orders with a wider TakeProfit so that it's not closed when the TakeProfit price is hit?

Hi William William :) 

Thanks for your reply! Actually i dont really set a take profit traditionally, i have my code check on every tick whether the price has reached the takeprofit that i want (which is also calculated on the ATR, now that i think of it i should probably stabilize that in the same way i did with the trailing stop) and then, since my volume of trades is 0.02, it takes of half of that, leaving a 0.01 order and slapping on a break even stoploss on the opening price. Then my trailing stop code check once per candle if it should stay or go up. 

Basically the only thing i put on the order when i create it is the stoploss, the rest is done in realtime while the order runs. Static safetynet, but dynamic takeprofit and trailing stoploss i guess! :P

Using a percentage of the TakeProfit is hard for me, because i dont have one. And if i did it would close the whole order, like you implied. 

 
You could, instead of storing the ATR value, always query the iATR Indikator for that value, as you only need it for running positions.

This way, you wouldn't have to misuse the magic number for storing that value.

Since you always use the ATR at open time, you have the time index from the ATR you want.

So you could use iTimeShift to get the correct index and then query the iATR Buffer for it.

And instead of a fixed 10000 you could use MathPow(10, _Digits) or 1.0/Point()

Boths times you would auto adjust to the symbol.
 
Bob #:

Hi DannyBass, thank you for replying! 

Well the 10k is to make the ATR into an int, otherwise i cant store it in the magic number. Im aware it creates a problem for the jpy pairs, but i could simply copy paste my EA into an JPY friendly version by changing the 10k into 1k (or 100, didnt fully check what pips were there). The main point in using magic numbers is because theyre persistent during the whole process. 

Im totally into using more conventional methods, but apart from vaguely conceptualizing an array storing the ATR values at the time a trade is made and then somehow connecting the numbers in the array to the orders made.. i got nothing. Also, when i test my EA over 10 or 15 years its going to have a loooot of trades, not sure if that goes well with arrays, need to look into that. 

I shouldve maybe said im just a crazy idiot writing while he discovers how all this beautiful coding stuff works, so if you have something more specific, like how i could use those global variables you mention, i'd be happy to hear what youre thinking. 

As it has been said, you don’t need to store anything for the ATR… you only need to extract the value you need… as far as I understand… the No Nonsense way is to use ATR as SL… but current ATR… you use the last closed bar ATR… not the ATR which was when you have opened the trade… it makes more sense … if you have one trade opened for 12 days, you should not use the ATR value from 12 days ago… use last closed bar ATR… adapt to the current condition…. As for the variables … you can use a variable saved in the global scope area, but better , and safer Global Variables …

P.S. : NoNonsense Forex is a YouTube product… this is what they sell… dont expert miracles as they Say… But is quite good for education … not so much for making money though…I don’t Believe that VP, successful trade as he sais ,…is doing what is says … trading 30 minutes a day… and a strategy that is only based on few indicators … most of the strategies indicator based can be automated … all of us should be milionários if it only be that easy… I mean sooner or later, all indicators will get you into a 3-400 pip move… but look at the charts… how often is those moves occur… not so often… THE TREND IS YOUR FRIEND… you are not seeing that friend very much…. 😁
 

Hi Dominik, Great feedback! Im going to look into that iTimeShift :D 

Hi DannyBass, Haha yeah, i know.. Teachers teach because they dont do, right? ;) I've been studying this method for two years now, it seems to make sense. But im also looking into other strategies. So far i've taught myself to program because it seems really cool.. And to be honest im really appreciating the feedback! :D I will look more into both your feedback for sure! 

 
Dominik Christian Egert #:
You could, instead of storing the ATR value, always query the iATR Indikator for that value, as you only need it for running positions.

This way, you wouldn't have to misuse the magic number for storing that value.

Since you always use the ATR at open time, you have the time index from the ATR you want.

So you could use iTimeShift to get the correct index and then query the iATR Buffer for it.

And instead of a fixed 10000 you could use MathPow(10, _Digits) or 1.0/Point()

Boths times you would auto adjust to the symbol.
When you say iTimeShift… you meant iBarShift right? 
 
DannyBass #:
When you say iTimeShift… you meant iBarShift right? 
Yes, sorry.

I typed from my head, sometimes I mix it up.

BTW, CopyBuffer allows you also to address the value directly by using datetime as input, so you could skip iBarShift usage all together.




 
thats exactly why i posted my meager code.. Thats some good stuff. I will post my updated code soon, after i update it :) Might take a few days, i work a 24/7 job with an insane manager so im always tired :) But y'all feedback gave me some very helpful insights!