Indicator

Fathom Walls

Some levels hold, again and again. Spot the ones buyers or sellers keep defending.

On closed bars, finds a cluster of nearby extremes: highs or lows repeated within tickGrouping ticks, with no breakout beyond tickBreakoutMargin. The cells at the extreme must hold enough volume, dominated by one side. At most one signal per bar, always final. The computation restarts every week.

Identifier
liquidity-walls
Objects received
signal
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": "liquidity-walls",
  "instrument": "NQ.front",
  "indicator": "liquidity-walls",
  "params": {
    "minClusterVolume": 30,
    "minDeltaPercent": 40,
    "minPerBarVolume": 10,
    "minimumBars": 2,
    "nearnessBars": 100,
    "tickBreakoutMargin": 0,
    "tickGrouping": 4,
    "timeframe": 15
  },
  "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
minClusterVolumeinteger4000 to 10,000,000contractsTotal volume the wall’s cells must exceed (threshold excluded).
minDeltaPercentinteger700 to 100%Minimum share of the dominant side in the volume of the wall’s cells.
minPerBarVolumeinteger1000 to 1,000,000contractsMinimum volume for a cell to count.
minimumBarsinteger22 to 100barsMinimum number of counted cells.
nearnessBarsinteger201 to 1,000barsMaximum age of an extreme in the cluster, in bars.
tickBreakoutMargininteger10 to 100ticksHow far price may poke past the extreme of the bar cluster.
tickGroupinginteger11 to 100ticksDepth of the wall below or above the extreme.
timeframeinteger6015 · 60 · 300—Bar duration in seconds: 15, 60 or 300.

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.

signal sent complete

Signal of the closed bar barStartNs.

Format of the id: <barStartNs>. Each object is sent once, already complete (final: true).

FieldTypeUnitPresentDescription
cellsinteger—alwaysNumber of cells that qualify the wall.
priceintegerticksalwaysExtreme tested by the bar.
sidestring · buy | sell—alwayssell: seller wall at the high; buy: buyer wall at the low.
sideVolumeintegercontractsalwaysVolume of the dominant side in those cells.
volumeintegercontractsalwaysVolume of the wall’s cells.

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.

Final version
{
  "t": "upsert",
  "id": "1790217915000000000",
  "final": true,
  "ts": "1790217934086470651",
  "data": {
    "price": 122988,
    "side": "sell",
    "volume": 72,
    "sideVolume": 60,
    "cells": 4
  }
}

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/liquidity-walls/params.json",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "minClusterVolume": {
      "type": "integer",
      "default": 400,
      "minimum": 0,
      "maximum": 10000000,
      "description": "Total volume the wall’s cells must exceed (threshold excluded)."
    },
    "minDeltaPercent": {
      "type": "integer",
      "default": 70,
      "minimum": 0,
      "maximum": 100,
      "description": "Minimum share of the dominant side in the volume of the wall’s cells."
    },
    "minPerBarVolume": {
      "type": "integer",
      "default": 100,
      "minimum": 0,
      "maximum": 1000000,
      "description": "Minimum volume for a cell to count."
    },
    "minimumBars": {
      "type": "integer",
      "default": 2,
      "minimum": 2,
      "maximum": 100,
      "description": "Minimum number of counted cells."
    },
    "nearnessBars": {
      "type": "integer",
      "default": 20,
      "minimum": 1,
      "maximum": 1000,
      "description": "Maximum age of an extreme in the cluster, in bars."
    },
    "tickBreakoutMargin": {
      "type": "integer",
      "default": 1,
      "minimum": 0,
      "maximum": 100,
      "description": "How far price may poke past the extreme of the bar cluster."
    },
    "tickGrouping": {
      "type": "integer",
      "default": 1,
      "minimum": 1,
      "maximum": 100,
      "description": "Depth of the wall below or above the extreme."
    },
    "timeframe": {
      "type": "integer",
      "default": 60,
      "enum": [
        15,
        60,
        300
      ],
      "description": "Bar duration in seconds: 15, 60 or 300."
    }
  }
}
Schema of the data field
JSON
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://fathomcharts.com/schemas/liquidity-walls/data.json",
  "title": "signal",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "price",
    "side",
    "volume",
    "sideVolume",
    "cells"
  ],
  "properties": {
    "cells": {
      "type": "integer",
      "description": "Number of cells that qualify the wall."
    },
    "price": {
      "type": "integer",
      "description": "Extreme tested by the bar."
    },
    "side": {
      "type": "string",
      "enum": [
        "buy",
        "sell"
      ],
      "description": "`sell`: seller wall at the high; `buy`: buyer wall at the low."
    },
    "sideVolume": {
      "type": "integer",
      "description": "Volume of the dominant side in those cells."
    },
    "volume": {
      "type": "integer",
      "description": "Volume of the wall’s cells."
    }
  }
}