Skip to content

futures.public_liquidates: result shape and timestamp field differ from docs, size sign undocumented #132

Description

@karudo

Docs page: https://www.gate.com/docs/developers/futures/ws/en/#public-liquidate-order-notification

The live futures.public_liquidates feed does not match its documentation in three ways, and the gateio/gatews Python SDK has no channel class for it at all (that repo is archived, so reporting here). All four points are reproducible; raw frames are included below.

Endpoint: wss://fx-ws.gateio.ws/v4/ws/usdt, subscribed by contract name (300 contracts per shard). Frames captured 2026-08-10.

{"time":1786327033,"time_ms":1786327033532,"channel":"futures.public_liquidates","event":"update","result":{"contract":"HEI_USDT","price":"0.13827","time":1786327033531,"size":-23}}
{"time":1786327035,"time_ms":1786327035702,"channel":"futures.public_liquidates","event":"update","result":{"contract":"HEI_USDT","price":"0.13761","time":1786327035701,"size":-9}}
{"time":1786327040,"time_ms":1786327040873,"channel":"futures.public_liquidates","event":"update","result":{"contract":"LAB_USDT","price":"0.11824","time":1786327040872,"size":-9}}

1. result is a bare object, not an array

The docs type result as Array ("Array of objects") and the example shows "result": [{...}]. Every frame observed carries a bare object. A client written to the documented shape breaks on the first message.

2. The timestamp field inside result is time, not time_ms

The parameter table for the notification lists time_ms (Integer, "time_in_milliseconds"). The live object carries time, holding a millisecond value.

Note this is specifically about the result object — the envelope does have time_ms, so the mismatch is easy to miss when skimming. Observed keys:

  • envelope: time, time_ms, channel, event, result
  • result: contract, price, time, size

Whichever side is authoritative, the two disagree today, and a client that reads only the documented name gets undefined on every row.

3. The sign of size is not documented

size is described only as "liquidate order quantity"; the example shows -124 with no explanation of the sign. This is the single most important field in the feed — it decides whether an event is a short being liquidated or a long — and the documentation does not say.

Determined empirically over 1008 events across 184 contracts:

  • size > 0 → short liquidation (forced buy). Price moved +1.58% in the two minutes before the event; only 9% of these events had falling price beforehand (n=387).
  • size < 0 → long liquidation (forced sell). Price moved −1.15% before; 93% had falling price (n=614).

Cross-checked against the exchange's own 5-minute rollup in futures.contract_stats: in five-minute buckets where it reported short liquidations only, 84% of granular volume was positive; where it reported longs only, 10% was.

Please state the convention in the docs so clients do not each have to measure it.

4. The Python SDK has no channel class for futures.public_liquidates

In gateio/gatews, python/gate_ws/futures.py defines FuturesLiquidatesChannel (futures.liquidates, authenticated) but nothing for the public channel, which was added on 2025-02-19 per the WS changelog. Users of the SDK have to bypass it to subscribe.

Aside

futures.liquidates returns authentication required for Channel futures.liquidates when subscribed without credentials, which is correct and expected — noting it only because the two channel names are one word apart and it is easy to reach for the wrong one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions