Skip to content
Version v0.4 (draft)
ChangelogContributing

Reference

Venue adapter contract

The contract between an executor and one venue.

An executor talks to venues through adapters. In the reference implementation this is a gRPC service, Venue; every request names a venue, and one adapter process may serve several. The adapter decides nothing.

Operation Contract
Health Is the venue usable now (credentials loaded, venue reachable)? Checked before a send.
Capabilities Order types with the times in force allowed for each; v0.4 asset_classes (per asset class: order types, order classes with their times in force, notional times in force, replace, extended_hours, max_legs, exercise, and venue features such as Hyperliquid position_tpsl); per-instrument lot_size, tick_size, max_price_decimals, max_price_sig_figs, min_qty, min_notional, quote_currency; reduce_only support; network (for example testnet). A venue difference lives in this declaration, not in the executor.
Quote Read-only price for an instrument.
Submit Send one order. Outcomes: ack (with status and any fills), reject (definitive, nothing placed), timeout (ambiguous: the venue may have it; the order moves to unknown), not_configured (definitive local failure).
Cancel Cancel by client order id (a group: its open exits too). The executor confirms against a snapshot.
Replace v0.4. New terms for a working simple order (old_replaced when the venue replaced it synchronously).
Act v0.4. exercise or do_not_exercise an option position.
Snapshot Status and fills for watched client order ids, ids the venue does not know (missing_ids), external fills, and complete. An incomplete snapshot never counts as missing.
Balances Cash for the account, or supported=false.
ListInstruments Every instrument the venue lists, normalized: symbol, display name, asset_class, product_class, quote_currency, lot_size, tick_size, max_price_decimals, shortable, fractionable, status (active, halted, delisted); or supported=false. Read-only. The authorizer syncs its instrument list from it and marks a symbol the venue stops listing as delisted.
Activities Non-trade account activity since a time (dividends, interest, fees, transfers, option exercise, assignment and expiry). The executor forwards it to the authorizer, which records each event once and applies cash items when the venue account belongs to one user.
  • The client order id is the idempotency key and the reconciliation key. It is minted by the authorizer (co_ plus 32 hex characters) and never reused. If the venue needs a different format, derive it deterministically.
  • Never round or change a signed price or quantity. If the venue cannot accept it, reject. A protective limit for a market order is computed only on venues that have no native market order and need one (for example Hyperliquid, which sends an IOC limit at the protect price). The protect price is the signed reference moved by the signed collar, rounded toward the safe side. A venue with native market orders (for example Alpaca) receives a plain market order; the guard there is the authorizer’s pre-send checks on the signed reference price (staleness, collar, and the notional and buying power reserved at reference plus collar).
  • When unsure whether an order reached the venue, answer timeout, not reject.
  • Map, never downgrade. Translate a time in force or order type to the venue’s spelling, or reject it. Never coerce an unsupported combination into a supported one, and never declare a combination the venue would itself coerce.
  • Money is a decimal string on the wire.
  • Test hooks belong in a separate service, not in the venue contract.

The first venue with a working adapter is Hyperliquid perpetuals, used on testnet. The Hyperliquid market page covers how to connect, the order path, field mapping, supported types and how failures are handled.

  • The executor’s adapter signs with a Hyperliquid API wallet that the user’s main account approved. An API wallet can trade but cannot withdraw. The agent never sees it.
  • client_order_id maps to Hyperliquid’s cloid as 0x followed by the first 16 bytes of sha256(client_order_id).
  • Time in force: gtc to Gtc, ioc to Ioc, post_only to Alo. fok and day are refused. Market orders must be ioc and are sent as an IOC limit at the protect price.
  • Precision: size is a multiple of 10^-szDecimals; prices have at most 5 significant figures (integers always allowed) and at most 6 - szDecimals decimals for perpetuals. Minimum order value is 10 USDC.
  • Risk treatment: perpetuals can be long or short. An order that carries leverage has it set on the venue first (rejected if the venue refuses it). An order without leverage trades at the account’s current setting, which the adapter leaves alone; the authorizer reads that setting to cap and reserve by it. Funding and liquidation are not modeled.
  • v0.4 forms (asset class crypto): stop and stop_limit go out as trigger orders; bracket as one normalTpsl batch (entry, then reduce-only take-profit and stop-loss); replace with the venue’s modify (the old order is replaced at once). A stop without a limit carries the venue’s own TP/SL market slippage tolerance (10% past the trigger). The venue has no notional orders or options; its trailing stop and TWAP are not implemented in the adapter yet, and oto / oco are not mapped. Position-level TP/SL is not an OCO and is only declared as the feature position_tpsl.

Alpaca is connected for US stocks and ETFs, listed options and crypto, used on paper. Credentials are per account and never held by the agent.

  • Stocks and ETFs: market and limit with day, gtc, ioc, fok, opg and cls (opg only around the opening auction, cls only before the closing auction); stop, stop_limit and trailing_stop with day/gtc; bracket, oto and oco with day/gtc; notional market orders with day; replace; extended_hours on simple limits with day or gtc. Quantities up to 9 decimals; limit and stop prices at most 2 decimals at $1.00 or more and 4 below. Fractional quantities need day. A venue refusal for a potential wash trade is definitive: use a bracket or oco instead of two opposing simple orders.
  • Options: market day, limit day/gtc, stop and stop_limit day, mleg day (up to 4 legs), exercise and do_not_exercise (the latter only on the expiry day).
  • Crypto: pairs quoted in USD, USDT or USDC (for example BTC/USD). market and limit with gtc/ioc, stop_limit gtc, notional gtc/ioc, no replace.
  • Fills are reported once per order, aggregated, when the order is done at the venue. A group’s exits and legs are their own fills, with their instrument and side. A partially filled GTC order is booked when it ends.
  1. Implement the operations above, with unit tests against a fake client and no network.
  2. Keep it off by default behind configuration; secrets go only to the adapter’s environment.
  3. Seed reference data for the protected unit (order types, times in force, min and max notional) and the calendar. Instruments (lot, tick, quote currency, status) come from ListInstruments.
  4. If the product class is new, add its risk treatment first. Until then the authorizer fails closed (A2M_UNSUPPORTED_PRODUCT).
  5. Check quotes and metadata against the venue’s test network before any order.