Skip to content

About

Replay simulator for SPX 0DTE options: historical sessions with the full option chain at 10-second resolution, simulated fills, margin and settlement, and no lookahead.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Strikeline

CI License: AGPL v3 Python 3.13

Strikeline is a replay simulator for SPX 0DTE options (options that expire on the day they are traded). It replays a historical session with the complete SPXW option chain at 10-second resolution and simulates order execution, margin and settlement against the recorded quotes. At no point does the application expose data from after the replay clock.

Strikeline on the synthetic demo data: chart, price ladder, two spread positions and a working bracket

A synthetic FOMC session from the bundled demo data: the index chart (left), the option chain rendered as a price ladder aligned to the chart's price axis (right), and two open spreads with a working bracket order (bottom).

  • Purpose: deliberate practice of intraday options trading on historical sessions, at real time or accelerated up to 300x.
  • Scope: unlike chart-only replay, Strikeline replays every strike's bid and ask and fills orders against those quotes.
  • Evaluation: a bundled synthetic data set lets it run without a data subscription or broker account (Quick start).
  • Engineering: specification-driven development, approximately 1,400 automated tests, a lookahead gate, an independent oracle, and CI on Linux and Windows (Engineering).
  • Stack: Python 3.13, FastAPI, pyarrow and DuckDB, SQLite, vanilla JavaScript, TradingView Lightweight Charts.

Status. Strikeline is a personal project, developed for my own trading practice. It is extensively tested within its scope, but it has not undergone the independent review, hardening and operational work that production software requires. The live-broker connectors are experimental and have not been used with a real account.

Contents: Quick start · Features · Engineering · Using real data · Documentation · License

Quick start

Requires Python 3.13 (on Windows, use py -3.13 if it is not the default python).

git clone https://github.com/triwebb1/strikeline.git
cd strikeline
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -e .
python launch.py

On first run, the launcher generates the demo data set in data/, starts the server on http://127.0.0.1:8765 and opens a browser. Create a workspace on any session from 2030-04-08 to 2030-04-12 and start playback. On Windows, Strikeline.cmd launches the application once the package is installed.

The demo data is synthetic (src/strikeline/demo.py): a random-walk index with intraday volatility seasonality and event shocks, and option quotes priced with Black-Scholes on a skewed volatility smile and rounded to the SPXW tick grid. It is dated 2030 so that it cannot be mistaken for historical data.

Features

  • Price ladder. The option chain is rendered on the chart's price axis, with each strike at its price level, call and put bid / mid / ask, and $5 vertical spread prices between strikes. Positions, working orders and the order being composed share the same rows, alongside a P&L-at-expiration profile. Selecting a price opens an order ticket; optional one-click mode submits directly.
  • Lookahead-free replay. The server owns the clock and filters every response to data stamped at or before it. Playback runs at 1x to 300x, steps in 10-second increments, jumps, or advances with Next to one second before the next fill, trigger or session event. Blind mode starts on a random session and conceals the date.
  • Orders. Market, limit, stop and SPX-level trigger orders; OCO brackets; and multi-leg combinations (verticals, iron condors, butterflies) that fill atomically at the adverse side of every leg.
  • Account. Long and short positions per leg, Reg-T style margin with covered pairs margined together, buying-power checks at fill time, commissions, and cash settlement at the official close.
  • Chart. 10-second to 30-minute candles including the overnight session, VWAP with standard-deviation bands, prior-session levels, opening ranges, an EMA, and economic-event markers (CPI, FOMC, NFP) that appear only once the event would have been known.
  • Journal and statistics. Fills, an event log, a trade journal with notes and tags, and statistics across sessions. Each workspace is a simulated account persisted to SQLite and resumed exactly where it was left.
Order ticket opened from a ladder click The FOMC decision on the demo day: the stop-loss gaps through
Selecting a spread price on the ladder opens a ticket with an order preview. The synthetic FOMC announcement: the bracket's stop fills through a price gap.

Engineering

Development approach

Strikeline was developed over approximately one week using specification-driven development, with Claude Code as the implementation tool. The process below is what made that pace compatible with correctness:

  1. Specification first. Every rule (what constitutes a fill, when an order may act, how margin pairs legs, what the ladder displays) is defined in SPEC.md before implementation. The specification is versioned (v1.0 to v1.5), and code and tests cite its sections, so each behavior is traceable to a recorded decision.
  2. Correctness by design. The architecture makes the most consequential failures structurally difficult: the server owns the clock and gates every response, the engine is side-effect-free logic over integer cents, and all trading passes through a single Backend interface, which a test enforces.
  3. Phased delivery with acceptance. The data pipeline, engine, API and UI were built in sequence, each accepted before the next began. Data decisions rest on measurement; for example, the candle-wick method was selected by evaluating candidates against the actual index.
  4. Independent verification. In addition to unit and integration tests, an oracle with its own implementation re-derives each outcome from the raw data, a headless browser exercises the real UI, and a dedicated review followed each major change. Findings and their resolutions are documented (for example, docs/live/LIVE_REVIEW_FINDINGS.md).

I was responsible for the product and engineering decisions: the trading workflow and the ladder concept, the specification, the architecture, the testing strategy, and the acceptance of each feature through use. Claude Code wrote most of the code to that specification.

Verification

The suite contains approximately 1,400 automated tests: about 690 for the replay product (engine, data, server and UI) and 700 for the experimental broker connectors, which run against simulated brokers. The 1,200 tests that require no market data run in CI on every push, together with the end-to-end checks below on freshly generated demo data. The remainder replay licensed historical sessions (circuit-breaker halts, early closes, FOMC days) and run locally.

Check What it verifies
Lookahead gate No response contains data stamped after the clock, and every view recomputed from data with the future removed is identical (tests/demo/test_demo_gate.py).
Oracle Independent code, trading through the API as the UI does, predicts every fill, stop, margin figure and final cash balance to the cent from the raw quote files (tests/e2e/oracle_check.py).
Browser Playwright drives the real UI in headless Chromium and fails on any console error (tests/web/demo_tour.py, which also produces these screenshots).
Architecture The server does not bypass the Backend interface (tests/test_architecture.py).
Local-only server The server binds to 127.0.0.1 and rejects non-local Host headers and cross-origin requests, so other web pages cannot control it.
Input robustness Out-of-range prices and quantities are rejected before any state changes, and concurrent open and close operations or failed saves leave workspaces consistent.
Data validation and lint The demo data must pass the format validator; Ruff checks the code.

The complete suite runs with one command, on the demo data or on a local data set:

pip install -e ".[dev]" && python -m playwright install chromium
python tests/e2e/run_e2e.py --demo

Architecture

flowchart LR
    subgraph Browser["Browser (vanilla JS + Lightweight Charts)"]
        UI["chart · ladder · ticket · positions"]
    end
    subgraph Server["FastAPI server"]
        API["HTTP + WebSocket API"]
        Gate["lookahead gate<br/>(T ≤ clock)"]
        WS["workspaces<br/>(SQLite)"]
    end
    subgraph Backends["Backend interface"]
        Replay["ReplayBackend<br/>engine + replay clock"]
        Live["Live backends<br/>(experimental)"]
    end
    Data[("replay store + option snapshots<br/>(parquet)")]
    Pipeline["offline pipeline"] --> Data
    Demo["demo generator"] --> Data
    UI <--> API
    API --> Gate --> Replay
    API --> WS
    Replay --> Data
    Live -.-> Brokers["IBKR · TradeStation · Massive"]
Loading
Package Responsibility
strikeline.engine Pure trading logic: orders, fills, per-leg positions, margin, settlement and clock processing, with no I/O (docs/ENGINE.md).
strikeline.data Read-only loaders for the replay store and option snapshots, path configuration, and the format validator.
strikeline.backends The Backend interface the server depends on; ReplayBackend wraps the engine, and backends/live contains the experimental broker connectors.
strikeline.server FastAPI application, clock loop, lookahead gate, indicators, ladder and chain views, and workspaces (docs/API.md).
strikeline.pipeline Offline builder of the replay store from raw vendor files.
strikeline.demo Synthetic demo data generator.
web/ Frontend: ES modules with no build step and no framework.

The engine represents money as integer cents and time as UTC epoch seconds on a 10-second grid.

Using real data

Historical SPX option quotes are licensed per user, so none are included. Strikeline reads a documented, file-based parquet format, specified file by file in docs/DATA_FORMAT.md. A validator checks a data set against that specification:

python -m strikeline.data.validate --replay <dir> --options <dir>

The minimum requirement is 10-second SPXW option snapshots (bid and ask per strike; files in ThetaData's layout are read directly) and an index bar series with a trading calendar (the replay store). The included pipeline (python -m strikeline.pipeline build, rules in docs/PIPELINE.md) builds the replay store from the snapshots and 1-second ES futures bars (DataBento CSV), which also supply the overnight chart and VWAP. For other sources, writing the replay store directly is usually simpler; src/strikeline/demo.py is a complete reference writer.

Documentation

Document Contents
SPEC.md Product specification: every rule the application follows
docs/DATA_FORMAT.md Data contract for supplying your own data
docs/ENGINE.md Trading engine: fills, orders and account
docs/API.md HTTP and WebSocket API used by the web UI
docs/PIPELINE.md Pipeline rules for building the replay store from raw data
docs/wick_validation.md Evaluation behind the candle-wick method
docs/live/ Experimental live trading: design, broker notes and reviews
docs/mockups/price_ladder_v11.html Design mockup of the price ladder (a standalone HTML page; open it in a browser)

License

GNU AGPL v3.0 or later. You may use, study, modify and share Strikeline. If you distribute it, or make a modified version available to others over a network, you must provide the source of that version under the same license. Bundled third-party code is listed in THIRD_PARTY_NOTICES.md.

Strikeline is a training and research tool. It does not provide investment advice and is offered without warranty (see the license).

About

Replay simulator for SPX 0DTE options: historical sessions with the full option chain at 10-second resolution, simulated fills, margin and settlement, and no lookahead.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages