DpExchange.Webull.Subscription (DpExchangeWebull v0.1.1)

Copy Markdown View Source

The HTTP half of subscribing — internal.

Webull steers an MQTT stream with REST calls. POST /openapi/market-data/streaming/subscribe names the session_id that the MQTT connection registered as its client id, and the broker begins publishing to that session.

Split across two protocols like this, the failure modes are unusual and worth naming:

  • A 200 here does not mean data is arriving. It means the venue accepted the request. Whether anything is published depends on the MQTT session being up and carrying the same id. That is why coverage/1 reports only what arrived — on this venue, "asked", "accepted" and "delivering" are three different moments.
  • A session id mismatch fails silently in the most expensive way: the HTTP call succeeds, the broker publishes to a session nobody is listening on, and the socket sits connected and idle. There is no error anywhere. One generated id, used for both, is the only defence.

Every call is signed — this venue has no anonymous endpoints.

Summary

Functions

Starts publication for symbols on the MQTT session registered under session_id.

Stops publication for symbols.

Functions

subscribe(session_id, symbols, opts)

@spec subscribe(String.t(), [String.t()], keyword()) :: :ok | {:error, term()}

Starts publication for symbols on the MQTT session registered under session_id.

An empty symbol list is :ok without a request: asking the venue to subscribe to nothing spends a call from a budget this venue is already the tightest on.

unsubscribe(session_id, symbols, opts)

@spec unsubscribe(String.t(), [String.t()], keyword()) :: :ok | {:error, term()}

Stops publication for symbols.