Go-live checklist¶
Repeat this list whenever the binary, config or strategy parameters change. Operational background is in Run in production; the economics of the shipped strategies are in Economics.
The build and the strategy¶
- The release build passes its tests:
ctest --preset release. - You have run a backtest with the parameters you will use, for example
./build/release/bin/fastmm-backtest --config configs/backtest-example.toml --data syntheticwith your[strategy.params]. - It survives the simulated exchange with faults. Enable
[sim.faults]in a copy ofconfigs/sim.toml(market-data drop, order-channel drop, skipped depth update, delayed acks, rejects, rate limits; see fastmm-sim-exchange) and run./scripts/run-sim.sh --duration 5m --sim-config <your sim config>. Each ERROR line in the engine log follows from an injected fault, and the shutdown line sayscancel_all ok. - A restart restores the position:
kill -9a keyed session with a position, start it again, and check that it logsrestored positionand ends at the venue's position with no orders the dead process left (What survives a restart). - The strategy is deterministic: record a backtest with
./build/release/bin/fastmm-backtest --config <your config> --data synthetic --out - --journal-out runs/bt/session.fmjand replay it with./build/release/bin/fastmm-replay --journal runs/bt/session.fmj --verify, which must exit with code 0. - A live session replays: replay the journal of the simulator run above (the log names it,
journal: <path>) with./build/release/bin/fastmm-replay --journal <path> --verify, which must printreplay MATCHand exit with code 0 (Journals, replay and PnL). Do the same for a journal of the practice session below.
A practice session¶
- A Binance Demo or testnet session of at least 24 h with the same strategy and risk settings (Run on a testnet).
- Each ERROR line (
grep ' ERROR ' runs/demo-1/engine.log) has a known cause (Troubleshooting). - The session's PnL reconciles with the account (Journals, replay and PnL).
- Your PnL estimate includes fees (example).
Risk limits¶
A [risk] limit is off when it is 0 or missing (Configuration).
-
max_order_qtyandmax_order_notional(settlement currency: the base coin for an inverse contract). -
max_positionper instrument, which counts same-side open orders. -
max_open_ordersper instrument. -
price_collar_bpsandfat_finger_bps. -
stale_md_ms. -
max_gross_notionalandmax_net_notionalacross instruments. -
max_loss, sized to what you accept losing: the budget carries across restarts until--clear-kill(The latched loss budget).[engine] on_killdecides what the process does when it trips (Kill switch and shutdown). - With instruments in more than one settlement currency,
[accounting]names the reporting currency and a rate source for each other currency; without it a start withmax_lossexits 3 (Configuration). -
orders_per_secandburstbelow the venue's order rate limit for your account. The connectors also limit themselves (Bybitorders_per_second, Deribitmatching_engine_rateandmatching_engine_burst, Binance fromexchangeInfo). -
stp = trueunless you trade against yourself on purpose.
Keys and access¶
- Keys come only from the environment (Configuration), and you never run with
--allow-inline-secrets. - The key has trading permission only: no withdrawals, no transfers.
- The key is restricted to your server's IP addresses where the venue supports it.
- One key per running engine, so that revoking one stops one engine.
The host¶
- On bare metal,
[engine] cpuandnet_cpuspin the engine and network threads to isolated cores withspin_mode = "busy". Shared machines use"adaptive"; WSL2 and laptops alsocpu = -1. Thetopology:lines at start show no warning (Cores).fastmm init --profile productionwrites a Binance Spot config for a dedicated host, andconfigs/profiles/production-latency.tomlhas the same[engine]table: busy spinning on isolated cores,timer_slack_ns = 1,lock_memory = true(raiseulimit -l,LimitMEMLOCK=infinityunder systemd) and a larger journal ring. - The engine and network cores are isolated (
isolcpus,nohz_fullandrcu_nocbs, or a cpuset), the CPU governor isperformance, NIC interrupts go to other cores, and transparent huge pages aremadviseoralways(/sys/kernel/mm/transparent_hugepage/enabled): the order and book tables ask for 2 MiB pages. - Latency figures in
fastmm-topand the log are not zero. Hosts withoutnonstop_tsc(many cloud VMs) take wall time fromclock_gettimeand still time intervals with the TSC whenconstant_tscis present. - The system clock is synchronised (chrony or systemd-timesyncd), and the status line's
clock_offset_msstays well belowrecv_window_ms. - The journal directory has room for the session (Journal files); check with
df -h runs. - The status file works:
./build/release/bin/fastmm-top --name <engine name> --onceprints a frame while the engine runs. - The log goes to a file (
--log), and warnings are mirrored to stderr ([logging] mirror_level).
Stopping¶
- You have done a kill-switch drill with this config: a keyed session with open orders, Ctrl-C,
shutdown took <n> ms (cancel_all ok)(Reading the last lines), and no open orders on the venue. - After every stop, including one that logged
cancel_all ok, the venue's open-orders page shows no orders. The shutdown cancel-all sends one request per subscribed instrument, andokmeans those requests succeeded; it does not cover orders on other instruments, orders the venue accepted after the request, or a--dry-run(which skips it). - You know where the venue's own "cancel all" is on its website, and you have read When cancel_all failed.
-
[engine] on_killis set, and whatever startsfastmm-liveorpython -m fastmm runalerts on exit codes 5, 6 and 7, which the shipped systemd unit does not restart (Deploy). - Someone watches the first live session from start to finish.