MarketLab Docs
Strategies

TWAP

Execute a parent order through time-weighted child orders on BULK.

TWAP

TWAP, or Time-Weighted Average Price, divides one parent order into smaller child orders and submits them at a fixed cadence. It is an execution strategy: you choose the side and amount; TWAP controls the schedule.

Market Lab's current TWAP implementation executes on BULK and uses market child orders.

TWAP can place real orders. Market child orders prioritize execution and can experience slippage. Always inspect the dry-run plan first.

Preview a TWAP

mlab strategy run twap BTC/USDT \
  --exchange bulk \
  --side buy \
  --margin 100 \
  --leverage 10 \
  --duration 300 \
  --interval 60 \
  --dry-run

A dry run:

  • obtains the current BULK reference price
  • multiplies --margin by --leverage to create the target exposure
  • converts that exposure into a lot-aligned total size
  • calculates the number and size of child orders
  • validates every child against the market's minimum notional
  • prints the complete strategy plan
  • does not create a job or submit an order

The estimated margin and exposure can be slightly lower than requested because size is floored to the market's lot size.

Scheduling Logic

The child count is:

ceil(duration / interval)

The normalized total size is divided across that many children. Distribution is performed in whole market lots, and any remainder lots are distributed without losing or exceeding the parent size.

For this configuration:

duration = 300 seconds
interval = 60 seconds

TWAP creates five child orders scheduled at approximately:

0s, 60s, 120s, 180s, 240s

The first child is submitted immediately. The remaining children are submitted once per interval. Together, the five scheduled buckets cover the 300-second execution window.

--duration defines how long the parent execution is spread across. --interval defines how frequently a child is submitted. An interval alone cannot determine when the parent order should finish.

Submit a Live Job

Remove --dry-run to submit the strategy:

mlab strategy run twap BTC/USDT \
  --exchange bulk \
  --side buy \
  --margin 100 \
  --leverage 10 \
  --duration 300 \
  --interval 60

Terminal mode prints the normalized plan and asks once for confirmation. After confirmation, mlab submits the immutable TWAP definition to mlabd, prints the job ID, and returns immediately. Closing the terminal does not stop the strategy.

Use --yes for non-interactive execution:

mlab strategy run twap BTC/USDT \
  --exchange bulk \
  --side sell \
  --size 0.01 \
  --duration 600 \
  --interval 30 \
  --yes \
  --output json

Structured live output requires --yes because JSON and JSONL modes cannot display an interactive confirmation prompt.

Arguments

ArgumentRequiredMeaning
SYMBOLYesMarket Lab symbol such as BTC/USDT
--exchangeNoExecution exchange; currently bulk and defaults to bulk
--sideYesParent side: buy or sell
--sizeOne amountTotal base-asset size
--marginOne amountTotal quote collateral; multiplied by leverage at deployment
--durationYesTotal execution window in seconds
--intervalNoSeconds between child orders; defaults to 60
--leverageNoLeverage applied to each child; defaults to 1
--reduce-onlyNoMarks every child as reduce-only
--dry-runNoPrint the plan without creating a job
--yesNoSkip the live terminal confirmation
--outputNoterminal, json, or jsonl

Set exactly one of --size or --margin.

When --margin is used, Market Lab multiplies it by leverage and resolves the resulting exposure to a fixed, lot-aligned parent size before the job is created. Later price changes affect the realized exposure of each market child, but they do not change the persisted target size.

Monitor the Job

The submission response includes a strategy job ID:

strategy_...

Use it to manage the detached worker:

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

strategy logs contains:

  • the normalized TWAP plan used by the worker
  • one strategy.child_order record per submitted child
  • the venue order ID and submission status
  • a final strategy.run.finished summary
  • a strategy.run.failed record when execution cannot continue

Job statuses are starting, running, stopping, stopped, completed, and failed.

Stop Behavior

Stopping a TWAP prevents future child orders. It does not reverse filled children or close the resulting position.

mlab strategy stop <JOB_ID>

Every child submission includes its job ID and sequence. mlabd atomically verifies that the job is still active, that children arrive in order, and that each child size matches the persisted schedule. A child submitted after the job has stopped is rejected.

TWAP has no restart command. If a stopped job filled only part of the parent amount, inspect the job logs and account fills, calculate the desired remainder, and submit a new TWAP explicitly.

Market and Limit Execution

TWAP itself does not require market orders; a TWAP trajectory can use either market or limit children. Market Lab currently implements only market-child TWAP.

The following are not currently accepted by strategy run twap:

  • --type limit
  • --price
  • --tif

Limit TWAP requires additional lifecycle rules for resting orders, partial fills, cancellation, and the unfilled amount at expiration. Those semantics will be documented when limit-child TWAP is implemented. Market Lab will not silently treat a requested limit price as a market order.

Failure Behavior

The job stops and becomes failed when a child cannot be planned or submitted. Previously filled children remain filled; Market Lab does not roll them back.

Common validation failures include:

  • total size is not aligned with the BULK lot size
  • the schedule creates more children than available lots
  • an individual child is below the market minimum notional
  • requested leverage exceeds the market maximum
  • authentication is missing or no longer matches the configured BULK account

Inspect both the job and its logs after a failure:

mlab strategy status <JOB_ID>
mlab strategy logs <JOB_ID>
mlab fills --symbol BTC/USDT

On this page