Skip to content

WebSockets · Futures

Futures absorption stream

Futures absorption as it is called.
WS/v1/ws/futures/absorptionwsFuturesAbsorption
On this page

Held-extreme absorption from the same model as REST /v1/futures/absorption and the terminal's Futures Absorption widget: sellers absorbed when net aggressive selling keeps hitting a low that holds (buyers at a holding high), confirmed back at the extreme, with a threshold scaled to the contract's own volume. kind called is sent the moment an absorption is announced; kind updated follows at most once a second per absorption while its net aggression keeps growing (the same id as the call and as REST). Each dated contract's model is warmed from the captured recent tape of the current session, so calls can arrive right after subscribing; it starts afresh at each session open and restarts from the captured tape after a gap. Subscribe and unsubscribe products (ES, a product selects its front contract) or dated contracts (NQZ6) on one socket. The model parameters are the defaults; tune them per request on the REST route.

Connect and subscribe

Open wss://api.ordermap.si/v1/ws/futures/absorption?symbols=ES with your key in the Authorization header and your saved installation ID in X-OrderMap-Device-ID, then send a subscribe message. Up to 25 symbols per connection. Streams need API Pro. All keys and projects share one active device per account and one connection per event type. Reuse the same installation ID for every stream and reconnect. Browser subprotocols, limits and close codes are in WebSockets.

Node.js

import WebSocket from "ws";

// Create a UUID once per installation, save it, and reuse it for every stream.
const deviceId = process.env.ORDERMAP_DEVICE_ID;
if (!deviceId) throw new Error("Set ORDERMAP_DEVICE_ID to this installation's saved UUID.");

const ws = new WebSocket("wss://api.ordermap.si/v1/ws/futures/absorption?symbols=ES", {
  headers: {
    Authorization: `Bearer ${process.env.ORDERMAP_API_KEY}`,
    "X-OrderMap-Device-ID": deviceId,
  },
});

ws.on("open", () => ws.send(JSON.stringify({ action: "subscribe", symbols: ["ES"] })));
ws.on("message", (raw) => {
  const message = JSON.parse(raw.toString());
  if (message.type === "event") console.log(message.seq, message.data);
  if (message.type === "gap") console.warn("continuity lost: refetch the range over REST", message);
});
ws.on("close", (code, reason) => console.log("closed", code, reason.toString()));

Subscribe message

{"action":"subscribe","symbols":["ES"]}

Upgrade headers

A persistent installation ID is required. Supply the header below, or offer it as an ordermap.device.<id> browser subprotocol with ordermap.v1. Reuse the same saved ID for every event type, key, project and reconnect. Headers are not subscription filters.

ParameterType and limitsDescription
X-OrderMap-Device-IDheaderoptionalstringat least 16 charactersat most 128 characterspattern ^[A-Za-z0-9_-]{16,128}$Required unless supplied as an ordermap.device.<id> subprotocol together with ordermap.v1. Generate one random identifier per client installation and persist it across event types, keys, projects and reconnects. Never send it in the URL.

Subscription parameters

3 parameters, none required. Send them in the query string of the upgrade request, or as the filters of a subscribe message.

ParameterType and limitsDescription
symbolsqueryoptionalarray<string>comma-separated in one parameter1 to 25 itemseach at most 128 characterspattern ^[A-Za-z][A-Za-z0-9.]{0,9}$Symbols to subscribe to (up to 25).
sidequeryoptionalarray<string>comma-separated in one parameterbuysell1 to 2 itemsOnly these absorbed aggressors: sell (sellers absorbed at a low) or buy (buyers absorbed at a high).
min_net_aggressionqueryoptionalintegermin 1max 1000000Only absorptions whose net aggression reaches this many contracts.

Event

Each event is one message: {"type":"event","event_type":"futures.absorption","seq":N,"data":{...}}.

data of futures.absorption

  • aggressor_sharenumberrequiredaggressor_volume divided by classified_volume.
  • aggressor_volumeintegerrequiredAggressor contracts since the test began.
  • classified_volumeintegerrequiredBuy plus sell contracts since the test began.
  • contractstringrequiredDated contract.
  • end_timeintegerunix-msrequiredLatest print that grew the absorption. Unix epoch milliseconds (UTC).
  • idstringrequiredIdentifier of the absorption, the same on its call, its updates and REST /v1/futures/absorption.
  • kindstringrequiredcalled when the absorption is announced, updated while its net aggression keeps growing.calledupdated
  • net_aggressionintegerrequiredAggressor contracts minus the other side's since the test began (unknown-side prints excluded).
  • pricenumberrequiredThe holding low or high.
  • price_ticksstringrequiredprice as an integer count of ticks, as a string.
  • sidestringrequiredAbsorbed aggressor: sell when sellers were absorbed at a holding low, buy when buyers were absorbed at a holding high.buysell
  • start_timeintegerunix-msrequiredFirst print of the test of that low or high. Unix epoch milliseconds (UTC).
  • symbolstringrequiredThe symbol subscribed to.
  • thresholdnumberrequiredNet aggression the call required.
  • timestampintegerunix-msrequiredTime of the print that produced this event. Unix epoch milliseconds (UTC).
  • trigger_timeintegerunix-msrequiredWhen the absorption was called. Unix epoch milliseconds (UTC).

Example event

{
  "type": "event",
  "event_type": "futures.absorption",
  "seq": 1,
  "data": {
    "aggressor_share": 0.5865,
    "aggressor_volume": 61,
    "classified_volume": 104,
    "contract": "NQZ6",
    "end_time": 1792979848900,
    "id": "4c1f0a9e2d7b6c5a8e3f1d0b9a7c6e5f4d3b2a1c0e9f8d7c6b5a4e3d2c1b0a9f",
    "kind": "called",
    "net_aggression": 18,
    "price": 29163.75,
    "price_ticks": "116655",
    "side": "sell",
    "start_time": 1792979827763,
    "symbol": "NQ",
    "threshold": 13.84,
    "timestamp": 1792979848900,
    "trigger_time": 1792979848900
  }
}

Before the upgrade

Errors before the upgrade are ordinary JSON errors; after it, problems arrive as messages and close codes (see WebSockets).

StatusMeaningBody
101Switching protocols: WebSocket protocol ordermap.v1.Switching protocols
400Invalid handshake parameters or missing, malformed or conflicting persistent device identifier.Error object
401Missing or invalid API key (Authorization, X-API-Key or, from a browser, the ordermap.key. subprotocol).Error object
403The plan has no streaming (streaming_not_in_plan), the dataset is not released, or the account is suspended.Error object
409stream_connection_limit: the account is already connected on another device, or already has this event type open on the active device. The existing connection is preserved.Retry-AfterError object
426The request is not a WebSocket upgrade.Error object
429Rate limit or WebSocket cooldown.Retry-AfterError object
503stream_unavailable: the stream is not enabled or its source is down; retry after Retry-After seconds.Retry-AfterError object

Authenticated responses carry the X-RateLimit-* headers (see rate limits); 429 and 503 add Retry-After.