I have a lot of questions on forums about how can we set a stoploss with values from an indicator or any other kind of points distance below or above orders computed by multiple of ATR. It is very easy to do it in ProOrder, and in this short article I will explain how to use conditional request to set a stoploss dynamically and accordingly to it.
Define a simple automated trading strategy example
Let’s make a simple crossover strategy of price over a 100 period simple moving average:
1 2 3 4 5 6 7 8 9 10 11 12 |
defparam preloadbars = 150 defparam cumulateorders = false mm = average[100](close) condition = close crosses over mm if condition then buy 1 lot at market set stop loss 200*pointsize endif |
This long only strategy has a fixed stoploss of 200 points. This stoploss will be written in the broker orderbook as soon as the order is launched by the platform. By using the pointsize instruction, we make sure that this strategy would be also effective for any kind of instrument : we are here trading the mini DAX but this code would be exactly the same for any forex pairs, no need to adapt anything because of instrument’s digits.
It’s ok but it is also a pre-determined fixed stoploss that does not take any market information.. but it’s always better to take market informations for takeprofit or stoploss placement!
Create a dynamic stoploss with an indicator
Because we use here a moving average to take positions on market, we can use it to create a dynamic zone that reflect market behaviour at the moment we make an entry in the market. Let’s add average true range band below the moving average:
1 2 |
mm = average[100](close) ATRsl = mm - highest[50](averagetruerange[100](close)*2) |
Now we have defined a dynamic stoploss zone adapted to our entries (red curve in the picture above).
Stoploss placement accordingly to the indicator value
To know exactly at which price evolve the ATR band stoploss, we have to calculate its distance value from price, at each new bar:
1 |
dynamicSL = close-ATRsl |
By this, we now known in the first place, where to put our stoploss:
1 2 3 4 5 6 7 |
if condition then buy 1 lot at market //first stoploss: SL = close-ATRsl set stop ploss SL dynamicSL = SL endif |
The pLOSS instruction is defined in points. We also set our dynamicSL to have the same value than the first stoploss for better comparison in the next part of the code.
Then in real time we calculate at which price we have to sell our position(s) by comparing the actual stoploss to the dynamic one :
1 2 3 4 5 6 7 |
//dynamicSL if longonmarket then if(ATRsl>dynamicSL) then dynamicSL=ATRsl endif sell at dynamicSL stop endif |
By doing this calculation, we ensure that our stoploss is moving accordingly while the price (or our ATRsl line) is moving higher. If not, we do not update our dynamicSL variable.
The entire code of the strategy example :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
defparam preloadbars = 150 defparam cumulateorders = false mm = average[100](close) ATRsl = mm - highest[50](averagetruerange[100](close)*2) condition = close crosses over mm if condition then buy 1 lot at market //first stoploss: SL = close-ATRsl set stop ploss SL dynamicSL = SL endif //dynamicSL if longonmarket then if(ATRsl>dynamicSL) then dynamicSL=ATRsl endif sell at dynamicSL stop endif GRAPH dynamicSL as "dyn" |
You surely understood here that the real order stoploss is not really moving, we are only setting a stop order to sell at market when the price is touching our dynamic zone stoploss instead. Though this code is compliant in real market trading conditions and compatible with IG market and ProRealTime CFD ProOrder trading. You should treat it as an example of what we can do to protect gain while trading in a trend market.
Hello Nicolas,
Is there any reason to use “sell” and not “set stop” in the “dynamicSL” conditional code? In this case, is not the same behavior?
Thanks.
Andrés.
This will have the same behavior than a stoploss. Sell a long position is actually closing it. Set stop don’t work if you wanna put your stoploss above the entry price.
How can this be implemented as a stoploss after manual entry short/long?
Sorry, but Prorelatime code can’t manage manual positions.
If a position is opened with IG via ProOrder, will the position appear in the IG platform and is it possible to manually adjust the stoploss level in the IG platform?
The position will be of course visible in your broker orders list. But if you adjust the stoploss level manually, the ProOrder system will be automatically stopped.
Thanks for the quick reply! When you adjust the stoploss level in the IG platform and the ProOrder system is stopped, is it possible to immediately restart the ProOrder system for it to open new positions?
Great post, it helped me with my long trailing stop. What is the ATRsl code for a short?
@ Seb – to make it a short stop just change to if a hort on market, flip the sign < and add exitshort. Look at other stop loss function that includes both long and short and I think you’ll understand
Thanks Victor, I got it working. For short you also need to modify:
//first stoploss:
SL= close–ATRsl
to:
//first stoploss:
SL= close
Correction
*//first stoploss:
SL= ATRsl
If the next bar open (where your position is opened) is different from the close, your stop will not be set at the indicator level, correct?
The stop order should be set at the level of when the read was read.
The thing is, I have an instance where a scaled-in position has different exit prices. In other cases scaled-in positions have one exit price. I don’t understand this, I thought a close/next bar open difference is the cause, but it must be something else then.
A second backtest run gave one exit in the same instance. I don’t know why the first run gave two, but it does its job now 🙂
It would be very interesting if we could “unset” a stop e.g. :
if conditions then
“unset” stop ploss SL
endif
Did you try to revert it to 0? SET STOP PLOSS 0
Does it really work, Nicolas? I’ll try it, just in case. Sometimes the obvious goes unnoticed 😐
Thanks for shaking me up.
Please see a little correction discussed here : https://www.prorealcode.com/topic/dynamic-stop-loss-atr-based/#post-66084
It shows the dynamic stop loss correctly in the graph window and removes some other small bugs.
An improved code for long positions is :
defparam preloadbars = 150
defparam cumulateorders = false
mm = average[100](close)
ATRsl = mm – highest[50](averagetruerange[100](close)*2)
condition = close crosses over mm
if condition and (not longonmarket) then
buy 1 lot at market
//first stoploss:
sell at ATRsl stop
currentdynamicstopprice = ATRsl
endif
//dynamicstopprice
if longonmarket then
if (ATRsl > currentdynamicstopprice) then
currentdynamicstopprice = ATRsl
endif
sell at currentdynamicstopprice stop
endif
GRAPH currentdynamicstopprice as “dynamic stop loss”
Good Day Ladies and gentlemen,
Can anyone assist me with simple code of STOPLOSS.
I want my Stoploss to be on the low of previous candle when I am long and High of previous candle when I am short.
Regards
Maano
Coded multiple times on forums, please use the search located under your avatar picture.