This document defines a modular architecture for a strategy execution system consisting of:
The system separates definition, configuration, execution, and visualization into clearly distinct layers.
A strategy is a Python module that defines:
on_tick)init)render)CONFIG_SCHEMA)Characteristics:
.py file (optionally + config)A strategy instance represents a configured and uniquely identifiable deployment of a strategy.
Defined at creation and never changed:
id (unique internal identifier)strategy_typeaccountmarket (e.g. BTC/USDT)Purpose:
User-editable and persisted:
{
"risk": 0.01,
"window": 20,
"note": "test run"
}
Characteristics:
Example:
{
"prices": [],
"position": 0
}
Strategy Definition → Strategy Instance → Runtime Execution → UI Rendering
Each instance has exactly one mode:
mode ∈ { off, observe, active }
| Mode | Loaded | Receives Ticks | Can Trade |
|---|---|---|---|
| off | ❌ | ❌ | ❌ |
| observe | ✅ | ✅ | ❌ |
| active | ✅ | ✅ | ✅ |
Source of truth:
{
"id": "...",
"strategy_type": "...",
"account": "...",
"market": "...",
"mode": "observe",
"config": {...}
}
running_instances = {
"id": StrategyInstance(...)
}
Derived from persistent state.
The engine continuously aligns runtime with the database.
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)
The system is declarative: The database defines the desired state, the engine enforces it.
class Strategy:
CONFIG_SCHEMA = {}
def __init__(self, context, config):
self.context = context
self.config = config
self.state = self.init()
def init(self):
return {}
def on_tick(self, tick):
pass
def render(self):
return {"widgets": []}
Strategies interact only through context:
context.get_price()
context.place_order(...)
context.get_orders()
def place_order(...):
if mode != "active":
raise Exception("Not allowed")
Defined via CONFIG_SCHEMA
Purpose:
Example:
{
"risk": {
"type": "float",
"default": 0.01
}
}
Generated dynamically:
def render(state):
return {
"widgets": [
{"type": "line_chart", "data": [...]},
{"type": "metric", "label": "PnL", "value": 123}
]
}
Config UI = user input
Runtime UI = system output
Displays:
for instance in running_instances:
instance.on_tick(tick)
def get_ui(instance_id):
return instance.render()
mode fieldThe system consists of:
Let strategies always think — but only sometimes act.