MarketLab Docs

Execution

Plan, simulate, submit, and monitor BULK trades through Market Lab.

Execution

Market Lab has two execution entry points:

  • CLI commands for explicit operator-driven orders
  • ctx.trade and ctx.cancel for deployed strategy scripts

Both use the same validation and BULK adapter. Live mutations are signed and serialized inside mlabd.

Live execution can place real orders. Use --dry-run for CLI orders and script backtest for strategy scripts before enabling live execution.

Requirements

Execution requires:

  • a BULK account
  • an active BULK agent created with mlab auth set bulk
  • a symbol in the embedded BULK market catalog
mlab auth status
mlab daemon status

The main wallet private key is used only to authorize or revoke the agent. Market Lab stores the agent credential in the operating system keychain and loads it only inside mlabd for live signing.

Dry Run

mlab trade long BTC/USDT --notional 10 --dry-run

A dry run:

  • resolves the configured BULK account
  • obtains a reference price for market orders
  • normalizes size from --size or --notional
  • validates embedded market rules
  • prints the complete TradePlan
  • does not sign, submit, or start mlabd

Place an Order

mlab trade long BTC/USDT --notional 100 --leverage 5
mlab trade short BTC/USDT --size 0.001 --leverage 3

Terminal mode prints the normalized plan and asks for confirmation. Structured live output requires --yes because it cannot prompt:

mlab trade long BTC/USDT --notional 100 --yes --output json

Every order must specify exactly one of --size or --notional. Explicit size must align with the market lot size. A notional order is converted to size and floored to that lot size.

Market and Limit Orders

Market order:

mlab trade long BTC/USDT \
  --notional 100 \
  --type market \
  --dry-run

Limit order:

mlab trade short BTC/USDT \
  --size 0.001 \
  --type limit \
  --price 65000 \
  --tif alo \
  --dry-run

Limit time-in-force values:

  • gtc: good until cancelled
  • ioc: immediate or cancel
  • alo: add liquidity only

--price and non-default --tif are valid only for limit orders. Limit prices must align with the embedded tick size.

Native Protection

Attach a stop loss, take profit, or both:

mlab trade long BTC/USDT \
  --notional 100 \
  --leverage 5 \
  --sl 63000 \
  --tp 69000 \
  --dry-run

BULK protection is signed in the same transaction as the parent:

  • --sl creates a native stop action
  • --tp creates a native take-profit action
  • both create a native OCO range
  • protection activates after the parent fills
  • one OCO trigger cancels its sibling

Market Lab does not poll prices to emulate protection. Trigger prices must align with the tick size and be on the correct side of the entry. Protection cannot be attached to a reduce-only order.

Leverage and Reduce Only

mlab trade long BTC/USDT \
  --notional 100 \
  --leverage 5 \
  --reduce-only \
  --dry-run

Leverage starts at 1 and cannot exceed the embedded market maximum. --reduce-only is passed into the signed BULK order.

Account State

mlab positions
mlab orders
mlab fills

Filter to one Market Lab symbol:

mlab positions --symbol BTC/USDT --output json
mlab orders --symbol BTC/USDT --output json
mlab fills --symbol BTC/USDT --output json

These are read-only BULK account requests and do not start mlabd.

Cancel and Close

mlab cancel BTC/USDT <ORDER_ID> --dry-run
mlab cancel BTC/USDT <ORDER_ID>

Close creates a reduce-only market order in the opposite direction for the complete position size:

mlab close BTC/USDT --dry-run

The symbol is optional in interactive terminal mode. Pass it explicitly for structured output or non-interactive use when several positions exist.

Script Execution

Strategy scripts use the same normalized execution request:

const order = ctx.trade({
  key: `entry-${candle.t}`,
  side: 'long',
  notional: 100,
  leverage: 5,
  order: { type: 'market' },
  sl: 63000,
  tp: 69000,
})
  • script backtest intercepts this call with the historical simulator.
  • script run keeps execution disabled.
  • script run --venue bulk routes it to live BULK execution through mlabd.

Returned script signals and intents do not place live orders. See Script Execution for request fields, idempotency, cancellation, jobs, and onExecution.

Runtime

Live CLI orders and deployed script jobs use the persistent mlabd process. It owns:

  • agent-key access and signing
  • nonce sequencing
  • order and cancellation submission
  • script job and idempotency state
  • order correlation and event delivery
  • the BULK account WebSocket

The runtime starts automatically when a live command or script job needs it and remains active until stopped.

mlab daemon start
mlab daemon status
mlab daemon events --limit 20
mlab daemon stop

Runtime files live under:

~/.market-lab/execution/
  mlabd.sock
  runtime.json
  events.jsonl
  mlabd.log
  jobs/

The runtime directory is owner-only (0700) and the Unix socket is owner-only (0600).

Account WebSocket

mlabd subscribes to BULK account events instead of polling REST on a timer.

The stream provides:

  • initial account state
  • order updates and fills
  • position and margin changes
  • liquidations and ADL events
  • cancellation failures

The daemon reconnects with bounded backoff after a disconnect. Once reconnected, it performs one REST order-history and fill recovery for the disconnected interval, then resumes WebSocket-driven state. No scheduled REST reconciliation runs while the stream is healthy.

mlab daemon status reports:

  • account stream connection state
  • last account event timestamp
  • last gap recovery timestamp
  • tracked open-order count
  • active script-job count
  • last runtime error

Runtime Events

Inspect the global runtime journal:

mlab daemon events --limit 20 --output jsonl

It includes CLI submission and tracking events such as:

  • order_submitted
  • order_cancelled
  • order_tracking_started
  • order_status
  • account_ws
  • account_recovery_fill

Deployed script execution has a per-job event journal delivered through onExecution. Inspect the script’s combined output with:

mlab script logs <JOB_ID> --follow --output jsonl

TOML Configuration

version = 1

[market]
symbol = "BTC/USDT"

[execution]
venue = "bulk"
notional = 100
order_type = "market"
leverage = 5
sl = 63000
tp = 69000
reduce_only = false
dry_run = true
yes = false

[output]
format = "terminal"
mlab trade long --config marketlab.toml

CLI values override TOML values. Do not put wallet keys or agent credentials in TOML.

Validation Boundary

Before signing, Market Lab rejects:

  • unknown or non-trading markets
  • unsupported order types or time-in-force values
  • size values not aligned with lot size
  • limit or protection prices not aligned with tick size
  • invalid stop-loss or take-profit direction
  • estimated notional below the market minimum
  • leverage above the market maximum
  • protection attached to reduce-only orders
  • mismatched symbols, accounts, or cancel order IDs

Market rules come from the versioned BULK snapshot embedded in the binary:

mlab markets --provider bulk --symbol BTC/USDT

BULK References

On this page