Skip to content

Automation with CommandClient & MM Bot Tuning

Objective

Use EduMatcher's programmatic command client for repeatable admin workflows and practice advanced pm-mm-bot runtime tuning for startup and reconciliation.

Pre-reading in the User Guide

Prerequisites

  • Chapters 01-20 completed.
  • Engine running with GW_ADMIN and at least one MM gateway configured.
  • Python environment able to import edumatcher.commands.

Background

The interactive tools are excellent for manual operation, but production-like operations often require deterministic automation:

  • One-shot operator runbooks (halt/resume, symbol cleanup, gateway checks).
  • Repeatable incident actions with explicit timeouts.
  • MM bot tuning for startup reliability in sparse-book conditions.

This chapter combines two advanced surfaces:

  1. ExchangeCommandClient (programmatic admin command API).
  2. Advanced pm-mm-bot runtime flags such as bootstrap timeout and QLEGS reconciliation interval.

Exercise 1: Run a Minimal CommandClient Session

Execute a short Python script:

python - <<'PY'
from edumatcher.commands import ExchangeCommandClient

with ExchangeCommandClient("GW_ADMIN") as client:
    auth = client.connect()
    print("auth:", auth)
    symbols = client.symbol_list()
    print("symbols:", symbols)
    state = client.session_status()
    print("session:", state)
PY

Checkpoint: you can connect, read symbols, and read session status programmatically.

Exercise 2: Script a Safe Symbol-Protection Runbook

Run a scripted sequence:

python - <<'PY'
from edumatcher.commands import ExchangeCommandClient

with ExchangeCommandClient("GW_ADMIN") as c:
    c.connect()
    c.symbol_halt("AAPL")
    c.cancel_symbol("AAPL")
    book = c.book_depth("AAPL")
    print("AAPL bids:", len(book.get("bids", [])), "asks:", len(book.get("asks", [])))
    c.symbol_resume("AAPL")
    print("AAPL resumed")
PY

This is easier to run consistently than a manual multi-step console sequence.

Checkpoint: you can automate halt/cancel/verify/resume for one symbol.

Exercise 3: Automate Gateway Exposure Cleanup

Use API methods to clear one participant and verify no resting orders remain:

python - <<'PY'
from edumatcher.commands import ExchangeCommandClient

target = "TRADER02"

with ExchangeCommandClient("GW_ADMIN") as c:
    c.connect()
    c.kill_switch(target)
    orders = c.order_list(target)
    print("remaining orders for", target, ":", len(orders))
PY

Optional extension:

  • Add gateway_kick(target, reason=...) after kill_switch when operational policy requires immediate disconnect.

Checkpoint: you can explain when to use kill-switch only vs. kill-switch + kick.

Exercise 4: Tune pm-mm-bot Startup Reliability

Run one bot with explicit startup controls:

pm-mm-bot \
  --symbol AAPL \
  --gap 0.10 \
  --qty 500 \
  --startup-session-timeout-sec 5.0 \
  --bootstrap-timeout-sec 1.0 \
  --qlegs-reconcile-interval-sec 15.0 \
  -v

Observe startup logs for:

  • QBOOT bootstrap resolution.
  • QLEGS reconciliation status.
  • Session readiness before first quote.

Representative startup sequence:

[INFO] QBOOT reply: active_quote=None bootstrap_prices={...}
[INFO] QLEGS reconcile: symbol=AAPL state=clean
[INFO] Session state CONTINUOUS; issuing initial quote

Checkpoint: you can identify and tune the timeout knobs that control startup behavior.

These knobs apply per symbol on a --symbols bot

Every flag in this exercise — --bootstrap-timeout-sec, --qlegs-reconcile-interval-sec, --startup-session-timeout-sec, and the gap/spread validation from 02 — Setting Up Market-Maker Liquidity — is still a single process-wide value even when the bot covers several symbols with --symbols, but the QBOOT/QLEGS requests themselves, and the startup/gap checks they inform, run once per symbol. A pm-mm-bot --symbols AAPL,MSFT,TSLA -v run shows three independent [AAPL]/[MSFT]/[TSLA]-tagged QBOOT and QLEGS exchanges in the startup log, not one. If you tune --bootstrap-timeout-sec down aggressively for a fast classroom demo, remember it is one shared timeout budget applied to each symbol's QBOOT/QLEGS round trip in turn, not split across them.

Exercise 5: Empty-Book Bootstrap Drill

Simulate sparse startup conditions and run bot with explicit bootstrap range:

pm-mm-bot --symbol AAPL --initial_min 95.00 --initial_max 105.00 -v

Then compare behavior with and without range configured.

Expected understanding:

  • With range: bot can start quoting on fresh books.
  • Without any bootstrap source: bot fails fast with clear reason.

Fails fast per symbol, not necessarily for the whole process

On a --symbols bot, "without any bootstrap source" excludes that symbol from quoting rather than stopping the process outright, as long as at least one other symbol resolves a reference price — see Per-symbol failure isolation. The single-symbol case in this exercise is the special case where there is no "other symbol" left, so the process-level failure you'll observe here is the same behavior applied to a symbol set of one. --initial_min/ --initial_max are also one shared range applied independently to each symbol — with two symbols configured this way, expect two different random prices, one per symbol, both drawn from the same range.

Checkpoint: you can choose a bootstrap strategy appropriate for your environment.

Exercise 6: Build a Combined Automation Flow

Design a short automation script that:

  1. Checks session status.
  2. Halts one symbol if needed.
  3. Clears that symbol's resting orders.
  4. Resumes symbol.
  5. Verifies top-of-book depth.

Use ExchangeCommandClient methods only (no manual prompt commands).

Acceptance criteria — your script passes if all of the following hold:

  • Correct halt response: the halt call returns a success/ack response for the target symbol (not a generic exception or timeout).
  • Book actually empties: after the clear step, a book query for that symbol shows zero resting orders on both sides before you resume it.
  • Correct resume response: the resume call returns success and a subsequent SYMBOL_STATUS-style query (or equivalent client method) shows the symbol back in a tradeable state.
  • Idempotent rerun: running the entire script a second time immediately afterward produces the same end state (symbol active, book empty of the orders your script itself cleared) without raising an error — halting an already-halted symbol or clearing an already-empty book must not crash the script.
  • No orphaned state: after the script finishes, no test order placed by the script remains resting outside of what step 5 intentionally verifies.

Checkpoint: your script is deterministic, idempotent, and easy to rerun during drills, and satisfies all five acceptance criteria above.

Summary

You now have advanced operational coverage for:

  • Programmatic admin orchestration with ExchangeCommandClient.
  • Repeatable incident-response style command sequencing.
  • Practical pm-mm-bot tuning for startup/bootstrap/reconciliation behavior.

Reflection

Why does this chapter insist your automation scripts be idempotent (safe to rerun) rather than accepting "runs correctly once" as good enough? Think about an incident-response scenario at 3am — what goes wrong if an on-call engineer reruns a non-idempotent halt/clear/resume script by mistake?

Further Reading

You have completed the operator track. The remaining chapters (22–27) cover the external protocols — RALF, CALF, the REST/WebSocket API, the market index, and the ALF/BALF TCP gateways.