Determinism
A backtest must produce the identical result every time, so:
- Never read the wall clock. Use
ctx.Now()and bar timestamps. - Never use random numbers (unseeded ones, anyway).
- Don’t keep lifecycle state in private flags. Gate decisions on
ctx.Position/ctx.Flat, which are reconstructed from fills – smacross gates onctx.Position(bar.Symbol).Quantity, never on a “amILong” boolean. State derived from bars and fills survives restarts; private flags do not. - Make ClientIDs deterministic. smacross stamps
fmt.Sprintf("smacross_%d", bar.CloseTime.UnixNano())– a private counter would collide across a live restart.
Learning from the bundled strategies
The repository’s non-demo strategies are useful implementation references, but their trading rules are not reproduced in this manual. The examples above use the deliberately public hello and smacross demonstrations. The other strategies were consulted only for recurring platform techniques: validating cross-field inputs in OnInit, sizing lookback, checking Series.Fresh in multi-timeframe code, deriving lifecycle state from fills, forming deterministic client IDs, handling brackets and cancellations, and summarising state during shutdown.
That is a good way to read an unfamiliar strategy without copying its contents: separate its platform-shaped code from its trading thesis. Study how it asks for data, indexes a series, prevents duplicate exposure, constructs an order, and tests a replay seam. Treat the signal formula, parameter values and portfolio selection as private strategy policy.