The strategy() declaration
strategy() accepts everything define() accepts (title, position, axis, customTitle, format, maxBarsBack) plus the broker parameters below. All are optional except title. Arguments are literal-only and validated like define(); any strategy param may also be wired to a normal input() so users can adjust it from the script settings, with the declaration acting as the default.
strategy(title="MA Cross",
initialCapital=10000, // starting equity, > 0
currency="USD", // display label
commissionPercent=0.0, // per fill, percent of notional
slippageBps=0.0, // adverse, per market-crossing fill
slippageModel="fixed", // "fixed" | "bookEstimate"
qtyType="percentOfEquity", // "fixed" | "percentOfEquity" | "cash"
qtyValue=100, // meaning depends on qtyType
pyramiding=1, // max stacked same-direction entries
fillModel="pessimistic", // "pessimistic" | "pathHeuristic"
instrument="spot", // "spot" | "perps", perps since engine 3.0.63
leverage=1, // perps only, > 0, since engine 3.0.63
maintenanceMarginPercent=0.5, // perps only, >= 0 and < 100, since engine 3.0.63
makerFeePercent=0.0, // perps maker fills, since engine 3.0.63
takerFeePercent=0.0, // perps taker fills, since engine 3.0.63
funding="data") // "data" | "off", perps funding since engine 3.0.63
| Parameter | Default | Meaning |
|---|---|---|
initialCapital | 10000 | Starting account equity. Must be positive. |
currency | "USD" | Display label for money-denominated stats. |
commissionPercent | 0 | Spot commission charged on every fill as a percent of fill notional. Ignored under instrument="perps" with a warning if nonzero since engine 3.0.63. |
slippageBps | 0 | Adverse basis points applied to market, stop, and trailing fills. Limit fills are exempt: a limit price is a bound and can fill better but never worse. |
slippageModel | "fixed" | "bookEstimate" prices market-crossing fills from recorded order-book depth where available. See Slippage and costs. |
qtyType / qtyValue | "percentOfEquity" / 100 | Default order sizing. "fixed": qtyValue units per entry. "percentOfEquity": (qtyValue / 100 * equityAtFill) / fillPrice. "cash": qtyValue / fillPrice. Since engine 3.0.63, perps mode makes "percentOfEquity" and "cash" size margin, then notional is margin times leverage. |
pyramiding | 1 | Maximum stacked same-direction entries. Excess entries are rejected and counted, never silently dropped. |
fillModel | "pessimistic" | Intrabar ordering assumption when a bar could fill two levels. See Fill simulation. |
instrument | "spot" | Since engine 3.0.63. "spot" uses spot accounting. "perps" enables isolated leveraged margin, liquidation, maker/taker fees, and optional funding. |
leverage | 1 | Since engine 3.0.63. Perps leverage. Must be greater than 0. In perps mode, percentOfEquity and cash size margin, then notional is margin times leverage. |
maintenanceMarginPercent | 0.5 | Since engine 3.0.63. Perps maintenance margin rate used to compute the liquidation price. Must be at least 0 and less than 100. |
makerFeePercent / takerFeePercent | 0 / 0 | Since engine 3.0.63. Perps fee rates as a percent of fill notional. Maker applies to limit-bound fills; taker applies to market-crossing fills. Ignored by spot with a warning if nonzero. |
funding | "data" | Since engine 3.0.63. Perps funding mode. "data" uses recorded funding settlements from the chart venue when supplied; "off" makes funding an exact no-op. |
Strategy scripts default to position="onchart" so trade markers land on the price series.
Order API
strategy.entry(id, direction, qty=na, limit=na, stop=na, ocaName=na, comment=na)
strategy.close(id, comment=na) // close the named entry (market, next open)
strategy.closeAll(comment=na)
strategy.cancel(id) // cancel pending unfilled orders with this id
strategy.cancelAll()
strategy.exit(id, fromEntry=na, qty=na, qtyPercent=na,
profit=na, limit=na, loss=na, stop=na,
trailPoints=na, trailOffset=na, ocaName=na, comment=na)
directionis"long"or"short".idis your string key; re-issuing an id replaces the pending unfilled order with that id.- A plain
strategy.entryis a market order for the next bar open. Addinglimitorstopcreates a resting order that fills when touched. strategy.exitattaches bracket legs to an entry id:profitandlossin ticks,limitandstopas absolute prices. At least one leg is required.exitwithoutfromEntryprotects all open entries. Stop, limit, and trail legs within one exit id are inherently one-cancels-all.trailPointsactivates a trailing stop once the trade's favorable excursion reaches that many price units;trailOffsetsets the trailing distance. The trail ratchets monotonically with new favorable extremes.ocaNamejoins any orders (entries and exits) into a one-cancels-all group: when one fills, the rest cancel immediately.- Getters, valid on any bar:
strategy.positionSize()(signed),strategy.positionAvgPrice(),strategy.equity(),strategy.openProfit(),strategy.netProfit(),strategy.closedTradeCount(),strategy.winTradeCount(),strategy.lossTradeCount(),strategy.maxDrawdown().
//@version=2
strategy(title="Trend with Brackets", initialCapital=10000, qtyType="fixed", qtyValue=1, pyramiding=1, fillModel="pathHeuristic")
timeseries bars = ohlcv(symbol=currentSymbol, exchange=currentExchange)
timeseries fast = sma(source=bars.close, period=5)
timeseries slow = sma(source=bars.close, period=20)
var lastClose = bars.close
if (crossover(fast, slow)) {
strategy.entry("Trend", "long")
}
if (strategy.positionSize() > 0) {
strategy.exit("Protect", fromEntry="Trend", stop=lastClose * 0.97, limit=lastClose * 1.05)
}
plotLine(value=fast, width=1, colors=["#4f8cff"], label=["Fast SMA"], desc=["5-period SMA of close"])
plotLine(value=slow, width=1, colors=["#8b5cf6"], label=["Slow SMA"], desc=["20-period SMA of close"])Position model
The broker nets to one position. A strategy.entry in the opposite direction is a reversal: it closes the existing position fully at the same fill, then opens the new one at the requested quantity. pyramiding caps same-direction stacking; rejected entries are counted in the output rather than thrown.
Sizing details worth knowing:
- Explicit
qtyon an order always wins over the declaration'sqtyType. - Sized-at-fill quantities (
percentOfEquity,cash) resolve from the slippage-adjusted fill price, and fractional quantities are legal (the broker does not round lots). - Since engine 3.0.63, in perps mode,
percentOfEquityandcashsize isolated margin commitment, not direct notional. ExplicitqtyandqtyType="fixed"remain direct quantities and are margin-checked. - A computed size is rejected and counted when equity at fill is not positive or the quantity is not finite and positive.
Since engine 3.0.63, perps entries also pass an isolated-margin admission check before the opening leg is applied. Unrealized PnL is not collateral for adding exposure; see Perps and Leverage for the full model.
Order methods are recorded as rejected (not thrown) when the current bar has NaN OHLC values or is not confirmed. On the last bar, unfilled orders remain visible under pending orders in the output.