How to exit unprofitable trades with a percentage-based stop loss in TradingView?
How to exit unprofitable trades with a percentage-based stop loss in TradingView?
Section titled “How to exit unprofitable trades with a percentage-based stop loss in TradingView?”TL;DR
Turn your max-loss percentage into an absolute stop price and feed it tostrategy.exit()so every open position closes once it loses the configured percent.
At a Glance
Section titled “At a Glance”| Difficulty | Intermediate |
| Time to implement | 15-20 min |
| Category | Risk Management |
Quick Actions
Section titled “Quick Actions”Quick Start
Section titled “Quick Start”//@version=5strategy("Percent stop demo", overlay=true)
maxLossPercent = input.float(2.0, "Stop loss (%)", step=0.1) * 0.01
if ta.crossover(close, ta.ema(close, 50)) strategy.entry("Long", strategy.long)
if strategy.position_size > 0 stopPrice = strategy.position_avg_price * (1 - maxLossPercent) strategy.exit("Long %SL", from_entry="Long", stop=stopPrice)Why It Matters
Section titled “Why It Matters”Percentage stops scale with trade price so you risk the same fraction of capital regardless of the symbol or timeframe. They protect strategies from sudden swings while keeping risk consistent even when you pyramid or add to positions. Without translating the percentage to a price, TradingView can only submit tick- or price-based stops.
What You’ll Learn
Section titled “What You’ll Learn”- Gather percentage inputs and convert them into decimal factors.
- Compute long and short stop prices from
strategy.position_avg_price. - Submit or refresh the exits each bar so they track pyramiding entries.
- Plot stop levels to confirm they align with the percentage you expect.
Quick Reference
Section titled “Quick Reference”| Call | Purpose |
|---|---|
input.float(title, step) | Collects user-configurable stop percentages. |
strategy.position_avg_price | Returns the blended entry price to base calculations on. |
strategy.exit(id, from_entry, stop) | Submits the stop order at the calculated price. |
strategy.position_size | Confirms whether long or short exposure exists before sending stops. |
plot(series, style=plot.style_cross) | Visualises stop levels for debugging. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Collect percentage inputs
Accept separate values for long and short trades so you can fine-tune each side.longPercent = input.float(1.5, "Long stop (%)", minval=0.1, step=0.1) * 0.01shortPercent = input.float(1.2, "Short stop (%)", minval=0.1, step=0.1) * 0.01 -
Translate percentages to stop prices
Multiply the average entry by1 - percentfor longs and1 + percentfor shorts each bar.longStopPrice = strategy.position_avg_price * (1 - longPercent)shortStopPrice = strategy.position_avg_price * (1 + shortPercent) -
Submit exits whenever a position exists
Guard by position side so you only submit the relevant stop.if strategy.position_size > 0strategy.exit("Long %SL", from_entry="Long", stop=longStopPrice)if strategy.position_size < 0strategy.exit("Short %SL", from_entry="Short", stop=shortStopPrice)
Example Playbook
Section titled “Example Playbook”//@version=5strategy("Percentage stop breakout", overlay=true, initial_capital=50_000, default_qty_type=strategy.percent_of_equity, default_qty_value=5)
fastLen = input.int(20, "Fast EMA", minval=1)slowLen = input.int(60, "Slow EMA", minval=1)longPct = input.float(1.8, "Long stop (%)", minval=0.1, step=0.1) * 0.01shortPct = input.float(1.5, "Short stop (%)", minval=0.1, step=0.1) * 0.01
emaFast = ta.ema(close, fastLen)emaSlow = ta.ema(close, slowLen)
goLong = ta.crossover(emaFast, emaSlow)goShort = ta.crossunder(emaFast, emaSlow)
if goLong strategy.entry("Long", strategy.long)
if goShort strategy.entry("Short", strategy.short)
if strategy.position_size > 0 longStop = strategy.position_avg_price * (1 - longPct) strategy.exit("Long %SL", from_entry="Long", stop=longStop) plot(longStop, "Long stop", color=color.new(color.red, 0), style=plot.style_cross)
if strategy.position_size < 0 shortStop = strategy.position_avg_price * (1 + shortPct) strategy.exit("Short %SL", from_entry="Short", stop=shortStop) plot(shortStop, "Short stop", color=color.new(color.green, 0), style=plot.style_cross)- Stops refresh every bar, so pyramiding recalculates risk from the blended average price.
- Separate inputs let you run asymmetric long/short risk without editing code.
- Plotting the stop provides an immediate sanity check that the percentage lines up with the chart.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- Convert percentages to decimals once. Passing 2 instead of 0.02 places the stop 200% away and effectively disables protection.
- Clamp the result to sensible levels if you allow dynamic percentages (
math.max(percent, 0.001)). - Use
strategy.risk.max_position_loss()in addition to manual stops if you want broker-style fail-safes. - Remember that percentage stops move with the entry price—set them after every partial fill when pyramiding.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”My stop plots above price on a long position
Section titled “My stop plots above price on a long position”You’re probably adding instead of subtracting the percentage. Long stops should use (1 - percent); shorts use (1 + percent).
Stops vanish when I flatten
Section titled “Stops vanish when I flatten”That’s expected. strategy.exit() cancels the exit order when the associated entry closes. As soon as a new position opens the code resubmits the stop.
Can I trail based on percentage gain instead?
Section titled “Can I trail based on percentage gain instead?”Yes—replace the base calculation with strategy.position_avg_price * (1 + percent) for long take-profits or combine both stop and target in a single strategy.exit() call.
Key Takeaways
Section titled “Key Takeaways”- Percentage stops keep risk proportional to price level without hand-tuning ticks.
- Multiply the average entry by
1 ± percentto convert the percentage into a stop price. - Reissue the stops every bar so they adjust after scaling in or out.
- Visualise the stop level (or log it) to verify that the math matches your expectation.
Keep Going
Section titled “Keep Going”- Open AI Editor to apply the pattern with guided assistance
- Browse Strategy Examples for ready-to-run templates
- Connect to Live Trading when you are ready to automate
Adapted from tradingcode.net, optimised for Algo Trade Analytics users.