Stop trading based on a maximum loss in TradingView
Stop trading based on a maximum loss in TradingView
Section titled “Stop trading based on a maximum loss in TradingView”TL;DR
Callstrategy.risk.max_drawdown(value, type)to define the deepest loss your strategy may tolerate; TradingView closes open positions and blocks new ones once that threshold is breached.
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("Drawdown capped", overlay=true, initial_capital=50_000)
maxLossCash = input.float(5_000, "Max drawdown ($)")strategy.risk.max_drawdown(maxLossCash, strategy.cash)Why It Matters
Section titled “Why It Matters”A long losing streak can cripple a system—or worse, force aggressive recovery trades. A drawdown brake forces discipline: once the loss runs past the limit, TradingView flattens positions and ignores further entries until you adjust the script or restart the backtest.
What You’ll Learn
Section titled “What You’ll Learn”- Configure
strategy.risk.max_drawdownwith cash or percentage values. - Pair the drawdown guard with inputs so testers can adapt limits quickly.
- Understand how TradingView measures drawdown (equity-based, includes open P&L).
- Visualise drawdown to verify when the guard stops the strategy.
Quick Reference
Section titled “Quick Reference”| Helper | Purpose |
|---|---|
strategy.risk.max_drawdown(value, type) | Sets the maximum allowed drawdown before TradingView halts trading. |
strategy.equity | Used internally to compute drawdown; you can plot it for context. |
input.float, input.percent | Expose tunable drawdown thresholds. |
strategy.opentrades, strategy.closedtrades | Inspect trade history when diagnosing halts. |
label.new, plot | Highlight the moment the drawdown guard activates. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Expose the drawdown threshold
Provide inputs for both cash and percentage caps so users can choose.maxLossCash = input.float(3_000, "Max loss ($)", minval=0)maxLossPct = input.float(8.0, "Max loss (%)", step=0.1)modeIsPct = input.bool(false, "Use percentage cap") -
Register the guard
Feed the chosen value and mode intostrategy.risk.max_drawdown.if modeIsPctstrategy.risk.max_drawdown(maxLossPct, strategy.percent_of_equity)elsestrategy.risk.max_drawdown(maxLossCash, strategy.cash) -
Monitor drawdown
Plot equity or add labels so you know when the cap is triggered.dd = strategy.equity - ta.highest(strategy.equity, 1000)plot(dd, "Drawdown", color=color.new(color.red, 0), display=display.bottom)
Example Playbook
Section titled “Example Playbook”//@version=5strategy("Breakout with drawdown stop", overlay=true, pyramiding=0, initial_capital=50_000)
maxLossCash = input.float(4_000, "Max drawdown ($)", minval=100, step=100)usePercent = input.bool(false, "Use percent instead")maxLossPct = input.float(12.5, "Max drawdown (%)", step=0.1)
if usePercent strategy.risk.max_drawdown(maxLossPct, strategy.percent_of_equity)else strategy.risk.max_drawdown(maxLossCash, strategy.cash)
len = input.int(40, "Breakout length", minval=2)entryBuff = input.int(1, "Entry buffer (ticks)", minval=0)stopATR = input.float(2.5, "Stop ATR multiple", step=0.1)atrLen = input.int(14, "ATR length")
atr = ta.atr(atrLen)high = ta.highest(high, len)low = ta.lowest(low, len)
longTrigger = ta.crossover(high, high[1])shortTrigger = ta.crossunder(low, low[1])
if longTrigger strategy.entry("Breakout L", strategy.long)if shortTrigger strategy.entry("Breakout S", strategy.short)
if strategy.position_size > 0 strategy.exit("LX", "Breakout L", stop=strategy.position_avg_price - atr * stopATR)if strategy.position_size < 0 strategy.exit("SX", "Breakout S", stop=strategy.position_avg_price + atr * stopATR)
hhEquity = ta.highest(strategy.equity, 10_000)drawdown = strategy.equity - hhEquityplot(drawdown, "Drawdown", color=color.new(color.red, 0), display=display.bottom)
var label status = naif barstate.islast if not na(status) label.delete(status) halted = strategy.risk.allocation == 0 and drawdown <= (usePercent ? -maxLossPct * 0.01 * strategy.initial_capital : -maxLossCash) text = "Equity: " + str.tostring(strategy.equity, "##,###.00") + "\nDrawdown: " + str.tostring(drawdown, "##,###.00") + "\nTrading: " + (halted ? "PAUSED" : "ACTIVE") status = label.new(bar_index, close, text, style=label.style_label_left, textcolor=color.white, bgcolor=color.new(halted ? color.red : color.green, 70))- The guard is registered once—TradingView enforces the limit on every historical and real-time bar.
- Inputs let you toggle between cash and percentage drawdown without editing code.
- Visual feedback (plot + label) confirms when the brake halts trading.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- Drawdown is equity-based, so unrealised losses count. Expect the guard to fire before closed-trade stats reflect the same loss.
- Slippage and gaps can push drawdown beyond the requested max. Set the limit slightly tighter if you need a hard cash stop.
- Once triggered, the guard stays active until you remove or modify it and rerun the strategy. There’s no in-script reset.
- Combine with other risk tools (
strategy.risk.max_intraday_loss,strategy.risk.max_position_size) for layered protection.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”The strategy stopped but drawdown is smaller than my limit
Section titled “The strategy stopped but drawdown is smaller than my limit”Check the unit: strategy.cash expects raw currency amounts; strategy.percent_of_equity expects percentages. Mixing them leads to unexpected halts.
Can I disable trading only temporarily?
Section titled “Can I disable trading only temporarily?”strategy.risk.max_drawdown is permanent for the script run. If you need time-window pauses, implement your own logic with custom equity tracking and entry guards.
Does the guard cancel pending orders?
Section titled “Does the guard cancel pending orders?”Yes. Once the cap hits, TradingView cancels any unfilled entries and prevents new ones until you restart the strategy.
Key Takeaways
Section titled “Key Takeaways”strategy.risk.max_drawdownenforces a hard stop on strategy losses, measured with equity (open + closed P&L).- Decide whether to cap losses with a cash amount or as a percent of equity, and expose the choice via inputs.
- Visualise drawdown so you know exactly when the guard triggers and confirm the strategy pauses as expected.
- Combine with other risk controls for a comprehensive safety net around automated trading.
Keep Going
Section titled “Keep Going”- Open AI Editor to apply the pattern with guided assistance
- Browse PineScript 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.