Market Making¶
Objective¶
Understand the QUOTE command from a human operator's perspective, explore quote lifecycle, inactivation policies, QLEGS inspection, and MM obligations.
Prerequisites¶
Add a manual MM gateway to your config:
- id: MM_MANUAL_01
description: "Manual market-maker for training"
role: MARKET_MAKER
disconnect_behaviour: CANCEL_QUOTES_ONLY
quote_refresh_policy: INACTIVATE_ON_ANY_FILL
Restart the engine and connect:
Exercise 1: Submit a Two-Sided Quote¶
Expected:
Note both leg IDs — you'll need them to identify fills.
Checkpoint: quote acknowledged and active.
Exercise 2: Inspect Quote Legs with QLEGS¶
Expected: a table showing both legs with prices, quantities, and fill status.
Representative shape:
leg_id side price qty remaining filled_qty status
ord_abc_bid_001 BUY 149.90 500 500 0 ACTIVE
ord_abc_ask_001 SELL 150.10 500 400 100 PARTIAL
How to read it:
remainingtells you what is still resting.filled_qtytells you what already executed.statushelps classify lifecycle (ACTIVE,PARTIAL,FILLED, etc.).
Checkpoint: QLEGS shows both bid and ask legs.
Exercise 3: Get Filled and Observe Inactivation¶
From TRADER01, buy into the MM's ask:
Back at MM_MANUAL_01, you should see:
Under INACTIVATE_ON_ANY_FILL, both legs are pulled after any fill.
Checkpoint: fill + sibling cancel + INACTIVE status.
Exercise 4: Re-quote After Inactivation¶
Submit a fresh quote:
Checkpoint: new quote active; QLEGS shows fresh legs.
Exercise 5: Replace a Quote Without Cancelling¶
You can replace directly — the engine handles the swap:
Expected:
Checkpoint: old quote cancelled, new quote active in one step.
Exercise 6: Explicit Cancel¶
Expected:
Note
QUOTE_CANCEL is keyed by symbol, not by quote_id.
Checkpoint: quote fully cancelled.
Exercise 7: Check Quote Bootstrap State (QBOOT)¶
After submitting a quote, inspect the bootstrap state:
This shows the current active quote slot for your gateway+symbol — useful for verifying what the engine thinks your active quote is.
Why this matters operationally: on bot restart, a previous instance might have
left an active quote in the book. QBOOT prevents blind re-quoting by showing
whether a slot is already active so the new process can adopt or replace safely
instead of creating duplicates.
Typical outcomes:
MM_MANUAL_01> QBOOT|SYM=AAPL
QBOOT SYM=AAPL active=true quote_id=Q003 bid_id=<bid_id> ask_id=<ask_id>
or
Checkpoint: QBOOT shows active quote or empty slot.
Exercise 8: Understand Inactivation Policies¶
| Policy | Behaviour |
|---|---|
INACTIVATE_ON_ANY_FILL |
Sibling cancelled on any fill (even partial) |
INACTIVATE_ON_FULL_FILL |
Sibling cancelled only when filled leg fully consumed |
NEVER_INACTIVATE |
No automatic sibling cancel; MM must manage manually |
Key Takeaways¶
- The QUOTE command creates two linked limit orders (bid + ask).
quote_ididentifies the logical quote; legs are separate order IDs.- QLEGS inspects current leg state; QBOOT inspects the active slot.
- Use QBOOT first during startup, then QLEGS for leg-level reconciliation.
- Replacement quotes don't require explicit cancel first.
order.filldoes not includequote_id— correlate via leg order IDs.
Reflection¶
Why does the engine tie the bid and ask legs of a quote together with a
quote_id at all, rather than treating a market maker's two orders as
completely independent? What could go wrong for a market maker's risk
exposure if one leg filled and the sibling stayed resting under a
NEVER_INACTIVATE policy?
Further Reading¶
- Market Making
- Market-Maker Bot (pm-mm-bot)
- Market-Maker Bot CLI Reference
- Gateway Commands
- MM Quotes Concept
- ALF Protocol Reference
Next: 10 — Combo Orders