DpExchange.Webull.Environment (DpExchangeWebull v0.1.1)

Copy Markdown View Source

Which Webull this package is talking to — production, or the UAT environment.

This venue's demo story is only half a story, and that half matters

Gemini's demo environment is a complete parallel exchange: REST and streaming both. This one is not.

ProductionUAT
RESTapi.webull.comus-openapi-alb.uat.webullbroker.com
Streamingwss://data-api.webull.com:8883/mqttnone

The prior adapter records the measurement that establishes it: mqtt-uat.webullbroker.comNXDOMAIN. There is no UAT broker to connect to, and no amount of configuration produces one.

So environment: :uat gives a consumer authenticated REST against test data and no live stream at all. That is a genuinely useful thing — order placement and account calls can be exercised without money — and it is also a trap if a package pretends otherwise. subscribe/2 in UAT does not silently fall back to production, because a consumer testing against UAT who received production prices would be reading real market data while believing it was fake. It refuses.

streaming?/1 exists so a caller can ask before it commits, rather than discovering the gap from a subscription that never delivers.

Resolution order

  1. an explicit :environment in the call's options — wins always
  2. DpExchange.Core.Config, which resolves per process, so one async test or one strategy runner can sit in UAT while its neighbours do not
  3. :production

Production is the default and an unrecognised value raises. A typo must not quietly resolve to production: the failure is asymmetric, since meaning UAT and getting production sends a real order to a real broker.

Summary

Functions

REST hostname without a scheme.

Every environment this package knows.

Whether this environment moves real money.

The environment in force for these options.

REST base URL, with scheme.

Whether this environment has a live stream at all.

The MQTT-over-WebSocket URL, or nil where the venue offers none.

Types

t()

@type t() :: :production | :uat

Functions

host(environment)

@spec host(t()) :: String.t()

REST hostname without a scheme.

Separate from rest_url/1 because the host participates in the signature — Webull signs it so a signature cannot be replayed against another environment. A caller needs both, and they must agree.

known()

@spec known() :: [t()]

Every environment this package knows.

live?(atom)

@spec live?(t()) :: boolean()

Whether this environment moves real money.

resolve(opts \\ [])

@spec resolve(keyword()) :: t()

The environment in force for these options.

rest_url(environment)

@spec rest_url(t()) :: String.t()

REST base URL, with scheme.

streaming?(environment)

@spec streaming?(t()) :: boolean()

Whether this environment has a live stream at all.

Asked before subscribing, so a consumer learns the answer from a question rather than from a subscription that never delivers.

streaming_url(environment)

@spec streaming_url(t()) :: String.t() | nil

The MQTT-over-WebSocket URL, or nil where the venue offers none.

nil is the honest answer for UAT and is not a configuration gap to fill in.