Pine Script strategy.risk Controls: Drawdown and Position Limits | SG Group
Skip to the article
TradingView guide · Content reviewed 日本語で読む
Pine Strategy Engineering · TV20

Pine Script strategy.risk Controls: Drawdown, Intraday Loss, Losing Days and Position Limits

A stop from strategy.exit() belongs to a trade or entry. A strategy.risk.* command applies across the strategy and can cancel pending orders, close positions, block further actions or reduce size after its condition is reached. This guide does not recommend a percentage threshold. It audits what each strategy-wide command enforces and how that enforcement changes the trade sample.

Who this guide is for: Pine developers adding global guardrails or investigating why orders disappear after a risk command triggers

Key points to understand first

THREE CONTROL LAYERS

strategy.risk is a strategy-wide enforcement layer

  1. 01
    Signal & sizingentry condition / qty / pyramiding

    When and how much to enter

  2. 02
    Per-trade exitsstrategy.exit / strategy.close

    How a particular entry closes

  3. 03
    Strategy-wide guardrailsstrategy.risk.*

    Global permission, caps and stops

TRIGGER FLOW
  1. 1threshold reached
  2. 2cancel pending orders
  3. 3close or reduce where specified
  4. 4block further actions for the command scope
A guardrail does not make a weak result inherently safe. Triggering it changes the trade sample and equity path.
01 · Guardrail verdict

A risk command enforces behavior; it is not a performance metric

strategy.risk.max_drawdown() is not the variable that displays maximum drawdown. It is a command that cancels pending orders, closes an open position and stops further trade actions after its condition is reached. strategy.max_drawdown and report drawdown describe an observed result. Similar names do not mean the same job.

Three meanings of risk control
LayerExampleActionQuestion
Measurementstrategy.max_drawdown / report DDMeasure the resultHow far did equity fall?
Per-trade controlstrategy.exit stopCreate an exit for selected entriesWhere does this trade close?
Strategy-wide enforcementstrategy.risk.*Constrain all strategy actionsWhen must the strategy stop acting?

Separate a reported measurement from a command that changes later simulation behavior.

02 · Command map

Choose commands by trigger and enforcement scope

Roles of strategy.risk commands
CommandMonitorsTypical enforcementBoundary caveat
allow_entry_inPermitted directionAn opposite entry can close instead of reverseConfirm its scope on strategy.entry
max_cons_loss_daysConsecutive losing daysCancel, close and stop further trade actionsDefine the trading-day boundary
max_drawdownDD amount or percent from maximum equityCancel, close and stop later trade actionsPercent is based on maximum equity
max_intraday_filled_ordersFilled orders in a trading dayCancel, close and halt until session endAbove 1D it operates per chart bar
max_intraday_lossIntraday loss amount or percentCancel, close and halt until session endAbove 1D it operates per chart bar
max_position_sizePosition quantity after strategy.entryReduce entry quantity to the cap or suppress itDo not assume identical effect on every order API

Use the current reference manual for exact arguments, units and resumption behavior.

Commands can be combined. The first one to trigger changes orders and positions, which also changes the data observed by the others. Because the trade list may not identify the causal command on its own, retain input settings, version names, comments, alert messages or Pine logs.

03 · Enforcement semantics

Do not wrap a command in if and expect a temporary guard

Official TradingView guidance states that risk-management commands execute on every tick and order execution event and apply irrespective of their location in source. They cannot be deactivated for selected script executions. Treat their inputs as version-level settings rather than assuming a local conditional creates a time-limited guard.

The word intraday is timeframe-dependent. On a timeframe higher than one day, maximum intraday loss and filled-order count operate per chart bar. A weekly chart does not imply a hidden daily reset. Test the actual timeframe and symbol session.

Events to trace after a trigger
OrderQuestionEvidence
1Which bar/tick reached the threshold?Equity, daily P/L or filled-order count
2Which pending orders were cancelled?Order IDs and attempted reissues
3Was the position closed or quantity reduced?Exit comment, price and qty
4How long were later entries blocked?Next true condition with no order
5When did activity resume or end?Session boundary, next bar and later trade list

Complete the trace independently for each command.

04 · Interaction audit

Audit intersections with exits, pyramiding, margin and sessions

A strategy-wide command does not replace a per-trade exit. A bracket stop can fill first, or an intraday guard can close every open trade first. Exit reasons, holding time and MFE/MAE then change, so do not label ordinary and risk-enforced exits as one event class.

Common interactions
Other layerWhat can happenAudit method
strategy.exit bracketPer-trade SL/TP races the global guardSeparate exit IDs and comments
pyramidingMultiple entries reach position or fill-count caps soonerRecord open trades and transactions
marginA margin call reduces exposure before the risk thresholdDo not label it a guardrail trigger
session filterCandidate entries and reset boundaries changeFreeze IANA timezone and session
process_orders_on_closeThe enforced close fill timing can changeSeparate creation and fill bars

TV16 audits sizing, TV17 order states and TV19 session classification.

max_position_size() can reduce a strategy.entry() quantity so the resulting position stays below the cap. If even the minimum quantity cannot satisfy it, an entry can be suppressed. Do not assume it constrains strategy.order() in the same way; test each order API used by the script.

05 · Enforcement probe

Expose educational thresholds and measure one difference at a time

This structural example declares several risk commands. Its defaults are fictional mechanics-test values, not safe or recommended limits. In practice, begin with a version containing one command. The moving-average cross exists only to generate test events.

Pine Script v6: strategy-wide guardrail auditpine
//@version=6
strategy("Strategy risk guardrail audit", overlay = true, pyramiding = 3,
         initial_capital = 100000, margin_long = 100, margin_short = 100)

float maxDrawdownInput = input.float(20.0, "Max drawdown (%)", minval = 0.1, maxval = 100)
float maxDayLossInput = input.float(4.0, "Max intraday loss (%)", minval = 0.1, maxval = 100)
int maxFillsInput = input.int(6, "Max intraday filled orders", minval = 1)
int maxLossDaysInput = input.int(3, "Max consecutive loss days", minval = 1)
float maxPositionInput = input.float(4.0, "Max position units", minval = 1)

strategy.risk.max_drawdown(maxDrawdownInput, strategy.percent_of_equity)
strategy.risk.max_intraday_loss(maxDayLossInput, strategy.percent_of_equity)
strategy.risk.max_intraday_filled_orders(maxFillsInput)
strategy.risk.max_cons_loss_days(maxLossDaysInput)
strategy.risk.max_position_size(maxPositionInput)

float fast = ta.ema(close, 20)
float slow = ta.ema(close, 50)
bool longSignal = ta.crossover(fast, slow)
bool shortSignal = ta.crossunder(fast, slow)

if longSignal
    strategy.entry("Long", strategy.long, qty = 2)
if shortSignal
    strategy.entry("Short", strategy.short, qty = 2)

plot(fast, "Fast", color.aqua)
plot(slow, "Slow", color.orange)
plot(strategy.equity, "Equity", display = display.data_window)
plot(strategy.position_size, "Position size", display = display.data_window)

The values are fictional. Compare with otherwise identical baselines that remove one command at a time.

Give every input a unit and tooltip in production. Never mix cash and percentage limits in the version ledger. Plot observed metrics such as strategy.max_drawdown, equity and position size in a section separate from command settings.

06 · Guardrail budget

Measure current and hypothetical drawdown from peak equity

Assuming current equity does not exceed peak equity, the calculator uses peak equity, current equity, a configured drawdown percentage and a hypothetical next loss. It returns current drawdown, projected drawdown and the current remaining amount before the configured level. It does not recommend a threshold or predict an emulator fill.

Peak-based estimatecurrent DD amount = max(peak equity − current equity, 0)current DD % = current DD amount ÷ peak equity × 100projected DD % = max(peak − (current − next loss), 0) ÷ peak × 100current remaining amount = max(peak × guardrail % ÷ 100 − current DD amount, 0)Assumes current equity≤peak equity. The model does not reproduce open-profit updates, order fills, gaps, slippage or internal event ordering. If equity reaches zero or below while strategy.risk.max_drawdown uses strategy.percent_of_equity, pending orders are cancelled, open positions are closed and new orders remain disabled; do not interpret an arithmetic drawdown above 100% as usable capacity.
  1. Save the baseline

    Export Strategy Tester results without the risk command.

  2. Add one control

    Rerun identical conditions with only one guard added.

  3. Find the divergence

    Record the first bar, order or position where trade lists differ.

  4. Compare sample changes

    Review count, exit reason, holding time, distribution and drawdown.

  5. Build the combined version

    Combine only controls whose isolated effects are understood.

07 · Trigger ledger

Bind a trigger ledger to baseline and guarded versions

A lower drawdown is not proof that a command triggered, so keep a guardrail trigger ledger. For each command, store version ID, argument and unit, monitored basis, first trigger bar, pre-trigger value, cancelled orders, enforced closes, reduced quantity and later blocked entries, then bind the row to baseline and guarded CSV files.

Do not attribute a drawdown difference to the guard until the ledger explains the first trade-list divergence. Build a multi-command version only after each single-command trigger row is understood, and store risk exits, ordinary exits and margin calls as separate reasons.

DRAWDOWN GUARDRAIL CHECK

Drawdown from peak equity

Assuming current equity≤peak equity, estimate current and post-loss drawdown from maximum equity. This is not a threshold recommendation.

Current drawdown%
Post-loss drawdown%
Current remaining amountaccount currency

Input premise: b≤a. currentDD=max(a−b,0)÷a×100; projectedDD=max(a−(b−d),0)÷a×100; remaining=max(a×c÷100−max(a−b,0),0). Remaining is the current amount measured from current drawdown. Excludes orders, open-profit paths, gaps, slippage and event ordering. Verify the terminal percent-of-equity risk behavior separately when equity≤0.

Frequently asked questions

Are strategy.risk.max_drawdown() and strategy.max_drawdown the same?

No. The first is an enforcement command that stops strategy actions after its condition. The second is an observed maximum-drawdown value from the simulation.

Can I put a risk command in if to enable it only at certain times?

Do not design it as a temporary toggle. Official guidance says risk commands apply across the strategy regardless of source location and cannot be deactivated for selected executions.

Does max_intraday_loss reset daily on a weekly chart?

On timeframes above one day, the rule can operate per chart bar. Test the exact timeframe and session rather than inferring behavior from the word intraday.

What happens if equity reaches zero or below under percent-of-equity max_drawdown?

When strategy.risk.max_drawdown() uses strategy.percent_of_equity and equity reaches zero or below, pending orders are cancelled, the open position is closed and no new orders can be placed afterward. A calculator result above 100% is arithmetic, not evidence that the strategy can continue trading.

Does strategy.risk.max_position_size() always reject an oversized entry?

Not always. It can reduce the effective order quantity to fit the cap. If even the instrument’s minimum tradable quantity would violate the cap, the order is not placed. Keep requested and effective quantity as separate trigger-ledger fields.

Primary sources and verification links

  1. TradingView Pine Script — StrategiesOfficial risk-management commands, margin and order interactions.
  2. TradingView Pine Script — Reference Manual v6Official signatures, types and effects for strategy.risk commands.
  3. TradingView Pine Script — Strategies FAQOfficial sizing, custom statistics and strategy behavior examples.
  4. TradingView Help — Strategy propertiesOfficial capital, sizing, margin and recalculation settings.
  5. TradingView Pine Script — Migration to v6Official version changes including v6 margin defaults.

Edited and published by: SG Group · Editorial approach: We prioritize official TradingView Help Center and Pine Script documentation, then use exchange, regulator and other primary materials for market and product context. Features, data, pricing and connection terms change, so verify the current interface and linked sources before use.

Important notice: This article provides general education about TradingView interfaces, charts, alerts, screeners, paper trading and Pine Script. It is not investment advice, a trading signal, a recommendation of any instrument, data source or broker, or a guarantee of future price or profit. Features, pricing, data, exchange coverage, notifications, order integrations and Pine Script behavior vary by plan, region, connection and date and may change. Before risking money, verify current TradingView documentation and the terms of the relevant data source and connected provider, then rehearse the workflow with fictional data or paper trading.