Market LabDocs

Execution

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

Execution

Market Lab has three execution entry points:

  • CLI commands for explicit operator-driven orders
  • native execution strategies such as TWAP
  • ctx.trade and ctx.cancel for deployed strategy scripts

All three 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 built-in strategies, and use 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 --margin 10 --dry-run

A dry run:

  • resolves the configured BULK account
  • obtains a reference price for market orders
  • multiplies --margin by --leverage to obtain exposure, then normalizes the resulting size
  • validates embedded market rules
  • prints the complete TradePlan
  • does not sign, submit, or start mlabd

Place an Order

mlab trade long BTC/USDT --margin 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 --margin 100 --yes --output json

Every order must specify exactly one of --size or --margin. Explicit size is the exact base-asset exposure and must align with the market lot size. Margin is quote collateral: Market Lab multiplies it by leverage, converts that exposure to size, and floors the size to the market lot.

For example, --margin 100 --leverage 10 targets approximately $1,000 of exposure. Lot-size flooring can make the final margin and exposure slightly smaller.

Market and Limit Orders

Market order:

mlab trade long BTC/USDT \
  --margin 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 \
  --margin 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 \
  --margin 100 \
  --leverage 5 \
  --reduce-only \
  --dry-run

Leverage starts at 1 and cannot exceed the embedded market maximum. Market Lab sets BULK's leverage for the symbol before submitting the calculated exposure. --reduce-only is passed into the signed BULK order.

BULK uses cross portfolio margin, so it cannot provide an exact liquidation price before execution from margin and leverage alone. The plan marks projected liquidation as unavailable; after a fill, Market Lab reports the liquidation price returned by BULK for the resulting position.

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}`,
  position: 'open-long',
  margin: 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.

Script hooks do not return signals or intents; those fields are rejected. See Script Execution for request fields, idempotency, cancellation, jobs, and onExecution.

Built-In Strategies

Native strategies submit supervised jobs to mlabd. For example, preview and then deploy a TWAP:

mlab strategy run twap BTC/USDT --side buy --margin 100 --duration 300 --interval 60 --dry-run
mlab strategy run twap BTC/USDT --side buy --margin 100 --duration 300 --interval 60

The live command returns a job ID instead of holding the terminal open:

mlab strategy status <JOB_ID>
mlab strategy logs <JOB_ID> --follow
mlab strategy stop <JOB_ID>

See Strategies and TWAP.

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 and native-strategy job 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
  • active strategy-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

Native strategy plans, child submissions, and completion summaries are stored separately:

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

TOML Configuration

version = 1

[market]
symbol = "BTC/USDT"

[execution]
venue = "bulk"
margin = 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 exposure below the market minimum notional
  • 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 --exchange bulk --symbol BTC/USDT

BULK References

On this page