In this article, we will take a quick look at plotting stop losses and take profits. This technique has actually been covered in a couple of posts on this site already but there has never been a dedicated article on the subject and requests for this subject still occasionally come in!
Plotting Stop Losses and Take Profits
In Pine Script send stop loss and take profit orders by using thestop
andlimit
parameters for the strategy.exit()
and strategy.order()
functions. In fact, the strategy.entry()
function also supports sending stop
andlimit
orders. However, that would be considered an entry rather than a stop loss or take profit and thus out of the scope of this article. Having said that, the techniques used in this article can be used for entries and just about any line you want to track/plot.
Sending Orders
There are a couple of the reasons why people can sometimes find plotting the stop loss and take profit lines a little challenging:- They are using the
profit
andloss
parameters instead ofstop
andlimit
- They calculate the stop loss and/or profit level once at the time of entry.
profit
and loss
are measured in ticks
. As such, the numbers we use to feed these parameters do not provide a natural price level we can plot. As such, a bit more work would be required to plot the level. Note: For more information on the various stop-loss options, see this article.
The second item in the list above is often utilized when users wish to use a more complex calculation for their stop and some parts of that calculation can change between bars. For example, one common request is to set the stop
of a long entry at low
– ATR
(Average True Range).
If you don’t place strategy.exit()
function inside an if
statement, you can find that the stop line bounces around every bar as the ATR
value is updated.
Example
Before we move into a solution, let’s run through a quick example of placingstrategy.exit()
inside an if
statement in case you are having trouble visualizing it. The example below will calculate the stop
level and only send the order once when a longCondition
orshortCondition
is met.
//@version=3 strategy("My Strategy", overlay=true) ATR = atr(7) longCondition = crossover(sma(close, 100), sma(close, 200)) if (longCondition) stop_level = low - ATR profit_level = close + ATR strategy.entry("My Long Entry Id", strategy.long) strategy.exit("TP/SL", "My Long Entry Id", stop=stop_level, limit=profit_level) shortCondition = crossunder(sma(close, 100), sma(close, 200)) if (shortCondition) stop_level = high + ATR profit_level = close - ATR strategy.entry("My Short Entry Id", strategy.short) strategy.exit("TP/SL", "My Short Entry Id", stop=stop_level, limit=profit_level)This will result in a chart that looks something like this:
Plotting Solution
The key to plotting stop losses and take profits is to create aseries
(new line/variable) that is updated only when your stop-loss is updated. For example, if you only send a stop loss order once when the longCondition
is met, then we similarly we only update our new series
at that time too. Otherwise, we keep the same value as the previous bar. We can do this using something called a Ternary Conditional Operator. Click on that link for a more detailed tutorial on them.
The example below will expand on the first example to both plot the lines and fix the levels.
//@version=3 strategy("My Strategy", overlay=true) ATR = atr(7) longCondition = crossover(sma(close, 100), sma(close, 200)) if (longCondition) strategy.entry("My Long Entry Id", strategy.long) shortCondition = crossunder(sma(close, 100), sma(close, 200)) if (shortCondition) strategy.entry("My Short Entry Id", strategy.short) long_stop_level = na long_profit_level = na long_stop_level := longCondition ? low - ATR : long_stop_level[1] long_profit_level := longCondition ? close + ATR : long_profit_level[1] short_stop_level = na short_profit_level = na short_stop_level := shortCondition ? high + ATR : short_stop_level[1] short_profit_level := shortCondition ? close - ATR : short_profit_level[1] strategy.exit("TP/SL", "My Long Entry Id", stop=long_stop_level, limit=long_profit_level) strategy.exit("TP/SL", "My Short Entry Id", stop=short_stop_level, limit=short_profit_level) plot(strategy.position_size <= 0 ? na : long_stop_level, color=red, style=linebr, linewidth=2) plot(strategy.position_size <= 0 ? na : long_profit_level, color=green, style=linebr, linewidth=2) plot(strategy.position_size >= 0 ? na : short_stop_level, color=red, style=linebr, linewidth=2) plot(strategy.position_size >= 0 ? na : short_profit_level, color=green, style=linebr, linewidth=2)
Commentary
Before we start, It is worth noting that the example above could be achieved usingvaluewhen()
. This is outlined in the Save a variable / store a value for later post. However, it is a good idea to become familiar with ternary conditional operators as they will allow you to create some complex and unique trailing stop losses.
Although the code appears to be longer, there are actually only a few changes between the first example and this one. The first is that strategy.exit()
is no longer to be placed inside an if
statement. When we do this, we will start updating the order on every bar. However, since our value is not changing, then it doesn’t matter.
Next, we calculate our levels. When we do this, we must declare each series
with long_stop_level = na
first. This is because the code is written in version 3 of pinescript and if we want to reference a previous value of the same series
(e.g long_stop_level[1]
), we will receive an error if we do not declare it first.
The ternary conditional operators might seem daunting at first but they are essentially saying (for a long example):
- If a
longCondition
is met, set the line atlow
–ATR
. - If not, keep the previous value.
On the Charts
Once plotted, the chart should look like this:A Simple Alternative for Fixed % Stops / Profits
If you just simply want to set a stop loss or take profit at x% distance away from your entry level and you are NOT pyramiding (entering in the same direction multiple times), then you can just use the variablestrategy.position_avg_price
to calculate the lines.
(Note this example also features in the stop loss tutorial for Tradingview)
//@version=3 strategy("Stop Loss Example: Simple Stoploss", overlay=true) sma_per = input(200, title='SMA Lookback Period', minval=1) sl_inp = input(2.0, title='Stop Loss %', type=float)/100 tp_inp = input(4.0, title='Take Profit %', type=float)/100 sma = sma(close, sma_per) stop_level = strategy.position_avg_price * (1 - sl_inp) take_level = strategy.position_avg_price * (1 + tp_inp) strategy.entry("Simple SMA Entry", strategy.long, when=crossover(close, sma)) strategy.exit("Stop Loss/TP","Simple SMA Entry", stop=stop_level, limit=take_level) plot(sma, color=orange, linewidth=2) plot(stop_level, color=red, style=linebr, linewidth=2) plot(take_level, color=green, style=linebr, linewidth=2)
Mini Commentary
When we don’t have a position in the market thestrategy.position_avg_price
value equals na
. This is helpful for plotting because we are able to plot the stop loss line only when we are in a position. na
is never plotted and therefore we don’t need to add a ternary conditional operator like in the example above. .
Note: To ensure our lines are plotted tidily, the linebr
style should be used. This will ensure that you don’t have long lines joining up gaps between when the value is na
. You will see the difference if you just use a normal line style.
Find This Post Useful?
If this post saved you time and effort, please consider support the site! There are many ways to support us and some won’t even cost you a penny.
Brave
Backtest Rookies is a registered with Brave publisher!
Brave users can drop us a tip.
Alternatively, support us by switching to Brave using this referral link and we will receive some BAT!
Tradingview
Referral Link
Enjoying the content and thinking of subscribing to Tradingview? Support this site by clicking the referral link before you sign up!
PayPal
BTC
3HxNVyh5729ieTfPnTybrtK7J7QxJD9gjD
ETH
0x9a2f88198224d59e5749bacfc23d79507da3d431
LTC
M8iUBnb8KamHR18gpgi2sSG7jopddFJi8S
Hi!! I’m struggling to find a way to create a strategy according some parameters:
enterCond = xxxxxxx
entry: when enterCond == true
initial stop loss: entry price – 1.5%
Target 1: entry + 3% sell 50% and change stop loss to enter price
Target 2: entry + 5% sell 50% and change stop loss to T1
Target 3: entry + 7% sell 100%
———— my code —————–
buyCond = xxxxxxxxx
sl_inp = input(1.5, title=’Stop Loss %’, type=float)/100
tp_inp1 = input(3.0, title=’Take Profit 1 (%)’, type=float)/100
tp_inp2 = input(5.0, title=’Take Profit 2 (%)’, type=float)/100
tp_inp3 = input(7.0, title=’Take Profit 3 (%)’, type=float)/100
// First Position
first_long = buyCond and strategy.position_size == 0
if first_long
//initial stop loss: entry price – 1.5%
strategy.entry(“Long”, strategy.long, stop=(strategy.position_avg_price*(1-sl_inp)))
//sl1 = strategy.position_avg_price * (1 – sl_inp)
tp1 = strategy.position_avg_price * (1 + tp_inp1)
tp2 = strategy.position_avg_price * (1 + tp_inp2)
tp3 = strategy.position_avg_price * (1 + tp_inp3)
//Target 1: entry + 3% sell 50% and change stop loss to enter price
strategy.order(“Long”, strategy.long, qty=strategy.equity/2, stop=strategy.position_avg_price, when=close==tp1)
//Target 2: entry + 5% => sell 50% and change stop loss to T1
strategy.order(“Long”, strategy.long, qty=strategy.equity/2, stop=tp1, when=close==tp2)
strategy.close(“Long”, when=close==tp3)
———————————-
Could you help me please?
BUT if i want to set my stoploss at the YESTERDAY LOW and i want it is FIXED ??? it is impossible??? tv is a toy…