This document describes how strategy definitions become running instances in trader-mcp.
The design separates:
A strategy definition is reusable code, usually a Python module, that exposes the strategy class and behavior.
It typically defines:
init()on_tick()render()CONFIG_SCHEMAA strategy instance is a configured, uniquely identifiable deployment of a strategy definition.
It has:
Examples:
idstrategy_typeaccountmarketThese fields should be stable and audit-friendly.
Config is user-editable and persistent. It is stored as JSON in the database and supplied to the strategy on load.
State is owned by the strategy instance and is not part of persistent config.
Strategy Definition -> Persisted Instance Record -> Running Instance -> UI View
The database stores desired state. The engine reconciles runtime from that desired state.
Instances should use a small mode set:
off, observe, active
off, not instantiated, no ticks, no tradingobserve, instantiated, ticks enabled, trading disabledactive, instantiated, ticks enabled, trading enabledoff <-> observe is the power toggleobserve <-> active is the activation toggleoffpaused is not a persisted mode.
It is a runtime freeze state controlled by the engine.
This keeps the stored mode model small while still allowing a temporary freeze.
Strategies declare cadence with TICK_MINUTES.
The runtime heartbeats every 6 seconds and schedules strategies from that value.
TICK_MINUTES = 1.0 means about 10 heartbeat steps2.1 is validThe engine reconciles persisted records against runtime instances when records change and at startup.
def reconcile():
for record in db.instances:
if record.mode != "off" and record.id not in running:
load_instance(record)
if record.mode == "off" and record.id in running:
unload_instance(record.id)
Config changes should normally trigger a reload.
unload_instance(id)
load_instance(updated_record)
This is the clean default because it is deterministic and easy to debug.
Selective state carryover is not part of the current model, reload is the default.
The engine should:
account_id and client_id when orders are sent to exec-mcpThe dashboard shows:
It does not own trading logic.
The architecture is strongest when:
account_id and client_id