Skip to content

Port and compare original Zipline user journeys #156

Closed

Description

@stefan-jansen

User workflow and ownership

Explicit daily/minute bar labels, callback schedule/timezone, warmup/history adjustment as-of time, intent known_at, eligible execution bar/price, queue/cancel policy, price/volume units and stable IDs. Map Zipline us_futures execution window explicitly rather than by its calendar name.

Backtest owns runtime simulation and actual account exports. Data owns prepared inputs/adjustments, Engineer owns features, Diagnostic owns analytics. Existing Strategy, Engine, LifecycleDispatcher and AccountState remain authoritative. No mandatory new strategy base or Reloaded production dependency.

Current behavior and implementation

missing capability. Current interfaces: Strategy lifecycle callbacks, DataFeed prices/signals/history/context, Broker order/cancel APIs, target-weight executor/rebalance schedule, execution policies, costs, participation and risk controls.

Source locations: strategy.py, datafeed.py, engine.py, lifecycle.py, execution/schedule.py.

  • Introduce the opt-in native market/scheduler services described below while retaining the
    existing Strategy signature and context dictionary. Bind run state only for that run.
  • Implement current/history, last-traded/staleness, tradability, session access and prepared
    auxiliary-data queries over existing indexes. Native output is Polars; Pandas shape conversion
    belongs to the compatibility boundary.
  • Support pre-start warm-up without pre-start trading. Enforce per-field known-at and adjustment
    cutoffs, lifetimes and field-specific missing/forward-fill rules.
  • Extend actual dispatch for pre-session, eligible bar/open/close and session-end callbacks.
    Reuse Specs phase definitions and calendar schedules. Preserve callback registration order,
    once-per-session behavior, half-days and offsets. Missing intraday data cannot be replaced with
    an invented minute event.

Acceptance: migrate daily moving-average and minute market-close strategies. Compare callback
time/order, available history rows, shapes, keys, adjustment basis and decision outputs. Future
rows/events appended to the input cannot change an earlier decision. Cover warm-up, stale quotes,
missing volume, holidays, DST, early closes, breaks and overnight futures sessions.

Source locations: broker.py, core/order_book.py, core/execution_engine.py,
execution/fill_executor.py, models.py, accounting/gatekeeper.py, native risk boundaries,
and a new proposed compat/zipline/ namespace.

  • Deliver the controlled initializer, callback/context/asset facades, familiar API functions,
    finance parameter translators and legacy result projection through the native engine.
  • Qualify market/limit/stop/stop-limit orders, quantity/value/percent targets, batch order order,
    integer/fractional rules, cash constraints, cancellation and partial-fill statuses. A batch of
    legacy orders must not become a target-weight snapshot with different ordering semantics.
  • Add native order-context incremental fees, preserving existing model behavior by default.
    Quote/affordability checks cannot consume fee state. Cover per-share, per-dollar, per-trade and
    per-contract/minimum/exchange-fee conventions through full and partial fills.
  • Qualify no/fixed/basis-point/volume-share and futures volatility-volume impact routes. Add a
    native implementation where the existing model differs, using the current impact/limit
    interfaces. Compare consumed volume across multiple orders on the same asset/bar.
  • Compile trading controls into pre-submission checks, including order count, position/order
    size, dated restrictions and long-only behavior. Compile account controls separately at the
    reference validation boundary, including minimum leverage grace periods and session-end maximum
    leverage. Checking every account rule before every order would change strategy behavior.
  • Provide deterministic environment/time/record/benchmark handling. Preserve recorded values'
    documented carry behavior without overwriting authoritative native account fields.

Acceptance: execute the same original callback bodies through reference and adapter, then an
idiomatic native strategy. Use divergent open/close prices, pending targets, repeated targets,
partial fills and competing orders. Verify each submitted/remaining quantity, execution instant,
price, fee, rejection and cash/NAV sample. A ten-share order split into two five-share fills has
one $1 per-order minimum under the explicit reference policy; the current per-fill model stays a
separate supported method. Nested runs and callback errors cannot leak active adapter context.

  • Validate caller-supplied tables and immutable manifests against the Backtest contracts. Add
    Backtest-owned adapters/tests against the existing published input/feature APIs and captured
    valid external fixtures. Implementing another repository's provider, identity database or
    feature library is not part of this plan.
  • Map fetch_csv to a registered immutable auxiliary dataset using its original source key and
    explicit parsing/availability metadata. Preserve relevant preprocessing/symbol-mapping behavior.
    Prepare network data before execution; never contact an unrecorded URL or substitute unrelated
    data silently.
  • Offer a prepared Pipeline-panel route with stable IDs, universe masks, known-at values and
    requested output shapes. Show the exact construction change. Test lazy/eager/chunk options or
    report a precise incompatibility. Do not accept an arbitrary Pipeline object and ignore it.
  • Resolve benchmark assets to a declared prepared return/total-return series, including the
    reference reinvestment convention. A price-only benchmark proxy is insufficient when dividends
    matter. Carry dated benchmark provenance into results/consumer examples.
  • Supply actual holdings/account/fill inputs to public analysis APIs and a thin cash-equity Pandas
    projection for migrating Pyfolio users. Futures notional and NAV-valued holdings remain distinct.
    Existing external-return/factor workflows require no trading simulation merely to run analysis.

Acceptance: original momentum/Pipeline-style and OLMAR workflows have declared native routes;
input-key/universe/rank/availability comparisons pass before comparing trades. The analytical
handoff uses real Engine and reloaded artifact inputs with unchanged sample keys/units. Missing
optional benchmark/factor/volume data disables only dependent analyses. A missing essential route
stays unfinished, with its exact Backtest or external-contract blocker recorded.

Prepared-input adapters should accept documented Pandas/Polars panels and saved CSV/Parquet inputs
without making users rewrite their research storage first. Normalize at one boundary and test
timezone, identifier, null/dtype, duplicate-key and equal-time ordering preservation. Never silently
drop an unmapped instrument or deduplicate economically distinct events.

Acceptance and independent oracles

  • Callback trace -> available history/feature keys -> intents -> ordered fills -> cash/holdings/marks at each step; compare first divergence, not final NAV only.
  • Daily rebalance and minute market-close through DST/early close/holiday, stale/missing bar, end-of-data and pending order.
  • Market/limit/stop/stop-limit, target quantity/value/percent with open orders, cancel/EOD cancel, participation partial fills, cash/leverage/short restrictions and fee/slippage options.
  • Rename then symbol reuse retains distinct stable IDs; end-of-life rejects new orders and follows explicit final-mark/liquidation policy. Missing final quote does not become zero silently.
  • Split with pending/partial order and futures roll execution reuse accounting fixture expectations, not synthetic equivalent-price transformations.
  • Original example/API inventory below identifies concrete journeys, not verified parity. Run paired native reference profiles on frozen shared inputs plus independent timing/ledger oracles; support different successor APIs and qualify all material options.
  • Invalid or ambiguous inputs fail before account/output mutation; unknown information is not fabricated.
  • Existing default behavior, actual legacy artifact readers, keys/units, and captured accepted performance samples retain their qualified scope.

Dependencies

  • Data identity/universe/as-of history and Engineer point-in-time features for those journeys.
  • Action/account batches only for affected variants; ordinary daily/minute ports proceed now.

Source requirements

  • Coverage row 178: Zipline / Price adjustment basis and causal history (primary owner Data).
  • Coverage row 181: Zipline / Stable IDs, dated symbols, lifetimes and delistings (primary owner Data).
  • Coverage row 183: Zipline / Pipeline and adjusted history workflows (primary owner Engineer).
  • Coverage row 184: Zipline / Execution, callbacks and trading controls (primary owner Backtest).

Evidence and completion

Retain failing-base/passing-fix public Engine evidence for defects; independent arithmetic and matched native reference configurations for new behavior. Test actual installed producer-to-consumer workflows, not reconstructed account objects. All applicable final-head source, type, coverage, package, security, platform and strict documentation checks must pass before ordinary guarded merge. Missing essential workflows remain unfinished. No release or deployment is included.

Premises: none - This projection preserves accepted implementation requirements and explicit independent acceptance oracles; it introduces no untested factual assumption as a design prerequisite.

Closes: none
Advances: none

AI assistance: This implementation specification was prepared with OpenAI Codex using source inspection, retained Engine reproductions and the accepted maintainer-reviewed cross-library scope. The implementing maintainer remains responsible for review and executed evidence.

Plan reference: successor implementation projection, Issue 3; batch execution-history-controls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions