MarketDeck docs

spot

Spot trading on every registered exchange — read paths, write paths, and a venue-neutral CLI surface.

marketdeck spot is the spot-trading sibling of the perp-oriented wallets command. It exposes the same buy / sell / cancel / balances surface for every exchange that has a spot module — currently Hyperliquid, Aster, Bybit, and Binance.

The command is venue-neutral: pick a wallet (or --exchange ID for read-only paths) and the same subcommand works on every exchange. The wire-level differences — Bybit's category=spot, Binance's separate api.binance.com/api/v3/..., Aster's sapi.asterdex.com host, Hyperliquid's 10000+spotIdx asset id — all live inside exchanges/<id>/spot.js.

Usage#

marketdeck spot <subcommand> [args]

Subcommands#

SubcommandWhat it does
markets <exchange>Every spot pair on the venue with last price, 24h change, USD volume. Sorted top-20 by volume in text mode.
price <exchange> <symbol>Last price for one pair. <symbol> accepts the bare base coin (BTCBTCUSDT) or the full pair (ETHUSDC, PURR/USDC).
balances <wallet>Non-zero spot balances on the wallet's exchange. Sorted by total descending.
orders <wallet> [--symbol S]Open spot orders.
trades <wallet> --symbol SFill history. --symbol is required because every CEX API scopes per-pair.
`buy <wallet> <symbol> <qty> [--price P] [--quote] [--tif GTC\IOC\FOK] [--dry-run]`Market or limit buy. --dry-run returns the order plan without placing it.
`sell <wallet> <symbol> <qty> [--price P] [--tif GTC\IOC\FOK] [--dry-run]`Market or limit sell.
cancel <wallet> <symbol> <orderId>Cancel one order by id.

Symbol resolution#

Every exchange's spot.coinToSymbol accepts either:

  • a bare base coin (BTC) — the CLI appends the default quote (USDT) automatically.
  • a full pair symbol (BTCUSDT, ETHUSDC, BNBBTC).

Hyperliquid is the exception: its pair names are slash-separated (PURR/USDC) and non-canonical pairs are @<index>-encoded. A bare PURR resolves to the canonical pair (PURR/USDC) via the spot universe lookup.

Buy semantics#

For a market BUY, <qty> defaults to base-asset units (buy 0.001 BTC). Pass --quote to switch it to quote-asset units (buy 100 USDT worth of BTC). Limit BUY always uses base-asset units.

For market SELL, <qty> is always base-asset units — Bybit and Binance reject quote-denominated market sells, and silently quoting them would be a foot-gun.

Examples#

marketdeck spot markets binance | head
marketdeck spot price hyperliquid PURR/USDC

marketdeck spot balances main-bybit                         # signed read
marketdeck spot orders main-binance --symbol BTCUSDT
marketdeck spot trades main-binance --symbol BTCUSDT --limit 50

marketdeck spot buy  main-bybit  BTC 0.001                  # market buy in BTC
marketdeck spot buy  main-bybit  BTC 100 --quote            # market buy 100 USDT
marketdeck spot buy  main-bybit  BTC 100 --quote --dry-run
marketdeck spot buy  main-binance BTCUSDC 0.001 --price 60000 --tif GTC
marketdeck spot sell main-bybit  BTC 0.001 --price 80000

marketdeck spot cancel main-bybit BTCUSDT 1234567890

Adapter contract#

Each exchange exposes a spot sub-namespace via its adapter object:

const adapter = getExchange('binance');
await adapter.spot.listMarkets();
await adapter.spot.markPriceFor('BTC');
await adapter.spot.balances(creds);
await adapter.spot.marketOrder({creds, symbol: 'BTCUSDT', side: 'buy', qtyBase: 0.001});

The methods are intentionally a strict subset of what the perp surface exposes — no leverage, no margin-type, no SL/TP brackets, no funding. Everything that doesn't apply to a cash spot trade just isn't there.

Paper wallets#

Paper wallets settle in-process against the paper-spot engine (core/paper-spot.js, SQLite-backed in paper_spot_balances / _orders / _trades). The same marketdeck spot subcommands work on paper wallets — branching is by wallet.type, not a separate command. start_balance materialises as the wallet's initial USDT row on first interaction.

Mechanics:

  • Market orders settle immediately at markPrice * (1 ± slippage_bps/10_000). Slippage + taker fee share the GSettings keys (paper-slippage-bps, paper-taker-fee-bps) the perp paper engine uses.
  • Limit orders insert with status open and ride the daemon's paper-tick loop (paper-tick-seconds, default 15s). Once mark crosses the limit price the fill applies the maker fee (paper-maker-fee-bps).
  • Price source — defaults to Binance spot (broadest USDT coverage). Override per call with --exchange bybit|hyperliquid|aster.
  • Cancel flips the row's status to cancelled.

Failure modes that surface as exit code 3:

  • insufficient USDT (have X, need Y) — buy notional + fee exceeds the wallet's USDT balance.
  • insufficient <BASE> — sell quantity exceeds the asset balance.
  • no mark price for <SYMBOL> — the picked exchange's universe doesn't list the pair.
marketdeck spot buy  paper-demo BTC 0.001                    # market buy in BTC
marketdeck spot buy  paper-demo BTC 100 --quote              # market buy 100 USDT
marketdeck spot buy  paper-demo BTCUSDT 0.001 --price 50000  # limit buy
marketdeck spot buy  paper-demo BTC 0.0001 --exchange bybit  # use Bybit spot price
marketdeck spot orders paper-demo
marketdeck spot trades paper-demo
marketdeck spot cancel paper-demo BTCUSDT 42

What it does NOT do (yet)#

  • Cross-venue spread / funding-arb. The spot adapters surface listMarkets() so a future markets spot-spread can compute it; not built yet.