# Strategy Contract This is the canonical contract for `trader-mcp` strategies. ## Purpose A strategy defines behavior. It does not own persistence, lifecycle, or UI rendering. ## Strategy class ```python class Strategy: LABEL = "Human readable name" CONFIG_SCHEMA = {} STATE_SCHEMA = {} TICK_MINUTES = 1.0 def __init__(self, context, config): self.context = context self.config = config self.state = self.init() ``` ## Responsibilities ### Strategy - decides what to do - reads config - mutates `self.state` - returns structured render data ### Not strategy responsibilities - persistence - lifecycle control - config storage - identity ownership - direct access to engine internals ## Configuration - `CONFIG_SCHEMA` is declarative metadata - config is supplied by the engine - config changes are handled by reload - config should stay read-only from the strategy perspective ## State - `self.state` belongs to the instance - `STATE_SCHEMA` declares what state is durable / persisted - keep state serializable where practical - do not depend on hidden global state - the engine snapshots and restores state, not the strategy ## Lifecycle ```text init() -> state created on_tick() -> state updated reload -> state restored from engine snapshot if available ``` ## Context The context is capability-only. Allowed: - market/data access - order placement - logging - engine-mediated actions - binding `account_id` and `client_id` into exec calls Not allowed: - persistence - config storage - lifecycle decisions - strategy identity ownership ## UI output Strategies return structured widgets, not HTML. ```python { "widgets": [ {"type": "metric", "label": "PnL", "value": 123.45}, {"type": "line_chart", "data": [...]} ] } ``` ## Example ```python from src.trader_mcp.strategy_sdk import Strategy class Strategy(Strategy): LABEL = "Hello World" CONFIG_SCHEMA = {"label": {"type": "string", "default": "hello world"}} STATE_SCHEMA = {"counter": {"type": "int", "default": 0}} def init(self): return {"counter": 0} ```