Skip to main content
A Ziplime strategy is a Python file with lifecycle functions. You don’t subclass anything: define the functions the engine should call and keep your strategy state on context. The file is imported, so module-level code runs — keep it to imports, constants and definitions.

File skeleton

Importing TradingAlgorithm and BarData is optional; the type hints give your editor completion on context and data.

Hooks

The engine substitutes a no-op for any hook you leave out.

initialize(context)

Use it to:
  • Look up assets.
  • Store constants and mutable state on context.
  • Register scheduled callbacks and configure trading controls.
  • Mount point-in-time datasets with context.huggingface_dataset(...).
  • Attach pipelines.
  • Read configuration from context.algorithm.config.
Do not place orders in initialize: there is no current bar yet.

handle_data(context, data)

Use it to read current or historical values, calculate signals, check cash, positions and open orders, place or cancel orders, and record metrics.

before_trading_start(context, data)

Optional, once per session before normal bar processing. Define it async def: every data read is a coroutine, and the engine awaits the hook when it is one. A plain def still runs, but any await data... call inside it is impossible. Use it to reset daily state, read pipeline output or prepare the day’s universe. Orders are disallowed here.

analyze(context, perf)

Optional, once after the simulation finishes. perf is a pandas DataFrame with one row per session, including the columns you recorded with context.record(...).
Define analyze with plain def. The engine currently calls it without awaiting, so an async def analyze never runs. (The local MCP server’s check_strategy_code currently asks for async def on every hook — for analyze, follow this page.)

compute_signals(context, prices) and WARMUP

Optional. Return indicators computed over whole arrays; read them bar by bar through context.signals. Declare how many bars of history they need with a module-level WARMUP. See Vectorized Signals.

Storing state

Use attributes on context for anything that must persist across bars:
Avoid module-level mutable globals for strategy state: they survive between runs in the same process.

Algorithm configuration

Subclass BaseAlgorithmConfig at module level, and the engine loads it from the JSON file passed as run_simulation(..., config_file=...).
Dates, capital, bundle, benchmark, calendar, commission and slippage belong to the run, not to the code. Setting them inside the strategy either does nothing or contradicts the run.

Common mistakes