DpExchange.Robinhood (DpExchangeRobinhood v0.1.1)

Copy Markdown View Source

Robinhood Crypto, behind the DpExchange facade.

⚠️ EXPERIMENTAL

This package has not run in production. While it is 0.x the API may change without a major version — pin all three segments. Maturity is declared per endpoint through capabilities/0; do not read this banner as your check.

This module is the entire public API of this package.

This venue has no streaming API, and you cannot tell

Robinhood Crypto publishes no socket. subscribe/2 is served by a REST poll inside this package, and it delivers the same Core.Types.Quote to the same subscriber as a WebSocket venue would.

That is the sharpest test in the family of §6.0's claim that both endpoints always exist and a consumer never branches on transport. Before the facade, the absence travelled upward: the collection layer kept a poll set and decided which venues were exempt, and an operations page described these pairs in terms of a socket the venue does not have and has never claimed — sending readers hunting a streaming fault that cannot exist.

coverage/1 reports :internal_poll rather than :stream, which is the one place the difference is visible — and it is visible as what is arriving, never as how.

Credentials are required for market data

Every Robinhood Crypto call is signed with an Ed25519 key, including the quotes. There is no anonymous endpoint, so get_price/2 takes credentials:

{:ok, quote} = DpExchange.Robinhood.get_price("BTC-USD", credentials: %{
  api_key: "…", private_key: "…"
})

You hold the credentials; this package signs one request with them and keeps nothing.

The price is the ask

best_bid_ask returns the prices a taker would actually get. Where the venue sends no separate price, the ask is used — a real quoted number, and the one a buyer pays. It is not a mid and not a last trade, so a series built from it sits a spread above a mid-based series from another venue. bid and ask are both carried; what a price means is your decision, not this package's.

No candles, no order book, no volume

The venue publishes none of them. get_historical_prices/4, get_order_book/2 and volume are :unsupported — the venue's shape, not a gap here. Route that work elsewhere rather than discovering an empty series.

Supervision

children = [{DpExchange.Robinhood, credentials: my_credentials(), symbols: ["BTC-USD"]}]

Summary

Functions

The quote currencies this venue settles in.

Endpoints the venue does not serve, as distinct from ones this package has not ported.

Functions

quotes()

@spec quotes() :: [String.t()]

The quote currencies this venue settles in.

venue_does_not_serve()

@spec venue_does_not_serve() :: [{atom(), arity()}]

Endpoints the venue does not serve, as distinct from ones this package has not ported.

Both answer {:error, :not_supported}, and a caller acts the same way on either — but they mean different things to anyone deciding what to build next, so they are told apart here rather than flattened into one list.