Skip to main content

Local-first Elliott Wave analysis for swing traders

Project description

wave-alpha — Elliott Wave engine for swing traders

Local-first Elliott Wave analysis for swing traders. Deterministic rule engine · multi-timeframe coherence · optional LLM reranking · leak-free backtests.

PyPI version Downloads Python uv Ruff Pydantic v2 Local-first BYO key


Why wave-alpha

Existing "auto Elliott" tools are either dressed-up ZigZag indicators, institutional-priced terminals, or cloud-only SaaS. None of them give swing traders all of:

  • Rule-validated counts with calibrated alternates — not a single confident-but-fragile answer.
  • Multi-timeframe coherence (weekly + daily + 4h) as a first-class scoring input.
  • A trade-signal contract — entry, stop, target, R-multiple — derived directly from the count.
  • Honest backtests that enforce lookahead at every fetch site.
  • Local-first, BYO-key, no telemetry. Your watchlist and bars stay on your disk.

[!NOTE] The LLM is a strictly optional reranker and narrator — it never counts waves on its own. The deterministic engine is always the source of truth.

Contents

What it does

wave-alpha covers the full swing-trader workflow — from raw bars to a ranked thesis to a backtest receipt — organized around six capabilities:

Capability Summary Learn more
🌊 Wave detection Rule-validated Elliott counts with calibrated alternates and multi-timeframe coherence. How it works
🎯 Trade-ready signals Entry, stop, target, and R-multiple derived directly from the top count. Quick start
📋 Watchlist & scanning Persistent watchlist, multi-ticker scans, and a self-refreshing OHLCV cache. Watchlist & scan
📈 History & stability Per-ticker snapshots and a stability badge that tracks how a thesis holds up over time. History snapshots
✅ Honest backtests Three-layer harness with hard-enforced lookahead safety. Backtest harness
🤖 Optional LLM rerank BYO Anthropic key for reranking and narration; engine never depends on it. LLM reranking

Wave detection

  • Pattern library as data — six templates (impulse, zigzag, flat, expanded_flat, contracting_triangle, ending_diagonal) defined in YAML with hard / soft constraints. Add a pattern by dropping a file — no code change.
  • Multi-degree ATR-scaled pivots with deduplicated top-K candidates per timeframe.
  • Multi-timeframe coherence — weekly + daily + 4h read against each other; the coherence multiplier folds into final ranking.
  • Calibrated alternates ranked by final = coh × (α · engine + (1−α) · llm_prob), never a single confident answer.

Trade-ready signals

  • Entry / stop / target / R-multiple derived from the count's structural pivots.
  • Right-edge confirmation modelsheuristic, calibrated_heuristic, or trained logistic — with paired-bootstrap promotion gating.
  • Configurable target sourcefib_extension (default) or fixed_R.

Watchlist & multi-ticker scanning

  • Watchlist with imports from CSV or TradingView text format.
  • Scan any list of tickers with one command; reports persist to ~/.wave_alpha/scans/ for instant dashboard reload.
  • OHLCV cache auto-refetches a stale tail, so daily cron runs always pull fresh bars without re-downloading history.

History & stability tracking

  • Snapshot per analysis — every analyze call records the top counts, signals, and coherence to ~/.wave_alpha/history.sqlite.
  • Stability badge highlights when the top count's identity persists across runs — separates transient signals from a maturing thesis.
  • Best-effort writes that never raise, so corrupted state can't interrupt analysis output.

Honest backtest harness

  • Three layers — count direction hit-rate, per-degree pivot Brier score, and full trade simulation (hit rate, expectancy, profit factor, max drawdown in R-units).
  • Lookahead is hard-enforced by PointInTimeView at every fetch site, with a synthetic-leak unit test that plants a violation and verifies the assertion fires.
  • Grid search to sweep rule parameters across the curated universe.

Interfaces

  • CLIanalyze, scan, watchlist, backtest, train, ui, config (command reference).
  • Local web UI with TradingView Lightweight Charts (vendored, MIT) — deep-dive page, scan dashboard, watchlist manager, count-history strip. Zero CDN runtime dependencies.

Optional: LLM reranking

  • BYO Anthropic key — the engine is fully usable without one.
  • Reranker only — the LLM never counts waves; it adjusts ranking and narrates the top thesis.
  • Strict privacy contract — pivots and candidate structures only; no bars, no watchlist, no key in payload.

Prerequisites

Requirement Why
Python 3.11+ Pinned in .python-version; required by the engine.
uv Project manager — every command runs as uv run ….
Anthropic API key (optional) Only needed for --llm-mode live; requires the llm extra (wave-alpha[llm]). The engine is fully usable without it.

[!IMPORTANT] All commands go through uvdo not activate the venv manually. uv run resolves the right interpreter and extras for you.

Installation

From PyPI (most users)

# Lean install (deterministic engine + CLI)
uv pip install wave-alpha

# With the local web UI
uv pip install "wave-alpha[ui]"

# With the optional LLM reranker (BYO Anthropic key)
uv pip install "wave-alpha[ui,llm]"

The LLM reranker is opt-in — install the llm extra to enable --llm-mode live or cached. Without it, the deterministic engine works exactly the same.

Develop from source

git clone https://github.com/chen-star/wave-alpha.git
cd wave-alpha

# Engine + CLI only (most contributors start here)
uv sync --extra dev

# Add the web UI
uv sync --extra dev --extra ui

# Add the LLM reranker
uv sync --extra dev --extra ui --extra llm

Verify the install:

uv run wave-alpha version

Quick start

Run a one-off analysis on a ticker — no API key, no cloud, no account:

# Today
uv run wave-alpha analyze AAPL

# Or rewind to a specific cutoff (lookahead-safe)
uv run wave-alpha analyze AAPL --as-of 2024-12-31

# JSON output for scripting
uv run wave-alpha analyze AAPL --json | jq .

You'll see the top-3 ranked counts, a coherence score, and any derived trade signals (entry / stop / target / R-multiple). Each run also writes a snapshot to the local history database — see History snapshots.

CLI at a glance

Command Purpose
wave-alpha analyze TICKER Run analysis for a single ticker, optionally --as-of YYYY-MM-DD, --json, --llm-mode.
wave-alpha scan Scan watchlist (or --symbols A,B,C) and persist a report.
wave-alpha ui Launch the local web UI (binds to 127.0.0.1, picks a free port in 8765–8775).
wave-alpha watchlist add|rm|ls|import Manage saved tickers.
wave-alpha config show|set View or change config (API key, model, alpha).
wave-alpha backtest count|pivot|trade|grid Walk-forward backtest harness across three layers + grid search.
wave-alpha train right-edge|calibrated-heuristic Train and gate right-edge confirmation models.
wave-alpha version Print the installed version.

Every command supports --help.

Web UI

uv sync --extra ui
uv run wave-alpha ui          # binds to 127.0.0.1 on first free port in 8765–8775

Then open:

Page URL
Single-ticker deep-dive http://127.0.0.1:8765/deepdive/SPY
Scan dashboard http://127.0.0.1:8765/scan
Watchlist http://127.0.0.1:8765/watchlist
Settings (paste API key here) http://127.0.0.1:8765/settings

The deep-dive page composes a chart with pivot overlays, the multi-TF coherence row, the top-3 counts with optional LLM narrative, an auto-derived trade plan, right-edge alternates, and a count-history strip.

Watchlist & scan

uv run wave-alpha watchlist add AAPL
uv run wave-alpha watchlist add MSFT
uv run wave-alpha watchlist import portfolio.csv --format csv
uv run wave-alpha watchlist import tradingview.txt --format tv-txt

# Scan all watchlist tickers (LLM disabled by default — no API cost)
uv run wave-alpha scan

# Ad-hoc list with a specific cutoff
uv run wave-alpha scan --symbols AAPL,MSFT,NVDA --as-of 2026-05-01

Reports persist as JSON to ~/.wave_alpha/scans/<scan_id>.json so the dashboard reloads instantly without re-running.

History snapshots

Every analyze invocation writes a snapshot of the top counts, coherence, and trade signal into ~/.wave_alpha/history.sqlite. The web UI surfaces a per-ticker history strip and a stability badge that highlights when the top count's identity persists across runs — useful for separating transient signals from a maturing thesis.

The write is best-effort and never raises, so a corrupted DB or full disk will not interrupt analysis output.

LLM reranking (optional)

wave-alpha can rerank the engine's candidate counts and narrate them using an Anthropic API key (BYO).

# One-time setup
uv run wave-alpha config set api_key sk-...

# Live API; responses cached to ~/.wave_alpha/llm_cache.sqlite
uv run wave-alpha analyze AAPL --llm-mode live

# Reproducible — raises on cache miss, no key required
uv run wave-alpha analyze AAPL --llm-mode cached

# Engine-only baseline (default; mandatory for backtest comparisons)
uv run wave-alpha analyze AAPL --llm-mode disabled

# Tune the engine/LLM blend
uv run wave-alpha analyze AAPL --llm-mode live --alpha 0.6

Final ranking formula: final = coh_multiplier × (alpha × engine_score + (1 − alpha) × llm_prob).

[!IMPORTANT] Privacy contract. When the LLM is enabled, the only payload sent upstream is: ticker symbol, pivot timestamps and prices, candidate count structures, and coherence metrics. No bars. No watchlist. No API key in the payload. Nothing else.

Backtest harness

Honest accuracy starts with a leak-free backtest. Lookahead is hard-enforced by PointInTimeView at every fetch site, with a synthetic-leak unit test that plants a violation and verifies the assertion fires.

# Count layer — top-1 / top-3 forward direction hit rate
uv run wave-alpha backtest count \
  --universe data/universe_curated.txt \
  --start 2020-01-01 --end 2024-12-31 \
  --step 5 --out reports/count.md

# Pivot layer — per-degree confirmation rate + Brier score
uv run wave-alpha backtest pivot \
  --universe data/universe_curated.txt \
  --start 2020-01-01 --end 2024-12-31 \
  --out reports/pivot.md

# Trade layer — hit rate, avg R, expectancy, profit factor, max drawdown
uv run wave-alpha backtest trade \
  --universe data/universe_curated.txt \
  --start 2020-01-01 --end 2024-12-31 \
  --rules my-rules.yaml \
  --out reports/trade.md \
  --json reports/trade.json \
  --trades-csv reports/trades.csv

All three layers run --llm-mode disabled by construction — headline numbers are reproducible without an API key. The bundled data/universe_curated.txt ships 50 tickers across sectors and vol regimes; pass your own with --universe my-list.txt.

[!WARNING] The 4h timeframe is resampled from yfinance's 1h data, capped at ~730 days of history. Backtests reaching back further degrade gracefully to 2-timeframe coherence (weekly + daily) and emit a startup warning. The trade-layer report's 4h coverage line and the tf_count column in the CSV ledger let you slice ablations on this dimension.

How it works

OHLCV bars (weekly / daily / 4h)
  → PointInTimeView(bars, as_of)              # lookahead-safety boundary
  → detect_multi_degree (ATR-scaled zigzag)   # pivots at degrees 0..N
  → enumerate_counts(pivots)                  # YAML templates + fib + recency → top-K
  → three_way coherence(W, D, 4h)             # multiplier on engine_score
  → [optional] LLM rerank                     # blended via blend_scores(alpha, …)
  → derive_signal(top counts)                 # entry / stop / target / RR

Every consumer (CLI, web, scan) tolerates partial results — pipeline.run_analysis always returns an AnalyzeResult, even with empty bar series.

For full design rationale see docs/superpowers/specs/2026-05-03-wave-alpha-design.md.

Right-edge models

Three implementations of the ConfirmationModel protocol — selected via RightEdgeConfig.kind:

Kind What it is Artifact
heuristic Hand-coded weighted sum none
calibrated_heuristic Heuristic + per-degree Platt scalers JSON
logistic Full logistic regression with stable feature order JSON

Train artifacts via wave-alpha train right-edge --end 2024-12-31 [--with-fib-features] [--write]. Promotion is gated by paired bootstrap on Brier score and per-degree ECE; only PROMOTE / PROMOTE_CALIBRATION verdicts write without --force.

Persistence

All user-facing state lives under ~/.wave_alpha/:

Path Purpose
config.yaml API key, model, prefs
cache.sqlite OHLCV bar cache
llm_cache.sqlite LLM response cache
history.sqlite Per-ticker snapshot history
watchlist.json Saved tickers
scans/<scan_id>.json Persisted scan reports

Development

uv sync --extra dev
uv run pytest                                    # full test suite
uv run pytest tests/elliott -k impulse           # filter by folder + name
uv run pytest tests/test_pipeline.py::test_x -x  # single test, fail fast
uv run ruff check .                              # lint
uv run ruff format .                             # format

Pattern definitions live in src/wave_alpha/elliott/templates_data/*.yaml — each lists waves and constraints with severity: hard | soft. Adding a pattern is a YAML drop-in (force-included in the wheel via pyproject.toml); no code change is needed unless new constraint operators are introduced.

Disclaimer

This software is for educational and research use only. It is not financial advice. See DISCLAIMER.md for the full text. By using wave-alpha you accept that trading decisions are solely your responsibility.

A short banner is shown on first CLI invocation. To suppress it (e.g. in CI), set WAVE_ALPHA_NO_DISCLAIMER=1.

License

Released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wave_alpha-0.7.0.tar.gz (1.1 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wave_alpha-0.7.0-py3-none-any.whl (260.5 kB view details)

Uploaded Python 3

File details

Details for the file wave_alpha-0.7.0.tar.gz.

File metadata

  • Download URL: wave_alpha-0.7.0.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wave_alpha-0.7.0.tar.gz
Algorithm Hash digest
SHA256 972709c3f9a8c688992d2058824cd4fd3184165cb0d0accf7a004b7f79ed4ac6
MD5 abfae394e1c5d941d9f395094a9f2592
BLAKE2b-256 8c744a57cb0caff870613cb134c7463d424895863665a26a126abc426f450861

See more details on using hashes here.

Provenance

The following attestation bundles were made for wave_alpha-0.7.0.tar.gz:

Publisher: publish.yml on chen-star/wave-alpha

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wave_alpha-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: wave_alpha-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 260.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wave_alpha-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aa316c9e5fac5e367b67641b5cc462be2e75ac7dfaaeeda9a0582395f747badd
MD5 2ccc14242bdff0a49ae747344daedda3
BLAKE2b-256 1db559186fc5b1732da054b2e68d148922c1d760a9a56f2c75a1e1f567768785

See more details on using hashes here.

Provenance

The following attestation bundles were made for wave_alpha-0.7.0-py3-none-any.whl:

Publisher: publish.yml on chen-star/wave-alpha

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page