Indicator

Fathom Opening

Set the frame from the open. Track the opening range bounds and their extensions all session long.

Range of the openingMinutes minutes after 9:30 am New York time, provisional while it forms. Once the range is set, the breakout creates imbalance zones in its direction and, on request, three projections computed from the statistics of previous sessions (provided by the history service). Without statistics covering at least one full session, the statistics:<session> object reports STATISTICS_UNAVAILABLE. A session’s range and projections are removed when the next session opens.

Identifier
opening-range
Objects received
range, zone, projection, statistics
Calculation
Since the start of the week
Historical cost
1 unit per trade

Subscribe

The same params work in real time, on historical data and in exports. Any you leave out take their default value.

Subscribe message
{
  "t": "subscribe",
  "sub": "opening-range",
  "instrument": "NQ.front",
  "indicator": "opening-range",
  "params": {
    "extendBars": 10,
    "openingMinutes": 60,
    "projections": true,
    "timeframe": 300,
    "zones": true
  },
  "mode": "live",
  "from": "live"
}

Parameters

As soon as a parameter differs from its default, the subscription counts as a custom configuration. A new value may require preparing a new calculation (status warming).

ParameterTypeDefaultAllowed valuesUnitDescription
extendBarsinteger101 to 500barsInitial zone extension, in bars.
openingMinutesinteger601 to 240—Length of the opening range after 9:30 am New York time, in minutes.
projectionsbooleantruetrue · false—Publish statistical projections after the range breakout.
timeframeinteger30015 · 60 · 300—Bar duration in seconds: 15, 60 or 300.
zonesbooleantruetrue · false—Publish imbalance zones in the breakout direction.

Objects received

Each object keeps the same id from one update to the next. Its data is in the data field. Prices are in ticks: multiply them by the instrument’s tick size (GET /v1/instruments) to get points.

range updated continuously

Range; provisional while it forms, removed at the next session.

Format of the id: range:<session>. While it changes, the object is sent with final: false, and each new version fully replaces the previous one. Its last version carries final: true.

FieldTypeUnitPresentDescription
barstringtimestamp (ns)alwaysStart of the bar where the range began.
highintegerticksalwaysHigh (ORH).
lowintegerticksalwaysLow (ORL); midpoint ORM = (high + low) / 2.

zone updated continuously

Zone; provisional while it is active.

Format of the id: zone:<session>:<ordinal>. While it changes, the object is sent with final: false, and each new version fully replaces the previous one. Its last version carries final: true.

FieldTypeUnitPresentDescription
activeboolean—alwaysThe zone is still valid.
barstringtimestamp (ns)alwaysStart of the bar that created the zone.
endnumberbarsalwaysEnd, in bars from bar.
highintegerticksalwaysTop of the zone.
lowintegerticksalwaysBottom of the zone.
sidestring · buy | sell—alwaysDirection of the range breakout.
startnumberbarsalwaysStart, in bars from bar.

projection updated continuously

Session projection, updated with the state of the range.

Format of the id: proj:<session>:<label>. While it changes, the object is sent with final: false, and each new version fully replaces the previous one. Its last version carries final: true.

FieldTypeUnitPresentDescription
labelstring · Protection | Ext. Avg | Ext Std-1—alwaysProjection: protection, average extension, average extension + 1 standard deviation.
priceintegerticksalwaysProjected price.

statistics updated continuously

Reports that the session’s statistics are missing; removed at the next session.

Format of the id: statistics:<session>. While it changes, the object is sent with final: false, and each new version fully replaces the previous one. Its last version carries final: true.

FieldTypeUnitPresentDescription
statusstring—alwaysProjections were requested but the session has no statistics.

Calculation warm-up

The calculation starts over at the beginning of every week (Saturday 00:00 UTC). During the weekend close it keeps the state of the past week; objects still open are finalized on the first trade of the new week. If nobody is using your parameters yet, the server first recomputes the week since its start (status warming), then goes live (status live).

Historical data follows the same rules: a query over a past period returns exactly what the real-time stream published.

Example messages

Messages received with the subscription parameters above. Over WebSocket, each message also carries sub and cursor.

In-progress version
{
  "t": "upsert",
  "id": "range:2026-09-24",
  "final": false,
  "ts": "1790256600000077031",
  "data": {
    "bar": "1790256600000000000",
    "high": 122076,
    "low": 122076
  }
}
Final version
{
  "t": "upsert",
  "id": "range:2026-09-24",
  "final": true,
  "ts": "1790260200003097647",
  "data": {
    "bar": "1790256600000000000",
    "high": 122554,
    "low": 121973
  }
}
In-progress version
{
  "t": "upsert",
  "id": "zone:2026-09-24:0",
  "final": false,
  "ts": "1790266800003513995",
  "data": {
    "side": "buy",
    "high": 122373,
    "low": 122371,
    "active": true,
    "bar": "1790266500000000000",
    "start": -0.4,
    "end": 9.6
  }
}
In-progress version
{
  "t": "upsert",
  "id": "proj:2026-09-24:protection",
  "final": false,
  "ts": "1790266800003513995",
  "data": {
    "label": "Protection",
    "price": 122662
  }
}
Final version
{
  "t": "upsert",
  "id": "zone:2026-09-24:2",
  "final": true,
  "ts": "1790270400021675849",
  "data": {
    "side": "buy",
    "high": 123010,
    "low": 123008,
    "active": false,
    "bar": "1790268300000000000",
    "start": -0.4,
    "end": 6
  }
}

JSON schemas

To validate or type your data: the JSON schemas of the parameters and of data, also available from GET /v1/indicators. The SDK can generate types from them.

Parameters schema
JSON
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://fathomcharts.com/schemas/opening-range/params.json",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "extendBars": {
      "type": "integer",
      "default": 10,
      "minimum": 1,
      "maximum": 500,
      "description": "Initial zone extension, in bars."
    },
    "openingMinutes": {
      "type": "integer",
      "default": 60,
      "minimum": 1,
      "maximum": 240,
      "description": "Length of the opening range after 9:30 am New York time, in minutes."
    },
    "projections": {
      "type": "boolean",
      "default": true,
      "description": "Publish statistical projections after the range breakout."
    },
    "timeframe": {
      "type": "integer",
      "default": 300,
      "enum": [
        15,
        60,
        300
      ],
      "description": "Bar duration in seconds: 15, 60 or 300."
    },
    "zones": {
      "type": "boolean",
      "default": true,
      "description": "Publish imbalance zones in the breakout direction."
    }
  }
}
Schema of the data field
JSON
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://fathomcharts.com/schemas/opening-range/data.json",
  "anyOf": [
    {
      "title": "range",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "bar",
        "high",
        "low"
      ],
      "properties": {
        "bar": {
          "type": "string",
          "pattern": "^[0-9]+$",
          "description": "Start of the bar where the range began."
        },
        "high": {
          "type": "integer",
          "description": "High (ORH)."
        },
        "low": {
          "type": "integer",
          "description": "Low (ORL); midpoint ORM = (high + low) / 2."
        }
      }
    },
    {
      "title": "zone",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "side",
        "high",
        "low",
        "active",
        "bar",
        "start",
        "end"
      ],
      "properties": {
        "active": {
          "type": "boolean",
          "description": "The zone is still valid."
        },
        "bar": {
          "type": "string",
          "pattern": "^[0-9]+$",
          "description": "Start of the bar that created the zone."
        },
        "end": {
          "type": "number",
          "description": "End, in bars from `bar`."
        },
        "high": {
          "type": "integer",
          "description": "Top of the zone."
        },
        "low": {
          "type": "integer",
          "description": "Bottom of the zone."
        },
        "side": {
          "type": "string",
          "enum": [
            "buy",
            "sell"
          ],
          "description": "Direction of the range breakout."
        },
        "start": {
          "type": "number",
          "description": "Start, in bars from `bar`."
        }
      }
    },
    {
      "title": "projection",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "label",
        "price"
      ],
      "properties": {
        "label": {
          "type": "string",
          "enum": [
            "Protection",
            "Ext. Avg",
            "Ext Std-1"
          ],
          "description": "Projection: protection, average extension, average extension + 1 standard deviation."
        },
        "price": {
          "type": "integer",
          "description": "Projected price."
        }
      }
    },
    {
      "title": "statistics",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "status"
      ],
      "properties": {
        "status": {
          "const": "STATISTICS_UNAVAILABLE",
          "description": "Projections were requested but the session has no statistics."
        }
      }
    }
  ]
}