# Strategies & backtesting

> Turn a script into a strategy that places simulated orders and backtests on the chart's history, TradingView style.

A **strategy** is a script that places orders as well as plotting. You decide *when*
to enter and exit; Flowscope's broker emulator decides *how* those orders would have
filled, keeps the books (position, equity, commission, funding) and reports the
result in the [Strategy Tester](/docs/scripting/strategies/strategy-tester).

The model follows TradingView's Pine `strategy()`: one `strategy(...)` declaration,
order functions such as `strategy.entry` and `strategy.exit`, and read-only values
such as `strategy.positionSize` and `strategy.equity`, with the same names in
camelCase. Everything else is the language you already use for indicators.

## What changes when a script becomes a strategy

| Indicator | Strategy |
|---|---|
| Plots, tables, drawings, alerts | Everything an indicator can do |
| No notion of a position | A simulated account with position, equity and trades |
| Output lives on the chart | Output also feeds the Strategy Tester |
| — | Entry and exit marks with order ids on the chart |

A script is a strategy as soon as it contains a `strategy(...)` declaration. There
is at most one, usually right after the `script` header.

## A complete first strategy

The script trades a fast/slow EMA crossover in both directions and protects every
entry with a stop two ATRs away from the fill.

```flowscope title="ema-cross-atr-stop.fs"
script "EMA cross with ATR stop"

strategy(
  initialCapital: 10000.0,
  defaultQtyType: strategy.percentOfEquity,
  defaultQtyValue: 25.0,
  commissionType: strategy.commission.percent,
  commissionValue: 0.04,
  slippage: 1
)

input (
  fastLen = input.int(12, title: "Fast EMA", min: 1, max: 200)
  slowLen = input.int(26, title: "Slow EMA", min: 2, max: 400)
  atrLen = input.int(14, title: "ATR length", min: 1, max: 100)
  stopAtr = input.float(2.0, title: "Stop distance (ATR)", min: 0.1)
)

data chart = subscribe(data.ohlcv)

plot (
  fastLine = plot.line(title: "Fast EMA", color: color.blue, width: 2)
  slowLine = plot.line(title: "Slow EMA", color: color.orange, width: 2)
)

on chart.close {
  let fast = ta.ema(chart.close, fastLen)
  let slow = ta.ema(chart.close, slowLen)
  let atr = chart.atr(atrLen)
  fastLine.plot(fast)
  slowLine.plot(slow)

  if atr != null {
    // The stop distance in ticks, fixed at signal time.
    let stopTicks = math.round(atr * stopAtr / context.tickSize)
    if ta.crossover(fast, slow) {
      strategy.entry("Long", strategy.long, comment: "EMA up")
      strategy.exit("Long SL", "Long", loss: stopTicks)
    }
    if ta.crossunder(fast, slow) {
      strategy.entry("Short", strategy.short, comment: "EMA down")
      strategy.exit("Short SL", "Short", loss: stopTicks)
    }
  }
}
```

Open the script editor, paste it, and press **Add to chart**. The Strategy Tester
opens at the bottom of the window with the backtest.

### What happens on each bar

1. `on chart.close` runs once per confirmed bar of the loaded history, oldest first.
2. On a bullish cross, `strategy.entry("Long", strategy.long)` queues a market order.
   If the strategy is short, the same order also closes the short: entries reverse.
3. `strategy.exit("Long SL", "Long", loss: ...)` attaches a stop to the `Long`
   entry, `loss` ticks from the actual fill price.
4. The emulator fills the market order at the **next bar's open** plus one tick of
   slippage, charges 0.04 % commission, and then watches the stop on every bar.

> [!NOTE]
> Orders placed at a bar's close fill at the next bar's open unless you declare
> `processOrdersOnClose: true`. You decide after the close, so you can only trade
> after it. See [Broker emulator](/docs/scripting/strategies/broker-emulator).

## History and live bars {#live}

On a chart, a strategy runs over every loaded bar. When new bars arrive it runs
again over the whole history (at most every 0.75 s while a bar is forming), so the
Strategy Tester and the marks on the chart always show the backtest up to now. A
forming bar is not traded: handlers in `on chart.close` see confirmed bars only.

> [!IMPORTANT]
> Strategies never send orders anywhere. There is no exchange connection in the
> strategy engine. To act on signals yourself, declare an `alert` and trigger it
> next to your order calls; alerts fire on live bars only.

## Where to put order calls

Place order calls in `on chart.close`. Order functions run in handlers only; calling
them from `setup` is a compile error.

## Reading the result

The chart shows an arrow and label at each fill with the order id and size, a
dotted line from entry to exit (green for a win, red for a loss), and a dashed line
at the average entry price while a position is open. The Strategy Tester shows the
P&L curve, the performance summary for all, long and short trades, and the list of
trades.

During a [bar replay](/docs/app/replay) the backtest stops at the replay bar and
grows as the replay plays.

## Next steps

```cards
[Declaration](/docs/scripting/strategies/declaration) Every strategy property: capital, sizing, commission, slippage, margin, funding.
[Orders](/docs/scripting/strategies/orders) entry, order, exit, close and cancel: ids, pyramiding, reversals, brackets and trailing stops.
[Position and trades](/docs/scripting/strategies/position-and-trades) Read the position, account values and trades from your script.
[Broker emulator](/docs/scripting/strategies/broker-emulator) When and at what price orders fill, how costs and margin are charged.
[Risk](/docs/scripting/strategies/risk) Risk-based sizing, drawdown stops, position caps and cooldowns, written in the script.
[Strategy Tester](/docs/scripting/strategies/strategy-tester) The bottom panel: every metric defined, list of trades, CSV.
```

For complete worked strategies, see the
[EMA and ATR strategy](/docs/scripting/examples/ema-atr-strategy) and the
[CVD breakout strategy](/docs/scripting/examples/cvd-breakout-strategy) examples.
