Skip to content

Understand the two order phases of TradingView Pine strategy scripts

Understand the two order phases of TradingView Pine strategy scripts

Section titled “Understand the two order phases of TradingView Pine strategy scripts”

TL;DR
Each order you submit is first validated (risk, pyramiding, position limits), then executed. If validation fails, TradingView silently drops the command.

DifficultyIntermediate
Time to implement15-20 min
CategoryStrategies
//@version=5
strategy("Order phase demo", overlay=true, pyramiding=1)
strategy.risk.allow_entry_in(strategy.direction.long, 1)
if ta.crossover(close, ta.sma(close, 20))
strategy.entry("Long", strategy.long)
Tip. When an order never appears, check the “List of Trades” tab. If validation failed, you won’t see a trade or error—TradingView simply skips the command.

Strategy authors are often puzzled when orders fail to fire or when positions exceed pyramiding limits. Understanding TradingView’s two-stage pipeline (generation → execution) helps you diagnose missing trades, reconcile fills, and design safer risk logic.

PhaseWhat happensReasons validation can fail
1. GenerateTradingView evaluates your order request before the bar closes.Pyramiding limit reached, risk filters (strategy.risk.*), insufficient capital, conflicting order type, disabled direction.
2. ExecuteApproved orders are filled at the calculated price, respecting slippage and fill assumptions.Market gaps, limit price never touched, partial fills based on backtest assumptions.
  1. Inspect validation rules
    Use risk settings intentionally and remember which commands they affect.

    strategy.risk.max_drawdown(5_000, strategy.cash)
    strategy.risk.allow_entry_in(strategy.direction.long, 2)
  2. Choose order functions wisely

    • strategy.entry respects pyramiding and risk filters.
    • strategy.order ignores pyramiding/allow_entry_in—use it only when you truly want raw control.
    • Exit functions run in the execution phase; they can’t be blocked by pyramiding.
  3. Log decisions
    Store diagnostics in tables, labels, or prints so you know which phase blocked the order.

    var table t = table.new(position.top_right, 1, 1)
    table.cell(t, 0, 0, "Pos size: " + str.tostring(strategy.position_size))
//@version=5
strategy("Order phase tracker", overlay=true, pyramiding=1, initial_capital=25_000)
maxEntries = input.int(1, "Max longs per day", minval=1)
strategy.risk.allow_entry_in(strategy.direction.long, maxEntries)
fast = ta.ema(close, 21)
slow = ta.ema(close, 55)
longSignal = ta.crossover(fast, slow)
shortSignal = ta.crossunder(fast, slow)
if longSignal
strategy.entry("Long", strategy.long)
if shortSignal
strategy.entry("Short", strategy.short)
var label status = na
if barstate.islast
if not na(status)
label.delete(status)
status = label.new(bar_index, close,
text="Open longs: " + str.tostring(strategy.opentrades) +
"\nPyramiding: " + str.tostring(strategy.pyramiding),
style=label.style_label_left,
textcolor=color.white,
bgcolor=color.new(color.blue, 65))
Why this works.
  • Pyramiding is set to 1, so only one long trade should exist at a time.
  • If you swap `strategy.entry` for `strategy.order`, the guard disappears—highlighting how order type influences validation.
  • Label output helps diagnose whether orders were skipped due to the guard.
  • Use strategy.opentrades to track how many entries TradingView currently holds—helpful when debugging pyramiding issues.
  • Check risk functions: strategy.risk.max_intraday_loss, max_drawdown, and allow_entry_in all run during the generation phase.
  • Embrace logging: When an order is skipped, log contextual info (e.g., pyramiding count, risk flags) to a table or output list.
  • Beware of strategy.order: It ignores pyramiding and risk guards, so use it for explicit sizing only when you take full responsibility for exposure.

My strategy still adds positions despite pyramiding = 1

Section titled “My strategy still adds positions despite pyramiding = 1”

You’re likely using strategy.order, which bypasses pyramiding. Switch to strategy.entry or enforce limits manually.

A risk guard (e.g., strategy.risk.max_drawdown) probably triggered and is now rejecting new entries. Remove or raise the guard to resume trading.

The order passed validation but never met the execution criteria. Adjust backtest_fill_limits_assumption or use strategy.order with custom logic if you require a different fill model.

  • TradingView first validates your order, then executes it. Failures in the first phase are silent.
  • Risk controls, pyramiding, and order function choice determine whether an order reaches the execution phase.
  • Build debugging aids (labels, tables, prints) to monitor order counts and validation outcomes.
  • Use strategy.entry for orders that should respect strategy guards; use strategy.order only when you consciously bypass them.

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