Parameters and strategy state¶
Keep tunable values in params and values remembered between bars in state.
symbol = "TCS"
def on_start():
return {"lookback": 20, "qty": 10}, {"signals_seen": 0}
def on_tick():
if len(close) < params.lookback:
return
if position.is_flat and close[0] > mean(close, params.lookback):
state.signals_seen += 1
long(params.qty)
on_start() returns parameters first, initial state second. Parameters are read-only during a run. State is mutable; initialise a value before reading it. It persists between bars within a run. Persistence across restarts requires the runtime's state-restoration support, so do not assume a new run inherits the previous one.
For prices use price data; for holdings use positions. See state reference for access methods.
Separate configuration, memory and observations¶
| Value | Role | Can your strategy change it? |
|---|---|---|
params.lookback |
A configured input. | No, parameters are read-only during a run. |
state.signals_seen |
Memory you initialise and update. | Yes. |
close[0] |
Current market observation. | Read it; do not assign to it. |
position.qty |
Current holding view. | Change holdings through order actions. |
Ordinary local variables inside on_tick() are recreated each call. Use state when the value must survive to the next observation, and params when you want a setting rather than mutable memory.
Access and initialisation¶
Return (parameters, initial_state) from on_start() in that order. params.lookback and params["lookback"] read the same configured value. params.get("lookback", 20) supplies a fallback when the key is absent. A missing required attribute raises an error rather than inventing a value.
Read known attributes to inspect state, and use "signals_seen" in state to check whether a key exists. State uses attribute assignment, for example state.signals_seen = 0; initialise numeric counters before incrementing them.
In broadcast per-instrument mode, state is scoped to the current symbol. A count observed for TCS is not automatically the shared portfolio count. For a parameter snapshot, dict(params.items()) uses the public mapping interface. Although the Python proxy types expose to_dict(), the current strategy validator rejects that method name (TS005), so do not use it in a validated draft. Persistence across bars, across instruments and across process restarts are separate requirements. Check restoration support before relying on a restart to preserve state; checkpoint coordination is a runtime concern rather than a method to call on the public state proxy.
Continue a broadcast run¶
When your runner saves and resumes a current Atom checkpoint, it restores each broadcast member's state as well as the shared strategy state. For example:
universe = ["TCS", "INFY"]
def on_start():
return {}, {"observations": 0}
def on_tick():
state.observations += 1
if state.observations == 1:
long(1)
After two observations for each member, resuming makes each counter three on its next observation. It does not repeat the first-observation entry. This applies to full and differential checkpoints. Starting without a checkpoint is a new run and starts both counters at zero.
Older checkpoints contain only shared state, so missing per-member counters
cannot be recovered from them. Broadcast, pair, shared-budget and forecast
resume rejects those old snapshots rather than repeating initial entries.
Rebuild those runs from their original data. Keep serializable remembered values
in state; ordinary module globals and local variables are not checkpoints.