Pine Script Strategy Orders and Exits: Reservations and OCA | SG Group
Skip to the article
TradingView guide · Content reviewed 日本語で読む
Pine Strategy Engineering · TV17

Pine Script Strategy Orders and Exits: Limit, Stop, Brackets, Partial Exits and Pyramiding

The bar where a condition becomes true, the moment an order is created, the emulator fill, and the position close are not necessarily the same event. Multiple strategy.exit() calls also reserve position quantity in code order. This guide does not choose an optimal target or stop. It treats Pine Script v6 orders as a state machine and traces reversals, partial exits and leftovers through the List of Trades.

Who this guide is for: Pine strategy authors debugging unexpected fill bars or quantities, bracket exits, partial exits and pyramiding

Key points to understand first

ORDER STATE MACHINE

A signal is not an order, and an order is not a fill

  1. 01Condition trueCode calls an order command
  2. 02CreatedOrder receives ID, side, price and quantity
  3. 03PendingA limit or stop condition remains outstanding
  4. 04FilledPosition or realized P/L changes
  5. 05CancelledExplicit cancellation or OCA removes it
STATE PATHS
  • Market: created → next available tick → filled
  • Price order: created → pending → trigger/fill or cancel
  • Bracket: one leg fills → sibling is reduced or cancelled
On historical bars, the broker emulator simulates fills from available chart data. Order type and calculation settings alter the path.
01 · Lifecycle verdict

Read an order as a state transition, not just a function call

Order bugs often start when a source call is treated as the same event as a position update. This article traces logical states—created, pending, filled and cancelled—and quantity ownership. The separate question of why the broker emulator filled at a particular bar or price belongs to TV12, so do not mix that investigation with an exit-reservation correction.

  1. Record the condition

    Identify the bar and confirmed values that made it true.

  2. Record creation

    Capture command, ID, direction, qty, limit, stop and from_entry.

  3. Trace pending state

    Check whether a price order stayed active, changed, was reissued or cancelled.

  4. Record filled state

    Record the transition and effective quantity; hand bar-and-price causality to TV12.

  5. Reconcile the position

    Explain reversal, addition, partial exit, remaining quantity and OCA action in List of Trades.

02 · Order types

Separate market, limit, stop and stop-limit activation

Order-type audit
TypeHow it is createdWhat it waits forCommon misread
MarketNo limit or stopNext available tickAssuming a fill at the same condition-bar close
Limitlimit priceSpecified price or betterReversing favorable and unfavorable directions
Stopstop priceActivation at the stop or worseTreating stops as exit-only
Stop-limitstop and limit on entry/orderStop activation, then a limit fillAssuming the stop touch itself opens the position
Exit bracketlimit and stop on exitWhichever TP or SL leg triggers firstTreating it as one stop-limit order

Long and short favorable directions are opposite. Verify with current official examples.

Passing both stop and limit to strategy.entry() or strategy.order() creates one stop-limit order: the stop activates a later limit order. Passing both to strategy.exit() creates two exit orders, a take-profit limit and a stop-loss stop. Put this distinction directly in the code-review ledger.

03 · Command semantics

Entry, order, exit and close are not interchangeable

Responsibilities of the main commands
CommandPrimary jobPosition relationshipAudit point
strategy.entryEntry and default reversalSame-direction additions respect pyramidingA reversal transaction can include closing plus opening quantity
strategy.orderBasic directional orderChanges net position and ignores some propertiesDo not rely on pyramiding as its guard
strategy.exitPrice-based exits linked to entriesBrackets, partial and trailing exitsCheck from_entry, reservations and OCA
strategy.closeMarket close linked to an entry IDFills on an available tickReconcile FIFO/ANY and ID expectations
strategy.cancelCancel an unfilled orderDoes not close an open positionCheck whether code reissues it on every bar

Use the current TradingView documentation as the specification of record.

Pyramiding limits the number of open trades that strategy.entry() can maintain in one direction. It is not simply a one-order-per-bar safety switch. Multiple price orders can be created and triggered together, and strategy.order() ignores pyramiding. When commands are mixed, trace IDs and changes in net position explicitly.

04 · Exit reservations

Partial exits conserve quantity in call order

When several strategy.exit() calls target the same entry, each call reserves part of the open position in execution order. If a later request exceeds the unreserved remainder, its effective exit quantity is reduced. Reserving 19 first and requesting 20 second against a 20-unit position can leave only one unit for the second call.

Sequential reservation modeleffective exit 1 = min(request 1, open quantity)remaining 1 = open quantity − effective exit 1effective exit 2 = min(request 2, remaining 1)unreserved = max(open quantity − Σ effective exits, 0)This is a non-negative conceptual model. Recalculate after entries, fills, cancellations or order changes.

The TP and SL created by one strategy.exit() call form a bracket: filling one cancels its sibling. Orders from multiple exit calls belong to a strategy.oca.reduce group by default, allowing remaining quantities to shrink after another order fills. Document explicit entry-side OCA groups separately.

05 · Reservation experiment

Build two brackets that conserve the entry quantity

This educational example enters four units and allocates two units to each of two brackets. The entry condition is illustrative and makes no performance claim. Each exit call reserves two units, so requested exit quantity does not exceed the entry.

Pine Script v6: partial brackets and reservationspine
//@version=6
strategy("Two-bracket reservation audit", overlay = true, pyramiding = 1,
         initial_capital = 100000, margin_long = 100, margin_short = 100)

int fastLength = input.int(20, "Fast length", minval = 1)
int slowLength = input.int(50, "Slow length", minval = 2)
float fast = ta.sma(close, fastLength)
float slow = ta.sma(close, slowLength)
bool enterLong = ta.crossover(fast, slow) and strategy.position_size == 0

if enterLong
    strategy.entry("Long", strategy.long, qty = 4)

if strategy.position_size > 0
    float average = strategy.position_avg_price
    float stopPrice = average * 0.98
    float targetOne = average * 1.02
    float targetTwo = average * 1.04
    strategy.exit("Bracket 1", from_entry = "Long", qty = 2,
                  limit = targetOne, stop = stopPrice)
    strategy.exit("Bracket 2", from_entry = "Long", qty = 2,
                  limit = targetTwo, stop = stopPrice)

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

Each bracket creates a TP and SL and reserves two units. Gaps, slippage and intrabar paths remain simulation assumptions.

For an audit ledger, record order ID, creation bar, limit/stop prices, requested qty, effective reserved qty, fill bar and exit ID. Change the requests to three and three to see the second call shrink in the calculator before checking the strategy result.

06 · Trade forensics

Triangulate chart, Data Window and List of Trades

  1. Visualize creation

    Use labels or plots for the condition bar, limit, stop and entry ID.

  2. Inspect state variables

    Trace strategy.position_size, opentrades, closedtrades and position_avg_price.

  3. Open List of Trades

    Reconcile entry/exit IDs, timestamps, prices and quantities.

  4. Classify the surprise

    Choose creation timing, pending state, reversal, reservation, OCA or FIFO.

  5. Hand off the fill path

    If state and quantity reconcile but the bar or price still differs, continue in TV12 with the same version ID.

Symptom-to-check map
SymptomFirst checkSecond check
A later stop is too smallEarlier exit reservationsOCA reduce and unreserved remainder
Bracket requests exceed the positionCall order and requested qtyEffective qty for every call
A cancelled order returnsPer-bar reissue conditionID and strategy.cancel order
Reversal marker is largeExisting position sizeTransaction versus new position
A different entry closes firstFIFO behaviorclose_entries_rule

Change one cause at a time so the diagnosis remains reproducible.

07 · Order-state ledger

Keep one order-state row per event and version

Finish the order audit with an order-state ledger that has one row per event. Store version ID, bar index, command, order ID, from_entry, state, requested qty, effective reservation, position before/after and OCA action, and keep corrected logic as a separate version.

The ledger passes when each entry unit is accounted for once as reserved, unreserved, filled or cancelled and the total reconciles with final position size. Link bar-and-fill-price explanations to the TV12 audit by version ID instead of forcing both problems into one table.

ORDER RESERVATION LAB

Sequential exit reservation

Apply three requested exit quantities in code order and see later requests shrink to the remaining position.

Total effective reservationunit
Effective Exit 3 quantityunit
Unreserved remainderunit

Sequential model: r1=min(b,a); r2=min(c,max(a−r1,0)); r3=min(d,max(a−r1−r2,0)). Total=r1+r2+r3; unreserved=max(a−total,0). Excludes fills, cancellations and reissued orders.

Frequently asked questions

Does limit plus stop in strategy.exit() create a stop-limit order?

No. In an exit call, they create two bracket legs: a take-profit limit and a stop-loss stop. Limit plus stop in an entry or order call creates a stop-limit order.

Why does a later stop close only a small part of the position?

An earlier strategy.exit() call may have reserved most of the open quantity. The later call can use only the unreserved remainder and can be reduced automatically.

Does pyramiding=1 guarantee only one same-direction order?

Not as a universal rule. Pyramiding primarily governs open trades from strategy.entry(). strategy.order() and multiple triggered price orders require separate review.

Does strategy.cancel() close an open position?

No. strategy.cancel() cancels an unfilled order with the selected ID. Closing an open position requires strategy.close(), strategy.close_all() or a suitable exit order.

Primary sources and verification links

  1. TradingView Pine Script — StrategiesOfficial order types, commands, reservations, OCA, partial exits and pyramiding.
  2. TradingView Pine Script — Strategies FAQOfficial bracket, multi-target, trailing-stop and troubleshooting examples.
  3. TradingView Pine Script — Execution modelHistorical and realtime execution, recalculation and rollback.
  4. TradingView Help — Strategy propertiesProperties for fills, recalculation and pyramiding.

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.