Keep ownership clear:
account_id, client_id) to execution callsThe context is the strategy’s access boundary to the outside world. It should not become a secondary persistence layer.
If context loads config, it becomes harder to reason about, more coupled to storage, and less reusable.
Context = capabilities only.
record = {
"id": "...",
"strategy_type": "mean_rev",
"config": {
"risk": 0.01,
"window": 20
},
"mode": "observe"
}
def load_instance(record):
module = load_strategy(record["strategy_type"])
context = StrategyContext(engine, record["id"], mode=record["mode"])
instance = module.StrategyClass(
context=context,
config=record["config"]
)
running_instances[record["id"]] = instance
risk = self.config["risk"]
That read should be conceptually read-only from the strategy’s point of view.
Config changes should normally mean a clean reload.
unload_instance(id)
load_instance(updated_record)
Benefits:
Tradeoff:
That tradeoff is acceptable and probably desirable for the first version.
Config is:
State is:
Keep them separate.
If a strategy is active, a config change should move it to a safe mode before reload, then optionally reactivate it afterward. That avoids accidental trading during transition.
Engine constructs the world
Strategy lives inside it
Context is the interface to reality
Config is part of the world, not the interface
Use JSON config blobs in SQLite and reload on config change. That fits the current app shape well.