Skip to content

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
Call strategy.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.

DifficultyIntermediate
Time to implement15-20 min
CategoryRisk Management
//@version=5
strategy("Drawdown capped", overlay=true, initial_capital=50_000)
maxLossCash = input.float(5_000, "Max drawdown ($)")
strategy.risk.max_drawdown(maxLossCash, strategy.cash)
Tip. Choose between `strategy.cash` (currency) or `strategy.percent_of_equity` (percentage). Cash lets you mirror fixed loss limits; percent keeps the cap proportional to account size.

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.

  • Configure strategy.risk.max_drawdown with 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.
HelperPurpose
strategy.risk.max_drawdown(value, type)Sets the maximum allowed drawdown before TradingView halts trading.
strategy.equityUsed internally to compute drawdown; you can plot it for context.
input.float, input.percentExpose tunable drawdown thresholds.
strategy.opentrades, strategy.closedtradesInspect trade history when diagnosing halts.
label.new, plotHighlight the moment the drawdown guard activates.
  1. 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")
  2. Register the guard
    Feed the chosen value and mode into strategy.risk.max_drawdown.

    if modeIsPct
    strategy.risk.max_drawdown(maxLossPct, strategy.percent_of_equity)
    else
    strategy.risk.max_drawdown(maxLossCash, strategy.cash)
  3. 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)
//@version=5
strategy("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 - hhEquity
plot(drawdown, "Drawdown", color=color.new(color.red, 0), display=display.bottom)
var label status = na
if 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))
Why this works.
  • 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.
  • 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.

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.

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.

Yes. Once the cap hits, TradingView cancels any unfilled entries and prevents new ones until you restart the strategy.

  • strategy.risk.max_drawdown enforces 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.

Adapted from tradingcode.net, optimised for Algo Trade Analytics users.