Broker emulator
When and at what price simulated orders fill, and how commission, slippage, funding and margin are applied.
The broker emulator turns order calls into fills. It follows TradingView’s strategy emulator and is deterministic: the same script on the same bars always produces the same trades.
The basic cycle
For every confirmed chart bar, in this order:
- Fill phase. The emulator walks the bar along its price path and fills pending orders: market orders at the open, then limit, stop and exit orders where the path reaches them.
- Script phase.
on chart.closeruns and sees the account after this bar’s fills. It may place, modify or cancel orders.
Orders placed in the script phase of bar N are first worked in the fill phase of bar N + 1; market orders fill at its open plus slippage.
Timeline example
A 1-hour chart with slippage: 1, tick size 0.1, a long entry with a 300-tick stop:
| Bar | Open | High | Low | Close | What happens |
|---|---|---|---|---|---|
| 10:00 | 61,950.0 | 62,120.0 | 61,900.0 | 62,080.0 | on chart.close: the EMAs cross up. strategy.entry("Long", strategy.long) and strategy.exit("SL", "Long", loss: 300.0) are queued. |
| 11:00 | 62,075.0 | 62,300.0 | 62,050.0 | 62,250.0 | The market buy fills at 62,075.0 + 0.1 = 62,075.1. The stop is armed at 62,075.1 − 30.0 = 62,045.1; the low of 62,050.0 stays above it. |
| 12:00 | 62,240.0 | 62,260.0 | 61,980.0 | 62,010.0 | Path: open → high → low → close. On the way down the stop triggers and fills at 62,045.1 − 0.1 = 62,045.0. |
Exits are live from the moment the entry fills, including the rest of the entry bar: had the 11:00 low been 62,040.0, the stop would have filled on the entry bar.
processOrdersOnClose
With processOrdersOnClose: true, orders placed in on chart.close are worked at
that bar’s close instead of the next open: market orders fill at the close plus
slippage.
| Setting | Signal at bar N’s close fills at |
|---|---|
false (default) | Open of bar N + 1 |
true | Close of bar N |
On liquid 24/7 crypto markets the next open is usually within a tick of the close, so the difference is small, but around news it is not.
The intrabar path
A bar reports four prices. The emulator assumes the path open → nearer extreme → farther extreme → close: when the high is at least as close to the open as the low, price goes up first, otherwise down first. Orders are checked along each segment in the order the path reaches them, so for a bracket the leg on the first segment wins.
useBarMagnifier would walk lower-timeframe bars inside each bar instead. Charts do
not provide them yet, so strategies on charts always use the four-point path.
Limit orders
A limit order fills when price reaches the limit: a buy limit at 3,000.0 fills when the path touches 3,000.0. It fills at the limit price, or at the open when the bar opens beyond it (a better price). Limits never slip.
backtestFillLimitsAssumption: n asks for more: price must trade n ticks through
the limit before it fills, at the limit price. This approximates waiting in the
queue behind other orders.
Stop orders and gaps
A stop triggers when price trades at or beyond it and fills at the stop price plus slippage. When a bar opens beyond the stop (a gap), it fills at the open plus slippage, worse than the stop.
Slippage and commission
| Fill | Slippage | Commission |
|---|---|---|
| Market | slippage ticks against you | Yes |
| Stop, stop-loss, trailing stop | slippage ticks against you | Yes |
| Limit, take-profit | None | Yes |
| Margin call | None | Yes |
Commission follows commissionType and commissionValue and is part of each trade’s
profit.
Funding on perpetuals
With fundingCosts: true (the default), a position held through a funding
settlement pays or receives rate × position value at the open of the first bar at
or after the settlement: longs pay a positive rate and shorts receive it. The rates
are the ones the data hub recorded just before each settlement; aggregated markets
use the open-interest weighted rate of their venues. Funding is part of each trade’s profit and of the
Strategy Tester’s Funding paid.
Margin and liquidation
With marginLong or marginShort below 100 % (or leverage above 1), positions may
be worth more than equity. An entry the account cannot fund is skipped. On every
price the emulator checks that equity covers the margin of the position; when it no
longer does, it liquidates part of the position, as TradingView does: four times the
contracts needed to cover the shortfall, at that price. Each event is a Margin
call fill and counts in the tester’s margin calls.
strategy.marginLiquidationPrice tells where the next one would start.
Aggregated markets
On an aggregated market the emulator fills at the aggregated price, which no single venue offers. Treat such a backtest as a view of the market as a whole and confirm promising results on the venue you would trade.
Repainting and look-ahead
A strategy only sees the past: on chart.close runs after a bar is confirmed, and
its orders fill on later prices. Two things still deserve care:
- Signals from
on chart.updateuse the forming bar, whose values change until it closes. Place orders inon chart.close. - Reading another timeframe’s
formingvalues gives the developing bar, not a confirmed one. See repainting.