# Start here

> How a Flowscope script is organised, what happens when it starts, and when each handler runs.

Every Flowscope script has two kinds of content. Declarations describe what the script contains: its settings, its data, its outputs and its reusable logic. Handlers describe what happens when market data changes.

You do not need the whole language to build something useful. If you are new, read this page and then [build your first indicator](/docs/scripting/getting-started/first-indicator). If you already write TradingView Pine Script, start with [coming from Pine Script](/docs/scripting/getting-started/coming-from-pine). Pick up the [guides](/docs/scripting/guides) as individual topics become relevant.

## How a script is organised

A script is a single file. The first line is the header `script "Name"`. Every line after it belongs to a top-level declaration. Loose statements between declarations are not allowed; executable code lives inside a function or a handler.

| Declaration | What it defines |
|---|---|
| `input` | A setting shown in the script's settings panel. |
| `data` | A market-data subscription and the name you read it by. |
| `state` | A value that is initialised once and kept across all handler calls. |
| `setup` | A value computed once at start, or a family of values whose shape is fixed at start. |
| `pane` | A sub-pane below the price chart. |
| `window` | A separate window with its own panels: charts, tables or heatmaps. |
| `plot` | A visual output, such as a line or a histogram, that handlers feed. |
| `fill` | A shaded area between two plots. |
| `alert` | A named alert that handlers can trigger on live data. |
| `strategy` | Turns the script into a strategy and sets backtest properties. See [strategies](/docs/scripting/strategies). |
| `type` | A record with named fields and optional methods. |
| `fn` | A reusable calculation or action. It runs only when called. |
| `on` | A handler that runs for one event of one subscription. |

### Grouped declarations

`input`, `data`, `state`, `setup`, `plot`, `fill`, `pane` and `alert` have a grouped form. Put one declaration per line inside parentheses:

```flowscope
input (
  length = input.int(20, title: "Length", min: 1)
  upColor = input.color(color.up, title: "Up")
  downColor = input.color(color.down, title: "Down", sameLine: true)
)
```

This is exactly the same as writing three separate `input` lines. Grouping only helps you keep related declarations together. `script`, `strategy`, `type`, `fn`, `window` and `on` are always written on their own.

> [!NOTE]
> One statement goes on one line, and there are no semicolons. To split a long expression, break the line after an operator such as `+`, `&&` or `?`.

## A complete script shape

The script below draws the previous four-hour range on any chart. It uses most kinds of declaration at least once.

```flowscope title="previous-4h-range.fs"
script "Previous 4h range"

type Range {
  high: float
  low: float

  fn mid() -> float {
    return (self.high + self.low) / 2.0
  }

  fn width() -> float {
    return self.high - self.low
  }
}

fn rangeOf(high: float?, low: float?) -> Range? {
  if high == null || low == null {
    return null
  }
  return Range { high: high, low: low }
}

input (
  edgeColor = input.color(color.blue, title: "Range edges")
  showMid = input.bool(true, title: "Show midpoint")
)

data (
  chart = subscribe(data.ohlcv)
  h4 = subscribe(data.ohlcv, timeframe: 4h)
)

state last: Range? = null

plot (
  top = plot.line(title: "4h high", color: edgeColor, style: linestyle.step)
  middle = plot.line(title: "4h mid", color: color.gray, style: linestyle.dotted)
  bottom = plot.line(title: "4h low", color: edgeColor, style: linestyle.step)
)

on h4.close {
  last = rangeOf(h4.high, h4.low)
}

on chart.update {
  let r = last
  if r != null {
    top.plot(r.high)
    middle.plot(showMid ? r.mid() : null)
    bottom.plot(r.low)
  }
}
```

How the parts fit together:

1. `Range` groups two prices that always travel together and adds two methods.
2. `rangeOf` is a plain function. Declaring it does nothing; it runs only when `on h4.close` calls it.
3. Two inputs let you pick the edge colour and hide the midpoint.
4. Two subscriptions follow the chart's candles and four-hour candles on the same market.
5. `state last` remembers the most recent confirmed four-hour range between handler calls.
6. The three plots declare their default look.
7. `on h4.close` runs once per confirmed four-hour bar and stores the range.
8. `on chart.update` runs on every chart update and draws whatever range is stored.

`last` is a state value, which is a field-like storage slot. The handler copies it to the local `r` before the null check, because null checks only narrow locals. The [missing values](/docs/scripting/guides/missing-values) guide explains why.

## What happens at start

When you add a script to a chart, Flowscope prepares it in this order:

1. **Compile.** The source is parsed and type-checked. Errors appear with a code you can look up in [diagnostics](/docs/scripting/reference/diagnostics).
2. **Inputs.** Each input takes its saved value, or its default on first use.
3. **Setup.** `setup` expressions, panes, windows, plots, fills and alerts are created. Setup can call setup-safe built-ins and read `context` and inputs, but cannot call your own `fn`s.
4. **State.** Every `state` initialiser runs exactly once.
5. **History.** The loaded history of every subscription is replayed bar by bar, in time order, through your handlers.
6. **Live.** As new data arrives, the chart runs the script again over its history, so the newest bars go through the same handlers.

Because history and live data go through the same handlers, an indicator you see on old bars behaves the same way on new ones. If you change an input, the script restarts from step 2 and recomputes history.

> [!IMPORTANT]
> A script may take at most 10 million steps in one update. A script that exceeds it stops with an error instead of slowing the terminal. See [performance](/docs/scripting/performance).

## Handlers and when they run

Period-based subscriptions, `data.ohlcv`, `data.oi`, `data.vd`, `data.cvd` and `data.stat`, support three handlers:

| Handler | When it runs | Typical use |
|---|---|---|
| `on x.open` | Once when a new period of `x` starts. | Reset per-bar counters, start a new zone. |
| `on x.update` | Every time `x` changes, including many times while a live bar is forming. | Live values, drawings that follow price. |
| `on x.close` | Once when a period of `x` is confirmed. | Final values, confirmed signals, strategy orders. |

A `data.trades` subscription uses a single handler, `on t.trade(tr) { }`. It runs once for every print. `tr` is a `Trade` record with `time`, `price`, `size` and `isBuy`.

`data.book` and `data.volume` are snapshot sources. They have no handlers of their own; you read them inside a handler on another subscription.

A script can have as many handlers as it needs, but only one for each subscription and event pair. Handlers communicate through `state`: one handler writes a value, a later call of another handler reads it.

During history replay, a bar triggers `open`, then `update`, then `close`. On a chart, new data re-runs the script over the loaded history, at most every 0.75 s: confirmed bars go through `close`, the forming bar through `open` and `update`.

Continue with [your first indicator](/docs/scripting/getting-started/first-indicator), or read [data and update events](/docs/scripting/guides/data-and-events) for the full rules on what each subscription returns inside each handler.
