---
title: "Greek flow"
description: "The delta and the vega the options tape traded on the chart's underlying, signed by side and summed through the session. Each print's share delta is its…"
order: 104
section: "cookbook"
---

<!-- source: docs/indicators/cookbook/greek-flow.md; generated by packages/cli/scripts/gen-indicator-docs.ts, do not edit -->

# Greek flow

The delta and the vega the options tape traded on the chart's underlying, signed by side and summed through the session. Each print's share delta is its contracts times its delta times 100, calls up and puts down; a print bought at the ask counts as it is and one sold at the bid counts against, so the directional delta is the share delta bought at the ask minus the share delta sold at the bid. That is the share-equivalent pressure the tape puts on the stock, close to what the dealers on the other side end up hedging, and a divergence between it and the price is the read. The directional vega is the vega bought at the ask minus the vega sold at the bid, in USD per IV point: above zero the tape is net buying volatility. The delta line sits under the chart and the vega line in a pane below it.

The parts are four scalar `options_flow` inputs, the sided share delta and vega sums ([Data sources](../core-concepts/data-sources.md#us-listed-options-by-the-charts-underlying)), four more under `moneyness: "otm"` behind a setting gate, a named `pane` for the vega line ([Plotting](../presentation/plotting.md#panes)) and a `render.label` that says why when there is nothing to draw ([Plotting](../presentation/plotting.md#fixed-position-text)). This is also the `greek-flow` template: the **Greek Flow** card under **Order flow** in the editor's starter list, and it compiles as written.

## The wrun indicator

```typescript sample=greek-flow
// Greek Flow: the delta and the vega the options tape traded on the chart's underlying, signed by side and summed
// through the session (each trade date starts again). Each print's share delta is its contracts times its delta
// times 100, calls up and puts down; a print bought at the ask counts as it is and one sold at the bid counts
// against, so the directional delta is the share delta bought at the ask minus the share delta sold at the bid: the
// share-equivalent pressure the tape puts on the stock, close to what the dealers on the other side end up hedging.
// The directional vega is the vega bought at the ask minus the vega sold at the bid, in USD per IV point: above zero
// the tape is net buying volatility. Prints at the mid or with no quote carry no side and count in neither line. The
// delta line sits under the chart and the vega line in a pane below it. Out of the money only reads the same sums
// over the out-of-the-money contracts (a second read, fetched only while it is on). The rows come from options_flow,
// one per bar: 1-minute rows reach back 7 days and 5-minute rows 30 days, so older bars carry none; a bar without a
// row adds nothing, and the regular-session bars that had none are counted, the sums being a floor while the count
// is above 0.

param.bool("otm", false, { label: "Out of the money only", description: "Read the out-of-the-money contracts alone (a second read, fetched only while this is on)" });
input("close", ohlcv.close); // the chart's own candles: the bar grid
input("trade_date", time.trade_date); // the bar's trade date: the sums start again on each
input("session", time.session); // 1 in the regular session: the bars a missing row is counted on
input("delta_ask", options_flow.share_delta_ask, { missing: "nan", description: "Share delta bought at the ask in the bar, the chart's underlying: contracts times delta times 100" }); // NaN on a bar the class serves no row for
input("delta_bid", options_flow.share_delta_bid, { missing: "nan", description: "Share delta sold at the bid in the bar" });
input("vega_ask", options_flow.vega_ask, { missing: "nan", description: "Vega bought at the ask in the bar, USD per IV point" });
input("vega_bid", options_flow.vega_bid, { missing: "nan", description: "Vega sold at the bid in the bar, USD per IV point" });
input("otm_delta_ask", options_flow.share_delta_ask, { moneyness: "otm", when: "otm", missing: "nan", description: "Share delta bought at the ask, out-of-the-money contracts" });
input("otm_delta_bid", options_flow.share_delta_bid, { moneyness: "otm", when: "otm", missing: "nan", description: "Share delta sold at the bid, out-of-the-money contracts" });
input("otm_vega_ask", options_flow.vega_ask, { moneyness: "otm", when: "otm", missing: "nan", description: "Vega bought at the ask, out-of-the-money contracts" });
input("otm_vega_bid", options_flow.vega_bid, { moneyness: "otm", when: "otm", missing: "nan", description: "Vega sold at the bid, out-of-the-money contracts" });
pane("vega", { title: "Vega flow", height_frac: 0.16, format: "usd" });
output("delta_flow", line, lower, { color: "#38bdf8", width: 2, label: "Directional delta", format: "si", unit: " sh", description: "Share delta bought at the ask minus sold at the bid, summed since the session's first bar, shares" });
output("delta_zero", line, lower, { color: "#334155", width: 1, legend: false, description: "The delta pane's zero line" });
output("vega_flow", line, lower, { pane: "vega", color: "#a78bfa", width: 2, label: "Directional vega", format: "usd", description: "Vega bought at the ask minus sold at the bid, summed since the session's first bar, USD per IV point" });
output("vega_zero", line, lower, { pane: "vega", color: "#334155", width: 1, legend: false, description: "The vega pane's zero line" });
// The readings, data-only: the Console reads them.
output("delta_bar", none, lower, { description: "This bar's directional share delta; NaN on a bar without a flow row" });
output("vega_bar", none, lower, { description: "This bar's directional vega, USD per IV point; NaN on a bar without a flow row" });
output("delta_sided", none, lower, { description: "This bar's share delta at the ask plus at the bid: the sided prints' delta whichever way they traded" });
output("missing_bars", none, lower, { description: "Regular-session bars of this session that carried no flow row: the sums are a floor while it is above 0" });
string("note", { max_bytes: 64 }); // the one line while there is nothing to draw
render.label("note_label", { position: "top_center", text: "note", color: "#94a3b8", style: "knockout", offset: [0, 8] });

let otm = false; // setting, read in onStart()
let day: f64 = NaN; // the trade date the sums run over
let delta = 0.0; // the session's sums
let vega = 0.0;
let rows = 0; // bars of this session that carried a flow row
let missing = 0; // regular-session bars of this session without one
let runRows = 0; // flow rows over the whole run

function onStart(): void {
  otm = pb_otm();
}

// onBar() runs once per bar: a new trade date starts the sums again; this bar's row adds its directional delta and
// vega, or counts as missing on a regular-session bar; then the lines and the readings.
function onBar(): void {
  const date = in_trade_date();
  if (!isNaN(date) && date != day) {
    day = date;
    delta = 0.0;
    vega = 0.0;
    rows = 0;
    missing = 0;
  }
  // The out-of-the-money inputs read NaN while the setting is off: their lane is never fetched.
  const deltaAsk = otm ? in_otm_delta_ask() : in_delta_ask();
  const deltaBid = otm ? in_otm_delta_bid() : in_delta_bid();
  const vegaAsk = otm ? in_otm_vega_ask() : in_vega_ask();
  const vegaBid = otm ? in_otm_vega_bid() : in_vega_bid();
  const served = !isNaN(deltaAsk) && !isNaN(deltaBid) && !isNaN(vegaAsk) && !isNaN(vegaBid);
  if (served) {
    delta += deltaAsk - deltaBid;
    vega += vegaAsk - vegaBid;
    rows += 1;
    runRows += 1;
  } else if (in_session() == 1.0) missing += 1;
  const reading = rows > 0;
  out_delta_flow(reading ? delta : NaN);
  out_delta_zero(0.0);
  out_vega_flow(reading ? vega : NaN);
  out_vega_zero(0.0);
  out_delta_bar(served ? deltaAsk - deltaBid : NaN);
  out_vega_bar(served ? vegaAsk - vegaBid : NaN);
  out_delta_sided(served ? deltaAsk + deltaBid : NaN);
  out_missing_bars(f64(missing));
  if (bar.isLast()) str_note(runRows == 0 ? "No options flow on this chart yet" : rows == 0 ? "No options flow yet this session" : ""); // an empty text draws no label
}
```

## How it works

**The model sums.** Each `options_flow` row carries `share_delta_ask` and `share_delta_bid`, the sum of contracts times delta times 100 over the bar's priced prints at the ask and at the bid, in shares of the underlying, and `vega_ask` and `vega_bid`, the vega of the same prints in USD per IV point. A print the data plane could not price has no greeks and adds to neither; `n_priced` counts the ones it could.

**Signed by side.** `delta_flow` adds the bar's share delta at the ask minus at the bid, so call buying and put selling push it up, put buying and call selling down. `vega_flow` does the same with vega. Prints at the mid or with no quote carry no side and count in neither. `delta_sided`, a data-only reading, is the bar's share delta at the ask plus at the bid: the sided prints' delta whichever way they traded.

**Sums by session.** Both lines start again on each trade date (`time.trade_date`). A bar without a row adds nothing, and a regular-session bar without one counts in `missing_bars`: while it is above 0 the sums are a floor.

**Out of the money.** The setting reads the same four fields under `moneyness: "otm"`, the out-of-the-money contracts alone (a strike within 0.5% of the underlying counts as out of the money). Those inputs carry `when: "otm"`, so their rows load only while it is on.

## Where it runs

US stock and ETF charts, and the option contract charts of those underlyings, through OpenMarket's official package once the chart serves `options_flow`. The class is upcoming: the kit declares it ahead of the chart lane, and a copy you run from the editor follows the US options rule on [Limitations](../reference/limitations.md). One-minute rows reach back 7 days and five-minute rows 30 days.

## When data is missing

A line with nothing to draw stays empty rather than flat at zero: a session without a row draws no line, and a label at the top of the chart says "No options flow on this chart yet" while no bar of the run carried one or "No options flow yet this session" while the newest session has none. Read `missing_bars` at the Console for the session's regular-session bars without a row.

## Customize it

- **Per bar instead of the session.** Draw `delta_bar` as a `histogram` in place of `delta_flow` to see each bar's pressure on its own.
- **Dollar delta.** Multiply the bar's share delta by `bar.close()` for the notional the tape moved.
- **One expiry bucket.** Add `dte: "0dte"` to the inputs to follow the same-day contracts, whose delta moves fastest.

## Run it

1. In the editor's Explorer, press the **Templates** icon ("Browse starter templates") and pick **Greek Flow** under **Order flow**.
2. Press **Run** on a US stock chart: the official package draws the delta line under the chart and the vega line below it.
3. At the editor's Console prompt, type `delta_flow` and `vega_flow` for the session's sums, or `delta_sided` for the last bar's delta on both sides.

## Concepts used

- [Data sources](../core-concepts/data-sources.md#us-listed-options-by-the-charts-underlying) for the `options_flow` fields and the `moneyness` knob
- [Plotting](../presentation/plotting.md#panes) for a second pane below the chart
- [Plotting](../presentation/plotting.md#fixed-position-text) for the label at a corner
- [Limitations](../reference/limitations.md) for the US options rule and the upcoming OPRA sources
