Strategy
97 entries. What each one takes, what it returns, and a working example.
Account currency.
Returns the account currency — currently the constant "USD".
Note
Account currency — DERIVED FROM THE SYMBOL: quote currency for crypto pairs (BTCUSDT -> "USDT"), "TRY" for BIST stocks/indices and VIOP contracts, "USD" for forex/commodities/global indices. LABEL ONLY: no FX conversion is performed; capital and profit/loss stay unitless numbers. The value is constant ("USD"); multi-currency/FX conversion is not modeled yet.
When to use
To attach the account currency to output or a label.
Limits
For now it always returns "USD"; it does not reflect the symbol's quote currency.
The value is constant ("USD"); multi-currency/FX conversion is not modeled yet.
label(close, accountCurrency())
Attaches the currency label (USD) to price.
Real-time alert: call it inside your own if; emits the message on the current (last) bar. freq: alert.freq_once_per_bar / alert.freq_once_per_bar_close / alert.freq_all. v0.1: run-time output only.
Does not return a value; it produces an alert event when the condition turns from false to true on the last bar.
Note
v0.1: run output only; the alert center will be connected in a later phase.
alert("Buy signal", alert.freq_once_per_bar_close)
Sends a "Buy signal" alert when the condition holds; it fires once at bar close and does not repeat within the same bar.
alertcondition(condition, title?, message?)
Alert definition: fires an alert event when the condition crosses false->true on the last bar (condition-based, edge record). Separate from alert(), which is message+frequency based.
Returns nothing; registers an alert on the rising edge (false→true) of the condition.
Note
Distinct from `alert()`: `alertcondition` is condition-based and edge-triggered (the first bar the condition turns true). Takes a compile-time constant title/message.
When to use
When you want a single notification the moment a signal condition turns true.
alertcondition(crossover(close, sma(close, 50)), "Crossover", "Price crossed above SMA50")
Alerts on the bar where price crosses above SMA50.
Allowed entry direction (strategy.direction.long/short/all). A disallowed direction opens no new position and closes the opposite position instead.
Returns nothing. Prevents opening a new position in the disallowed direction.
Note
When a signal arrives in the disallowed direction, no new position opens; an open opposite position is CLOSED (not reversed). strategy.direction.all (default) applies no restriction.
Limits
Only affects opening new positions; additional pyramiding legs follow the same rule.
allowEntryIn(strategy.direction.long) enterLong(rsi(close,14) < 30) enterShort(rsi(close,14) > 70)
When the short signal arrives, the open long closes; no new short opens.
Average percent loss of closed losing trades (running, positive-abs).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(avgLosingTrade())
Plots the average percentage loss of losing trades in a separate pane; the value is given as a positive number and updates as each trade closes.
Average absolute-currency loss of closed losing trades (running, positive).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(avgLosingTradeCurrency())
Plots the average loss of losing trades in account currency; not a percentage, but the amount that left the account.
Average net % per trade (running).
Returns the average profit/loss per trade ((gross profit − gross loss) / closed trades) as a running series.
Note
Returns 0 when there are no closed trades yet (no division by zero).
When to use
To measure the strategy's per-trade expectancy.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(avgTrade(), "Avg. Trade")
Plots the average per-trade result.
Average absolute-currency P&L of closed trades (running). avgTrade returns PERCENT; this is currency.
Average absolute-currency P&L of all closed trades (running).
Note
The absolute-currency version of avgTrade (pnlPct/100 x notional). The percent name (avgTrade) is unchanged and backward-compatible.
When to use
When position-sizing/risk reporting needs absolute currency (instead of percent).
plot(avgTradeCurrency())
Plots the average profit or loss per closed trade in account currency; above zero the strategy is winning on average.
Average percent profit of closed winning trades (running).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(avgWinningTrade())
Plots the average percentage gain of winning trades; read together with the losing average it shows the win/loss balance.
Average absolute-currency profit of closed winning trades (running).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(avgWinningTradeCurrency())
Plots the average gain of winning trades in account currency.
Cancels the pending order with the given id — both an entry pending (limit/stop) and a resting/bracket exit order; the same id is cleared from both (constant id; every bar if when omitted).
Returns nothing; it cancels the pending order with the given id.
Note
The same id is cleared from both a pending entry (limit/stop) order and a pending exit order. If no such order exists, it does nothing.
When to use
To withdraw a specific pending order on a condition (for example when the signal is no longer valid).
Limits
The id must be a static string (it cannot be dynamic). It will not reverse an order that has already filled.
Not for
Not for closing an open position — cancel only withdraws a pending order that has not filled yet; use exit to close a position. It cannot undo an already-filled order either. To clear every pending order at once, cancelAll is handier than calling cancel one by one.
enterLong(barIndex==0, id='A', limit=close*0.98) cancel('A', when=barIndex==3) exit(barIndex==40)
The 'A' limit order placed on bar 0 is cancelled on bar 3 if it has not filled.
enterLong(barIndex==0, id='A', limit=close*0.97) cancel('A', when=close < lowest(low,20)) exit(barIndex==40)
If price breaks below the 20-bar low, the 'A' limit order is canceled and no trade opens.
Cancels all pending orders — entry pending plus resting/bracket exit orders are cleared together (every bar if when omitted).
Returns nothing; it cancels all pending orders.
Note
All pending entry and pending exit orders are cleared together.
When to use
To withdraw every pending order in one go when the market state changes or at the end of the day.
Limits
It does not close an open position (it only clears pending orders); use exit for the position.
Not for
It does not close an open position — it only clears pending orders; use exit for a position. If you want to target a single order, cancelAll is too broad; use cancel with an id instead. It has no effect on orders that already filled.
enterLong(barIndex==0, id='A', limit=close*0.98) enterLong(barIndex==0, id='B', stop=close*1.02) cancelAll(when=barIndex==2) exit(barIndex==40)
On bar 2 both the A and B pending orders are cancelled; if unfilled, no trade opens.
enterLong(barIndex==0, id='A', limit=close*0.98) enterShort(barIndex==0, id='B', stop=close*1.02) cancelAll(when=rsi(close,14) > 60) exit(barIndex==40)
When RSI rises above 60, both the A and B pending orders are cleared.
Cash (equity approximation). Result: 10000
Returns the same equity series as `equity()`.
Note
Alias of `equity()`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(cash(), "Cash")
Plots the equity curve.
Closes the ENTIRE open position (all legs) unconditionally on a bar where the condition is true — a market exit fills at the open of the NEXT bar after the signal. Uses the same exit path as exit() but without fromEntry/qtyPct filter — always closes all. Closes every bar if no condition is given. The condition may also be passed by name: `condition=`, `kosul=` and `koşul=` all do the same thing.
Returns nothing. On a bar where the condition is true, closes the ENTIRE open position (all legs) at market — at the open of the NEXT bar after the signal.
Note
Uses the same exit path and timing as exit() (a market exit fills at the next bar's open) but without the fromEntry/qtyPct filter — it always closes all. Closes every remaining leg in a pyramided or partially-closed position. Calling it with no open position does nothing. ⚠ IMPORTANT: the named argument must be spelled EXACTLY `kosul` (ASCII, no diacritic) — `condition=` or the accented `koşul=` are NOT recognized and raise NO error: the condition is treated as never given, which makes closeAll fire unconditionally on EVERY bar (a silent-wrong trap). Its sibling closePart uses a different spelling (the accented `koşul`) — the two are not interchangeable.
Uses the same exit path and timing as exit() (a market exit fills at the next bar's open) but without the fromEntry/qtyPct filter — it always closes all. Closes every remaining leg in a pyramided or partially-closed position. Calling it with no open position does nothing.
enterLong(crossover(close, sma(close,20))) closeAll(crossunder(close, sma(close,20))) plot(close)
Buys when price crosses above the 20-period average, closes the whole position when it crosses below.
Closes a fraction (%) of the position; full close when the ratio is omitted. The condition may also be passed by name: `condition=`, `kosul=` and `koşul=` all do the same thing. For the ratio, `qtyPct`, `oran` and `percent` are equivalent. ⚠ The abbreviations `cond` and `pct` are NOT recognized — they raise a clear error rather than silently misbehaving.
Returns nothing; on the true bar closes `oran`% of the open position (full close when omitted).
Note
`oran` applies to the currently REMAINING open quantity — successive calls reduce it cumulatively (e.g. 1.0 → 25% → 0.75 → 50% → 0.375). Same partial-close behavior as unnamed `exit(cond, qtyPct=oran)`.
Limits
`oran` must be a constant number in the range 0 (exclusive) - 100 (inclusive); out-of-range or dynamic values → clear error.
NOTE: the `oran` (ratio) parameter exists in the signature but currently has no effect — a FULL close is performed, not partial. For partial exits use `exit(condition, qtyPct=...)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) closePart(crossunder(close, sma(close, 30)))
Fully closes the position on the down-cross.
Commission of the n-th closed trade.
The closed trade's round-trip (entry+exit) commission cost — in currency.
Note
The sum of entry and exit commission (commission rate only; slippage NOT included). Leverage/margin and position size are accounted for.
Limits
Returns 0 if the commission() setting is 0. Slippage is not part of this value.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeCommission(-1), "Commission")
Returns the last closed trade's round-trip commission cost.
Entry bar index of the n-th closed trade.
Returns the entry bar index of the n-th closed trade (resolved from entry time).
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeEntryBar(-1), "Entry Bar")
Plots the last trade's entry bar index.
Entry comment of the n-th closed trade.
Entry comment of the n-th closed trade — the text given to `enterLong/enterShort(comment="…")`. Empty string if none.
Note
This field is not tracked yet; always returns an empty string (present for syntax compatibility).
Limits
Produces no real value — the empty constant. A placeholder until commission/MAE/MFE/comment/id are modeled.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) label(close, closedTradeEntryComment(-1))
Returns empty string (no comment tracking).
Entry id of the n-th closed trade.
Entry order id of the n-th closed trade — the text given to `enterLong/enterShort(id="…")`. Empty string if no id was given.
Note
This field is not tracked yet; always returns an empty string (present for syntax compatibility).
Limits
Produces no real value — the empty constant. A placeholder until commission/MAE/MFE/comment/id are modeled.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) label(close, closedTradeEntryId(-1))
Returns empty string (no id tracking).
Entry price of the n-th closed trade (neg=from the end).
Entry price of the n-th closed trade — alias of `tradeEntryPrice(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeEntryPrice(0), "Entry")
Plots the closed trade's entry price.
Entry time of the n-th closed trade.
Entry time of the n-th closed trade — alias of `tradeEntryTime(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeEntryTime(0), "Entry Time")
Plots the closed trade's entry time.
Exit bar index of the n-th closed trade.
Returns the exit bar index of the n-th closed trade (resolved from exit time).
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeExitBar(-1), "Exit Bar")
Plots the last trade's exit bar index.
The USER note written via exit(comment=...) on a closed trade (empty if none). For the automatic reason code use closedTradeExitReason().
The user note written via exit(comment=...); empty string if none.
Note
It used to return the automatic reason code (wrong data) - now it returns the real user note. For the reason code use closedTradeExitReason().
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) label(close, closedTradeExitComment(-1))
Labels the last trade's exit reason.
The id of the resting exit order that closed the trade (exit(id=..., limit/stop=...)). Empty if none.
Exit order id of the n-th closed trade — the text given to `exit(id="…")`. ⚠ `id` is only meaningful for PENDING exits (limit/stop); an immediate condition-based close returns an empty string.
Note
This field is not tracked yet; always returns an empty string (present for syntax compatibility).
Limits
Produces no real value — the empty constant. A placeholder until commission/MAE/MFE/comment/id are modeled.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) label(close, closedTradeExitId(-1))
Returns empty string.
Exit price of the n-th closed trade.
Exit price of the n-th closed trade — alias of `tradeExitPrice(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeExitPrice(0), "Exit")
Plots the closed trade's exit price.
The automatic exit reason code of a closed trade: signal | stop | target | trail | partial1 | partial2 | eod | liq | manual | risk | exit. For the user note use closedTradeExitComment().
The automatic exit reason code (signal/stop/target/trail/partial1/partial2/eod/liq/manual/risk/exit).
Note
This value used to be returned by closedTradeExitComment() by mistake; they are now separate: comment = user note, reason = automatic reason code.
When to use
To branch on WHY the exit happened (stop vs target vs trailing).
plot(strLength(closedTradeExitReason(0)))
Takes the exit reason of the last closed trade and plots the length of that text; the reason is a string and cannot be plotted directly, so this example turns it into a number.
Exit time of the n-th closed trade.
Exit time of the n-th closed trade — alias of `tradeExitTime(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeExitTime(0), "Exit Time")
Plots the closed trade's exit time.
Max drawdown of the n-th trade.
The worst drawdown (MAE) the closed trade suffered during its life — in currency.
Note
Pure price movement: commission and carry EXCLUDED — 'how far price went against you', not the account-balance swing. Uses the lowest low for longs, the highest high for shorts; entry and exit bars are included.
Limits
Leverage and margin are included on the same scale as P&L. The measure is pure price movement; commission and carry are excluded. It may not match other platforms exactly.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeMaxDrawdown(-1), "MAE")
Returns the last closed trade's worst drawdown in currency.
closedTradeMaxDrawdownPercent(n?)
Max drawdown % of the n-th trade.
The closed trade's worst drawdown (MAE) — percent.
Note
Pure price movement: commission/carry EXCLUDED. Lowest low for longs, highest high for shorts; entry and exit bars included. The percent is on the same scale as P&L percent (leverage included).
Limits
The measure is pure price movement; commission and carry are excluded. It may not match other platforms exactly.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeMaxDrawdownPercent(-1), "MAE %")
Returns the last closed trade's worst drawdown percent.
Max run-up of the n-th trade.
The best run-up (MFE) the closed trade reached during its life — in currency.
Note
Pure price movement: commission and carry EXCLUDED — 'how far price went in your favor'. Uses the highest high for longs, the lowest low for shorts; entry and exit bars are included.
Limits
Leverage and margin are included on the same scale as P&L. The measure is pure price movement; commission and carry are excluded. It may not match other platforms exactly.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeMaxRunup(-1), "MFE")
Returns the last closed trade's best run-up in currency.
closedTradeMaxRunupPercent(n?)
Max run-up % of the n-th trade.
The closed trade's best run-up (MFE) — percent.
Note
Pure price movement: commission/carry EXCLUDED. Highest high for longs, lowest low for shorts; entry and exit bars included. The percent is on the same scale as P&L percent (leverage included).
Limits
The measure is pure price movement; commission and carry are excluded. It may not match other platforms exactly.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeMaxRunupPercent(-1), "MFE %")
Returns the last closed trade's best run-up percent.
Profit of the n-th closed trade (estimated, in account currency).
Returns the n-th closed trade's profit/loss in CURRENCY (pnl% × initial capital / 100).
Note
In currency units. For percent use `closedTradeProfitPercent(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeProfit(-1), "Last Trade P&L")
Plots the last closed trade's currency P/L.
Profit percent of the n-th closed trade.
Returns the n-th closed trade's profit/loss as a PERCENT (pnl%).
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeProfitPercent(-1), "Last Trade %")
Plots the last closed trade's percent P/L.
Size of the n-th closed trade.
Direction/size of the n-th closed trade — alias of `tradeSize(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradeSize(0), "Direction")
Plots the closed trade's direction.
Number of closed trades (running).
Returns the total number of closed trades so far, as a running series.
When to use
To track trade frequency and the denominator of win rate.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTrades(), "Closed Trade")
Plots cumulative closed-trade count.
Number of closed trades.
Returns the total closed-trade count — identical to `tradeCount()`.
Note
Alias of `tradeCount()`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(closedTradesCount(), "Closed")
Plots the closed-trade count.
First index of the closed trade list. Trade history is never trimmed here (no cap), so it always returns 0. Provided so that `for i = closedTradesFirstIndex() to...` loops ported from referans dil keep working.
First index of the closed trade list. Trade history is never trimmed here (no cap), so it always returns 0. Provided so that `for i = closedTradesFirstIndex() to ...` loops keep working even if trimming is introduced later.
plot(closedTradesFirstIndex())
Plots the first index of the closed-trade list; the number grows as the list is trimmed, showing that the oldest trades have dropped off.
Converts to account currency (unchanged if no FX).
Returns the value UNCHANGED (identity). Since the account and symbol currency are assumed equal, no FX conversion is applied.
Note
Exists for syntax compatibility; real FX conversion is not modeled (accountCurrency is the constant "USD").
When to use
For syntax compatibility when porting code that convert a value to the account currency.
Limits
Passes the value through as-is; since multi-currency is not modeled, no rate factor is applied.
plot(convertToAccount(close), "Value")
Plots the value unchanged.
Converts to symbol currency (unchanged if no FX).
Returns the value UNCHANGED (identity). No FX conversion is applied.
Note
Same as `convertToAccount` — passthrough placeholder; no FX model.
plot(convertToSymbol(close), "Value")
Plots the value unchanged.
Enter a fixed quantity (contracts/shares) per trade. Switches sizing from %equity to quantity-based; P&L = quantity × price change. Default %equity is kept if never called.
Returns nothing. When called, sizing switches from the default %equity to a fixed quantity; P&L = quantity × price change.
Note
If never called, the default %equity sizing is kept (existing strategies are unaffected). In quantity mode leverage does not enter P&L; it only sets required margin and the liquidation threshold. If margin is insufficient the trade is skipped (quantity is not trimmed).
Limits
Multiple entries (pyramiding) in fixed/cash mode are not supported in this version; multi-entry with leverage is also disabled.
defaultEntryQty(2) enterLong(crossover(close, sma(close, 20))) exit(crossunder(close, sma(close, 20))) plot(close)
Takes a fixed 2 units per trade; P&L is computed as 2 × price change.
Running maximum drawdown (%).
Returns the drawdown from the running equity peak (max drawdown) as a percentage.
When to use
To measure the strategy's risk profile and worst under-water period.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(drawdownPct(), "Pullback %")
Plots the running drawdown percentage.
enterLong(condition, stopLoss?, takeProfit?, trailingStop?, id?, limit?, stop?, ocaGroup?, qty?, comment?, stopLossTicks?, takeProfitTicks?, trailTicks?, trailOffsetTicks?, trailFar?, trailNear?, trailThresh1?, trailThresh2?, stopLossAtr?, partial1Pct?, partial1Size?, partial2Pct?, partial2Size?)
Open LONG when condition is true. With limit or stop, arm a pending order (not both); otherwise a market order fills at the open of the NEXT bar after the signal (an order can't fill before its own bar closes — realistic timing). A constant-string id names the entry; id + limit/stop → pending-order list (same id replaces, different ids coexist; cancel(id)/cancelAll clears). A constant-string ocaGroup auto-cancels the other pending entries in the same group once one fills (competing setup: arm both a breakout and a pullback order — whichever fills first cancels the rest). pyramiding(n) adds up to n entry parts in the same direction. Risk parameters (%): stopLoss / takeProfit / trailingStop. Pending limit/stop orders fill within-bar (high/low) when price reaches the level. If qty is given the order is an ABSOLUTE contract count (bypasses global sizing; still clipped by maxPositionSize). comment is a plain-text note (read back via entryComment()). qty and comment are given by name only. Tick-relative risk: stopLossTicks/takeProfitTicks are N x tickSize ABSOLUTE price distances (combined with percent/ATR: tightest stop, nearest target). trailTicks is the trailing ACTIVATION threshold (0 = immediate), trailOffsetTicks the FOLLOW distance; once activated it stays active. tickSize is resolved from the symbol; if unresolved these params are skipped with a warning. trailOffsetTicks is REQUIRED alongside trailTicks (trailTicks alone does not create a trailing stop; if missing a warning is emitted and it is skipped). All of the following are given by name only (they cannot be given in order): staged trailing stop trailFar/trailNear/trailThresh1/trailThresh2 — until profit% reaches trailThresh1 (default 2) only the fixed stopLoss/stopLossAtr applies; between trailThresh1 and trailThresh2 (default 5) it trails at trailFar%; above trailThresh2 it trails TIGHTER at trailNear% (defaults to trailFar) — each stage is PERMANENT, it does not revert. stopLossAtr: N x ATR(14), fixed at the ENTRY bar (unchanged for the life of the trade); combined with stopLoss/stopLossTicks, the TIGHTEST applies. Partial profit-taking: partial1Pct/partial1Size and partial2Pct/partial2Size — once profit% reaches the Pct threshold, Size (0-1, e.g. 0.5 = 50%) of the currently OPEN quantity closes ONCE; the two thresholds are checked INDEPENDENTLY (both can fire on the same bar).
Returns nothing; it reports an entry order to the strategy test.
Note
Risk values are percentages (stopLoss=2 means 2%). A market order (no limit/stop) fills at the open of the NEXT bar after the signal — an order can't fill before its own bar closes (realistic timing). If limit or stop is given, a pending order is set up instead (the two are not used together); pending orders fill within the bar when price reaches the level. id + limit/stop gives a pending order list: the same id updates it, different ids wait together. When one of the pending entries sharing an ocaGroup fills, the other entries in the group are auto-cancelled (competing setup: arm a breakout and a pullback order together — the first fill cancels the other). With pyramiding(n), up to n entry legs can be added in the same direction. The rule is passed straight in as a condition; there is no separate order function. Pending orders and scaled entries are all handled by the same call.
When to use
Market entry (no limit/stop — the order fills at the next bar's open after the signal); limit for buying at a set price (dip buying) or stop for a breakout. Combine id + pyramiding to add multiple entry parts.
Limits
The id cannot be dynamic (a static string is required). limit and stop cannot be given together in one call. Once the pyramiding cap is reached no new entry part is added and the order waits.
Not for
Not for merely placing a mark on the chart — use plotshape for that; enterLong opens a real trade and affects the backtest result. Do not use it to protect or close an already-open long entry part either; exits and protection are handled by exit. For a short entry, switch to enterShort.
Tip
The rule is passed straight in as a condition; there is no separate order function. Pending orders and scaled entries are all handled by the same call.
Risk values are percentages (stopLoss=2 means 2%). A market order (no limit/stop) fills at the open of the NEXT bar after the signal — an order can't fill before its own bar closes (realistic timing). If limit or stop is given, a pending order is set up instead (the two are not used together); pending orders fill within the bar when price reaches the level. id + limit/stop gives a pending order list: the same id updates it, different ids wait together. When one of the pending entries sharing an ocaGroup fills, its siblings are auto-cancelled (competing setup: arm a breakout and a pullback order together — the first fill drops the other). With pyramiding(n), up to n entry legs can be added in the same direction.
The rule is passed straight in as a condition; there is no separate order function. Pending orders and scaled entries are all handled by the same call.
enterLong(crossover(close, sma(close,20))) exit(crossunder(close, sma(close,20)))
BUY when price crosses above SMA20, close when it crosses below.
enterLong(barIndex==0, limit=sma(close,20)*0.98) exit(barIndex==40)
A pending limit 2% below SMA20; fills when price drops to that level.
enterShort(condition, stopLoss?, takeProfit?, trailingStop?, id?, limit?, stop?, ocaGroup?, qty?, comment?, stopLossTicks?, takeProfitTicks?, trailTicks?, trailOffsetTicks?, trailFar?, trailNear?, trailThresh1?, trailThresh2?, stopLossAtr?, partial1Pct?, partial1Size?, partial2Pct?, partial2Size?)
Open SHORT when condition is true. With limit or stop, arm a pending order (not both); otherwise a market order fills at the open of the NEXT bar after the signal (an order can't fill before its own bar closes — realistic timing). A constant-string id names the entry; id + limit/stop → pending-order list (same id replaces, different ids coexist; cancel(id)/cancelAll clears). A constant-string ocaGroup auto-cancels the other pending entries in the same group once one fills (competing setup: arm both a breakout and a pullback order — whichever fills first cancels the rest). pyramiding(n) adds up to n entry parts in the same direction. Risk parameters (%): stopLoss / takeProfit / trailingStop. If qty is given the order is an ABSOLUTE contract count (bypasses global sizing; still clipped by maxPositionSize). comment is a plain-text note (read back via entryComment()). qty and comment are given by name only. Tick-relative risk: stopLossTicks/takeProfitTicks are N x tickSize ABSOLUTE price distances (combined with percent/ATR: tightest stop, nearest target). trailTicks is the trailing ACTIVATION threshold (0 = immediate), trailOffsetTicks the FOLLOW distance; once activated it stays active. tickSize is resolved from the symbol; if unresolved these params are skipped with a warning. trailOffsetTicks is REQUIRED alongside trailTicks (trailTicks alone does not create a trailing stop; if missing a warning is emitted and it is skipped). All of the following are given by name only (they cannot be given in order): staged trailing stop trailFar/trailNear/trailThresh1/trailThresh2 — until profit% reaches trailThresh1 (default 2) only the fixed stopLoss/stopLossAtr applies; between trailThresh1 and trailThresh2 (default 5) it trails at trailFar%; above trailThresh2 it trails TIGHTER at trailNear% (defaults to trailFar) — each stage is PERMANENT, it does not revert. stopLossAtr: N x ATR(14), fixed at the ENTRY bar (unchanged for the life of the trade); combined with stopLoss/stopLossTicks, the TIGHTEST applies. Partial profit-taking: partial1Pct/partial1Size and partial2Pct/partial2Size — once profit% reaches the Pct threshold, Size (0-1, e.g. 0.5 = 50%) of the currently OPEN quantity closes ONCE; the two thresholds are checked INDEPENDENTLY (both can fire on the same bar). For a short, profit direction is REVERSED (price falling increases profit) — trail/partial thresholds are computed accordingly.
Returns nothing; it reports a short entry order to the strategy test.
Note
The short counterpart of enterLong; the same id/limit/stop/pyramiding/ocaGroup rules and fill timing apply (a market order fills at the next bar's open after the signal), and risk values are percentages.
When to use
Same logic as enterLong; the only difference is the short (downward) direction. Market entry fills at the next bar's open, limit/stop for a set price, id + pyramiding to add entry parts.
Limits
Shorting is not allowed in SPOT mode. The id cannot be dynamic; limit and stop cannot be combined. Once the pyramiding cap is full, a new entry part stays pending.
Not for
Not usable in SPOT mode, which does not allow shorting; use it only in a futures or short-enabled mode. It is not for placing a chart mark (plotshape) nor for closing an open entry part (exit). If you expect a rise, switch to enterLong.
enterShort(crossunder(close, sma(close,20))) exit(crossover(close, sma(close,20)))
SELL when price crosses below SMA20, close when it crosses above.
enterShort(barIndex==0, id='S', stop=sma(close,20)*1.02) exit(barIndex==40)
A pending stop 2% above SMA20; the short fills when price rises to that level.
The comment of the active position's entry order (plain-text; separate from id). Empty string when flat.
The comment string of the active position's entry order; empty string when flat.
Note
Reads the plain-text note set via enterLong/Short(comment=...). Separate from id (no tracking/cancel). With pyramiding, the last-added leg's comment is active.
When to use
To distinguish entry reasons (e.g. "trend"/"reversal") within one strategy and branch exit/reporting logic on them.
plot(entryComment()=="trend" ? 1 : 0)
Plots 1 when the open position's entry note is "trend" and 0 otherwise; it helps tell different entry reasons apart on the same chart.
entryMarket(condition, direction?)
Market entry (direction: long/short).
Returns nothing; routes a market order on the true bar. A thin wrapper over enterLong/enterShort.
Note
`order` is an alias for this (identical behavior). The direction argument picks long/short in one call; for stop/take-profit risk arguments use enterLong/enterShort.
When to use
When you want to route an entry in one line with the direction chosen by a variable.
direction = close > open ? "long" : "short" entryMarket(crossover(close, sma(close, 20)), direction)
On the crossover bar, a long or short market order depending on the candle direction.
Current account equity (backtest).
Returns the backtest equity series (post-risk, pre-order, valued at bar close).
Note
If initial capital is unset, 10000 is assumed. `cash()` is an alias of this.
When to use
To plot strategy performance or for equity-based position sizing.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(equity(), "Equity")
Plots the equity curve on a sub-panel.
exit(condition, fromEntry?, qtyPct?, id?, limit?, stop?, comment?, commentProfit?, commentLoss?, profit?, loss?)
Close the open position when condition is true — a market exit fills at the open of the NEXT bar after the signal (realistic timing, like entries). fromEntry targets a specific entry part; qtyPct closes a percent of the remaining. With limit and/or stop, arm an id'd resting exit order that fills within-bar when price reaches the level (id required). limit+stop together = bracket (take-profit + stop-loss): filling one cancels the other (OCO). comment: a plain-text note on the exit - read back with closedTradeExitComment(); its own automatic reason code (signal/stop/target/trail/eod...) is read separately with closedTradeExitReason(). commentProfit/commentLoss: writes the note matching whichever level filled — limit or stop (falls back to comment). profit/loss: give the protection level in TICKS instead of price — profit×tick above the entry is the take-profit, loss×tick below it is the stop-loss (mirrored for shorts). It is written into the entry's risk settings, i.e. the SAME mechanism as stopLossTicks/takeProfitTicks. Valid on an unconditional call; on a conditional one it is not installed and a warning is raised.
Returns nothing; it triggers a market exit (at the next bar's open) or sets up an id-tagged resting exit order.
Note
If limit/stop is not given, a market exit occurs: it fills at the open of the NEXT bar after the signal (realistic timing, like entries). Only limit or only stop gives an identified pending exit (fills within the bar when price reaches the level). limit and stop together give a bracket (take-profit + stop-loss pair): when one fills, the other is automatically canceled (OCO). qtyPct closes partially; the bracket is one-shot (once filled it is removed, and the remaining entry part is left unprotected).
When to use
Use a plain exit(condition) for a rule-based market exit — it fills at the next bar's open after the signal. Use a resting limit/stop for a set target or loss level. Use a bracket (limit+stop) to manage a take-profit and stop-loss pair in one order.
Limits
id and fromEntry cannot be dynamic. In a bracket, if both the target and the loss level are touched on the same bar, the one reached first fills; if they tie exactly, the stop-loss takes priority. A position-level risk stop (stopLoss/takeProfit) is evaluated first on the bar; if it closes the position, the resting exit orders do not fill that bar.
Not for
Not for opening a position — entries come from enterLong/enterShort; exit only closes an open entry part or attaches protection to it. Calling exit when there is no open position does nothing. To pull back a pending entry order, use cancel/cancelAll, not exit.
Tip
A single call handles both a market exit and a resting take-profit / stop-loss; when limit and stop are given together, filling one cancels the other.
A single call handles both a market exit and a resting take-profit / stop-loss; when limit and stop are given together, filling one cancels the other.
enterLong(crossover(close, sma(close,10))) exit(crossunder(close, sma(close,10)))
Rule-based immediate exit: close when SMA10 is crossed downward.
enterLong(barIndex==0, id='L') exit(barIndex==5, fromEntry='L', qtyPct=50) exit(barIndex==40)
On bar 5 only 50% of the L entry part is closed; the remainder on bar 40.
Total % loss of closed losing trades (running).
Returns the total loss of losing closed trades (gross loss, positive magnitude) as a running series.
When to use
As the denominator in profit factor and risk ratios.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(grossLoss(), "Gross Loss")
Plots cumulative gross loss.
Total absolute-currency loss of closed losing trades (running, positive). grossLoss returns PERCENT; this is currency.
Total absolute-currency loss of closed losing trades (running, positive).
Note
The absolute-currency version of grossLoss (pnlPct/100 x notional). The percent name (grossLoss) is unchanged and backward-compatible.
When to use
When position-sizing/risk reporting needs absolute currency (instead of percent).
plot(grossLossCurrency())
Plots the total loss of all losing trades in account currency, given as a positive number.
Total % profit of closed winning trades (running).
Returns the total profit of winning closed trades (gross profit) as a running series.
When to use
To compute performance ratios such as profit factor (grossProfit/grossLoss).
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(grossProfit(), "Gross Profit")
Plots cumulative gross profit.
Total absolute-currency profit of closed winning trades (running). grossProfit returns PERCENT; this is currency.
Total absolute-currency profit of closed winning trades so far (running).
Note
The absolute-currency version of grossProfit (pnlPct/100 x notional). The percent name (grossProfit) is unchanged and backward-compatible.
When to use
When position-sizing/risk reporting needs absolute currency (instead of percent).
plot(grossProfitCurrency())
Plots the total gain of all winning trades in account currency.
Largest single-trade percent loss (running, positive-abs).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(largestLosingTrade())
Plots the largest percentage loss taken on a single trade — the strategy's worst moment.
Largest single-trade absolute-currency loss (running, positive).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(largestLosingTradeCurrency())
Plots the largest loss taken on a single trade, in account currency.
Largest single-trade percent profit (running).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(largestWinningTrade())
Plots the largest percentage gain made on a single trade.
Largest single-trade absolute-currency profit (running).
Note
Percent-primary; *Currency suffix gives absolute currency (pnlPct/100 x notional). Losing metrics are positive-abs, consistent with grossLoss.
When to use
When reporting trade-quality/risk (avg win-loss, single largest trade).
plot(largestWinningTradeCurrency())
Plots the largest gain made on a single trade, in account currency.
Number of losing trades (running).
Returns the count of trades closed at a loss so far, as a running series.
When to use
In loss-rate and expectancy calculations.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(lossTrades(), "Losing")
Plots cumulative losing-trade count.
Margin liquidation price for a leveraged position: long -> entry x (1 - 1/leverage), short -> entry x (1 + 1/leverage). Empty when unleveraged (1x) or flat.
Note
Derived from the recorded per-bar position size (running max) / same formula used for liquidation.
When to use
When reporting leverage/margin risk and peak position size.
plot(marginLiquidationPrice())
Draws the liquidation price of a leveraged position over price; if price reaches this line the position is force-closed.
After n consecutive losing days, positions are force-closed and new orders permanently blocked.
Returns nothing. After n consecutive losing days, the open position closes and the strategy halts permanently.
Note
A day counts as losing if its closing equity is lower than its starting equity. Once the limit is breached, the effect is permanent — the strategy will not open another position for the rest of that run.
Limits
Only affects backtest/paper simulation; live broker order execution is not part of this version.
maxConsecLossDays(2) enterLong(true)
After 2 consecutive losing days, the position closes and the strategy stops entering again.
Highest number of contracts held so far (either direction, absolute).
Note
Derived from the recorded per-bar position size (running max) / same formula used for liquidation.
When to use
When reporting leverage/margin risk and peak position size.
plot(maxContractsHeldAll())
Plots the largest position ever held at one time, without separating longs from shorts.
Highest number of LONG contracts held so far.
Note
Derived from the recorded per-bar position size (running max) / same formula used for liquidation.
When to use
When reporting leverage/margin risk and peak position size.
plot(maxContractsHeldLong())
Plots the largest long position ever held.
Highest number of SHORT contracts held so far.
Note
Derived from the recorded per-bar position size (running max) / same formula used for liquidation.
When to use
When reporting leverage/margin risk and peak position size.
plot(maxContractsHeldShort())
Plots the largest short position ever held.
Maximum drawdown limit; when exceeded, positions are force-closed and new orders permanently blocked. type: strategy.percent_of_equity | strategy.cash.
Returns nothing. When the drawdown exceeds this limit, the open position closes and the strategy halts permanently.
Note
Once the limit is breached, the effect is permanent — the strategy will not open another position for the rest of that run. The drawdown is measured from the strategy's own PEAK equity, not from the entry price — it can trigger even while the position is still profitable relative to entry, if equity has pulled back this much from its own high.
Limits
Only affects backtest/paper simulation; live broker order execution is not part of this version.
maxDrawdownRisk(10, strategy.percent_of_equity) enterLong(true)
Even if the position is still profitable relative to entry, when equity falls 10% from its own peak the position closes and the strategy stops entering again.
After n filled orders in a day, positions are force-closed and new orders blocked until session end.
Returns nothing. After n orders fill within the day, the open position closes and no new entry is allowed for the rest of that day.
Note
Intended to limit excessive trading frequency. The limit resets at the next UTC day boundary.
Limits
Only affects backtest/paper simulation; live broker order execution is not part of this version.
maxIntradayFilledOrders(3) enterLong(barIndex % 2 == 0) enterShort(barIndex % 2 == 1)
When the 3rd order fills that day, the position closes; no new entry opens for the rest of that day.
Maximum intraday loss; when exceeded, that day's positions are force-closed and new orders blocked (resets next day). type: percent_of_equity | cash.
Returns nothing. When the intraday loss exceeds this limit, the open position closes and no new entry is allowed for the rest of that day.
Note
The restriction applies only for that day; it resets at the next UTC day boundary and the strategy resumes normal operation.
Limits
Only affects backtest/paper simulation; live broker order execution is not part of this version.
maxIntradayLoss(5, strategy.percent_of_equity) enterLong(true)
When 5% of equity is lost within the day, the position closes; the limit resets the next day.
Upper cap on position size (contracts/shares) in fixed/cash sizing mode (defaultEntryQty/sizeByCash); an order exceeding it is reduced to the cap. No effect in %equity mode.
Returns nothing. In fixed/cash mode (defaultEntryQty or sizeByCash) it caps the maximum reachable size; an order exceeding it is reduced to the cap.
Note
Meaningful only alongside quantity-based sizing (defaultEntryQty/sizeByCash). In the default %equity mode there is no contract notion, so it has no effect and emits a warning when called.
Limits
No effect in %equity mode (emits a warning). For a contract cap, first switch to quantity-based mode via defaultEntryQty or sizeByCash.
defaultEntryQty(5) maxPositionSize(2) enterLong(crossover(close, sma(close, 20))) exit(crossunder(close, sma(close, 20))) plot(close)
Although 5 units are requested, the position opens up to at most 2 units (reduced to the cap).
Gives the net profit or loss against the starting capital, bar by bar. Above zero is profit, below is loss. Read it to draw a strategy's curve or to change behaviour after a certain drawdown.
Returns the net profit/loss series: equity − initial capital.
When to use
To track the strategy's cumulative gain relative to the start.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(netPnl(), "Net P&L")
Plots cumulative net profit/loss.
Capital the open position locks up in the account: notional / leverage. Equals the notional without leverage; one tenth of it at 10x. The notional base matches openTradeProfit. Empty value when flat.
plot(openTradeCapitalHeld())
Plots the money the open position locks up in the account; the higher the leverage, the smaller the amount locked for the same position.
Commission of the open trade.
The commission the open trade has paid so far (entry only) — in currency. na if no position is open.
Note
Entry commission only (the exit has not happened yet); the sum across all open legs, on remaining size. Slippage excluded.
enterLong(crossover(close, sma(close, 10))) plot(openTradeCommission(), "Open commission")
Returns the entry commission the open position has paid so far (na if flat).
Entry bar index of the open trade.
Returns the open position's entry bar index; na if flat.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradeEntryBar(), "Open Entry Bar")
Plots the open position's entry bar index.
Entry comment of the open trade.
Entry comment of the open trade — the text given to `enterLong/enterShort(comment="…")`. Empty string if none.
Note
No comment tracking; empty string.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) label(close, openTradeEntryComment())
Returns empty string.
Entry id of the open trade.
Entry order id of the open trade — the text given to `enterLong/enterShort(id="…")`. Empty string if no id was given.
Note
No id tracking; empty string.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) label(close, openTradeEntryId())
Returns empty string.
Entry price of the open trade.
Returns the open position's entry price; na if flat.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradeEntryPrice(), "Open Entry")
Plots the open position's entry price.
Entry time of the open trade.
Returns the open position's entry time (epoch ms); na if flat.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradeEntryTime(), "Open Entry Time")
Plots the open position's entry time.
Max drawdown of the open trade.
The open trade's worst drawdown so far (MAE) — in currency. na if no position is open.
Note
Pure price movement: commission/carry EXCLUDED. A running 'worst so far' value over the open position; the current bar's low/high is included. Leverage/margin included. May not match other platforms exactly; the difference comes from this choice of measure.
enterLong(crossover(close, sma(close, 10))) plot(openTradeMaxDrawdown(), "Open MAE")
Returns the open position's worst drawdown so far, in currency (na if flat).
Max drawdown of the open trade (%).
The open trade's worst drawdown so far (MAE) — percent. na if no position is open.
Note
Pure price movement: commission/carry EXCLUDED. A running 'worst' percent over the open position; the current bar's low/high is included. Leverage included (same scale as P&L percent). May not match other platforms exactly; the difference comes from this choice of measure.
enterLong(crossover(close, sma(close, 10))) plot(openTradeMaxDrawdownPercent(), "Open MAE %")
Returns the open position's worst drawdown percent so far (na if flat).
Max run-up of the open trade.
The open trade's best run-up so far (MFE) — in currency. na if no position is open.
Note
Pure price movement: commission/carry EXCLUDED. A running 'best so far' value over the open position; the current bar's high/low is included. Leverage/margin included. May not match other platforms exactly; the difference comes from this choice of measure.
enterLong(crossover(close, sma(close, 10))) plot(openTradeMaxRunup(), "Open MFE")
Returns the open position's best run-up so far, in currency (na if flat).
Max run-up of the open trade (%).
The open trade's best run-up so far (MFE) — percent. na if no position is open.
Note
Pure price movement: commission/carry EXCLUDED. A running 'best' percent over the open position; the current bar's high/low is included. Leverage included (same scale as P&L percent). May not match other platforms exactly; the difference comes from this choice of measure.
enterLong(crossover(close, sma(close, 10))) plot(openTradeMaxRunupPercent(), "Open MFE %")
Returns the open position's best run-up percent so far (na if flat).
Unrealized profit of the open trade (estimated).
Returns the open position's unrealized profit/loss in CURRENCY (unrealized% × initial / 100); na if flat.
Note
For percent use `openTradeProfitPercent()`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradeProfit(), "Open P&L")
Plots the open position's currency unrealized P/L.
Unrealized profit % of the open trade.
Returns the open position's unrealized profit/loss as a PERCENT; na if flat.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradeProfitPercent(), "Open %")
Plots the open position's percent unrealized P/L.
Direction/size of the open trade.
Returns the open position's direction: +1 long, −1 short, 0 flat.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradeSize(), "Open Direction")
Plots the open position's direction.
Number of open trades (0/1).
Returns the open-trade count: 1 if a position is open, 0 if flat.
Note
At most one open trade is modeled (not broken out by pyramiding levels).
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(openTradesCount(), "Open Trade")
Plots whether a position is open (1/0).
First index of the open trade list. Trade history is never trimmed here (no cap), so it always returns 0. Provided so that `for i = openTradesFirstIndex() to...` loops ported from referans dil keep working.
First index of the open trade list. Trade history is never trimmed here (no cap), so it always returns 0. Provided so that `for i = openTradesFirstIndex() to ...` loops keep working even if trimming is introduced later.
plot(openTradesFirstIndex())
Plots the first index of the open-trade list.
Generic order (direction: long/short).
Returns nothing; identical to `entryMarket` — routes a market order on the true bar.
Note
Alias of `entryMarket`. Both call the same core (enterLong/enterShort).
order(crossover(close, sma(close, 20)))
A long market order on the crossover bar.
Gives the position direction on that bar: +1 when long, -1 when short, 0 when flat. Used to colour an indicator by position or to compute only while a position is open. It reports direction, not size.
Position direction per bar: +1 long, -1 short, 0 flat.
Note
Gives only the DIRECTION (not the size). For size/entry portions, use positionSize.
When to use
For coloring or filtering by position direction (for example, tint the candle green while long).
Limits
Only +1/-1/0; it does not show how many entry parts are open.
Not for
Not for learning how many entry parts are open or the size — it gives only the direction (+1/-1/0); use positionSize for size. You do not open or close positions with it; use enterLong/enterShort/exit. To draw a mark independent of direction, plotshape fits better.
enterLong(crossover(close,sma(close,20))) exit(crossunder(close,sma(close,20))) barcolor(iff(position() > 0, "#26a69a", na))
Candles are green on bars where a long is held; flat bars are not colored.
enterLong(crossover(close,sma(close,20))) plot(position(), "direction", "#ff9800")
A stepped direction line ranging between 0 and +1 in the lower pane.
Average entry price of the open position.
Returns the average entry price of the open position; na when flat.
Note
Returns na when flat — guard with `position() != 0` before use.
When to use
To compute stop/target levels relative to the open position.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(positionAvg(), "Entry Price")
Plots the open position's entry price.
Position size/direction (+/-).
Direction × the summed remaining size of the open entry parts (may be fractional).
Note
While position() gives only direction, positionSize reflects the number of open entry portions and partial closes: 3 entry portions → +3, +2.5 after a 50% close.
When to use
To track the effect of pyramiding or partial exits (how many units remain open).
Limits
Not an absolute lot or contract count; it is a entry part-ratio-based size.
Not for
Not where you expect a real lot or contract count — it returns a entry part-ratio-based size, not an exchange order quantity. If you only need direction (long/short/flat), position() is simpler. You do not open or close positions with this function; use enterLong/enterShort/exit for that.
pyramiding(3) enterLong(rsi(close,14)<40, id='L') exit(rsi(close,14)>60) plot(positionSize(), "size", "#2962ff")
Steps in the lower pane: +1→+2→+3, 0 on exit.
enterLong(barIndex==0, id='L') exit(barIndex==10, fromEntry='L', qtyPct=50) plot(positionSize(), "remaining", "#2962ff") exit(barIndex==40)
50% partial exit on bar 10 → size drops from +1 to +0.5.
Running maximum run-up (%).
Returns the run-up from the running equity trough as a percentage.
When to use
To measure the strategy's favorable-excursion potential.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(runupPct(), "Gain %")
Plots the running run-up percentage.
scan(condition, title?, score?, note?)
Record a scan row when the condition is true on the last bar. v0.1: run-time output only; scanner/persistence is not wired yet.
Does not return a value; if the condition is met on the last bar, it produces a scan row.
Note
v0.1: run output only; the scanner/persistent record will be connected in a later phase.
scan(close > sma(close, 20), title="Above MA", score=roc(close, 1))
Adds the symbol to the scan results when price closes above its 20-bar average on the last bar; the row appears titled "Above MA" and is ranked by the last bar's percentage change.
Bar duration of the nth trade.
Returns how many bars the n-th closed trade lasted.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeBars(0), "Bar Duration")
Plots the first trade's bar duration.
Number of closed trades (scalar).
Returns the total number of closed trades (scalar).
Note
`closedTradesCount()` is an alias. Not a series — the running total count.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeCount(), "Trade Count")
Plots the number of trades closed so far.
Entry price of the nth trade (0-based; -1=last).
Returns the entry price of the n-th closed trade.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeEntryPrice(0), "First Entry")
Plots the first closed trade's entry price.
Entry time of the nth trade (epoch).
Returns the entry time (epoch ms) of the n-th closed trade.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeEntryTime(0), "Entry Time")
Plots the first trade's entry time.
Exit price of the nth trade.
Returns the exit price of the n-th closed trade.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeExitPrice(0), "First Exit")
Plots the first closed trade's exit price.
Exit time of the nth trade (epoch).
Returns the exit time (epoch ms) of the n-th closed trade.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeExitTime(0), "Exit Time")
Plots the first trade's exit time.
Net % profit/loss of the nth trade.
Returns the n-th closed trade's profit/loss as a PERCENT (pnl%).
Note
The unit is PERCENT (not currency). For currency use `closedTradeProfit(n)`.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeProfit(0), "First P&L %")
Plots the first trade's percent P/L.
Size ratio of the nth trade.
Returns the direction/size of the n-th closed trade.
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(tradeSize(0), "Direction")
Plots the first trade's direction.
Number of winning trades (running).
Returns the count of trades closed at a profit so far, as a running series.
When to use
To compute win rate (winTrades/closedTrades).
enterLong(crossover(close, sma(close, 10))) exit(crossunder(close, sma(close, 10))) plot(winTrades(), "Winning")
Plots cumulative winning-trade count.
Number of break-even closed trades (running).
Returns the count of trades closed at break-even (zero profit) so far, as a running series.
When to use
To verify the winning + losing + break-even = closed identity, and to compute win rate without counting break-even trades.
plot(evenTrades())
Plots the number of trades that closed at break-even, leaving neither profit nor loss.