QuantWave is a high-performance, Polars-native technical analysis library for Rust. It extends talib-rs-core with modern indicators, Ehlers DSP suites, and ML feature engineering tools, ensuring bit-identical results between batch processing (Polars) and real-time streaming.
The project is structured as a Rust workspace to maximize modularity and performance:
quantwave-core: The engine containing core traits (Next<T>), state machines, and streaming implementations.quantwave-polars: High-level Polars integration providing the.ta()namespace on LazyFrames and Series.quantwave-backtest: Vectorized/streaming backtest engine + performance metrics.quantwave-py: The single PyO3 (abi3) extension. One cdylib exposes the indicator classes/batch fns (quantwave._quantwave), the backtest bindings (quantwave._backtest), and the native#[polars_expr]plugins behind thepl.col().tanamespace. Built with onematurin build→ onecp39-abi3wheel (no wheel-merge step).
- Rust (2024 edition)
cargo-expand(recommended for macro debugging)
- Build All:
cargo build - Test All:
cargo nextest run(MANDATORY: Use nextest only) - Install pre-push gate:
./scripts/install-git-hooks.sh— runs verify before each push (CI runs fast doc/metadata sanity only) - Verify (full gate):
./scripts/quantwave_verify.sh— metadata drift + nextest + pytest smoke (cached viascripts/verify_cache.py;VERIFY_NO_CACHE=1to force) (cached viascripts/verify_cache.py;VERIFY_NO_CACHE=1to force) - Run Benchmarks:
cargo bench - Check Linting:
cargo clippy - Check Formatting:
./scripts/rustfmt_check.sh—⚠️ nevercargo fmt --all.quantwave-core/src/options_india/iv_solver.rsholds Horner-form polynomial approximations (~12 levels of nested parens on 500-char lines) that make rustfmt spin at 100% CPU indefinitely. rustfmt followsmoddeclarations, sosrc/lib.rsandoptions_india/mod.rsinherit the hang and the whole crate becomes unformattable via cargo. This script batches and skips those paths — full workspace in ~1.2s. Interruptedcargo fmtruns leave orphaned rustfmt children burning CPU; clean up withpkill -f "bin/rustfmt"; pkill -f cargo-fmt.
Every indicator must implement the Next<Input> trait. This single source of mathematical truth powers both the streaming structs and the Polars plugins.
- Streaming-Batch Parity: Every indicator must have a
proptestthat assertsBatch(data) == Streaming.collect(data)usingapproxtolerances. - Gold Standard: Reference data is stored in
quantwave-core/tests/gold_standard/*.json. All implementations must match these industry-standard vectors. - Tests Location: ALL integration tests and gold standard files MUST reside in
quantwave-core/tests/. Root-leveltests/folders are prohibited. - SOURCE of calculation for all indicators must be recorded. IF you do not have a source do not assume, validate with the human before assuming the source. Research and give options for source.
When implementing indicators, refer to the following authoritative sources for calculation logic and edge-case handling:
- TradingView (Pine Script): De facto standard for retail algorithmic trading.
- Devexperts: https://devexperts.com/dxcharts/kb/docs/indicators
- Sierra Chart: https://www.sierrachart.com/index.php?page=doc/TechnicalStudiesReference.php
- QuantConnect: https://www.quantconnect.com/docs/v2/writing-algorithms/indicators/supported-indicators/wave-trend-oscillator
- MQL5: https://www.mql5.com/en/articles/indicators
- StockCharts: https://chartschool.stockcharts.com/table-of-contents/overview
Prioritize generic, extensible components. For example, moving averages should support swappable smoothing algorithms (SMA, EMA, HMA) via the SmoothingAlgorithm trait.
- Use Polars Expression Plugins for all custom vectorized logic.
- Avoid memory copies; operate directly on Arrow buffers.
- Leverage
talib-rs-core's SIMD-optimized foundations for classic indicators.
- Initialize workspace and foundational traits.
- Implement
SuperTrendas the "Steel Thread" indicator. - Establish the
gold_standardtesting infrastructure.
This project uses br (beads_rust) for issue tracking. br replaced bd
(beads/Dolt) on 2026-07-26 after the bd Dolt store's journal became
corrupted; issues were recovered from a pre-corruption JSONL export and
migrated into br's SQLite + JSONL store. bd's original data is preserved
(not deleted) in .beads.bak-20260726-092341/ and
.beads.bd-legacy-20260726/ at the repo root.
- Run
br robot-docs guidefor workflow context and command guidance. - Use
br ready,br show <id>,br update <id> --claim, andbr close <id>. - br has no
bd rememberequivalent; usebr create --type task(or a comment viabr comments add <id>) to persist project memory instead of MEMORY.md files. - Do not use markdown TODO lists for task tracking.
- br is non-invasive: it never commits, pushes, pulls, or installs git hooks on its own. After mutating commands (which auto-flush
.beads/issues.jsonlby default), remember togit add .beads/ && git commityourself when you want the JSONL export captured in git history.
IMPORTANT: This project uses br (beads_rust) for ALL issue tracking. Do NOT use markdown TODOs, task lists, or other tracking methods.
- Dependency-aware: Track blockers and relationships between issues
- Git-friendly: SQLite (fast local queries) + JSONL export (clean git diffs/merges)
- Agent-optimized: JSON output (
--jsoneverywhere), ready work detection, discovered-from links,br robot-docs - Prevents duplicate tracking systems and confusion
Check for ready work:
br ready --jsonCreate new issues:
br create "Issue title" --description="Detailed context" -t bug|feature|task -p 0-4 --json
br create "Issue title" --description="What this issue is about" -p 1 --deps discovered-from:quantwave-123 --jsonClaim and update:
br update <id> --status in_progress --json
br update quantwave-42 --priority 1 --jsonComplete work:
br close quantwave-42 --reason "Completed" --jsonbug- Something brokenfeature- New functionalitytask- Work item (tests, docs, refactoring)epic- Large feature with subtaskschore- Maintenance (dependencies, tooling)
0- Critical (security, data loss, broken builds)1- High (major features, important bugs)2- Medium (default, nice-to-have)3- Low (polish, optimization)4- Backlog (future ideas)
- Check ready work:
br readyshows unblocked issues - Claim your task atomically:
br update <id> --claim - Work on it: Implement, test, document
- Reference Management: When a task is completed, move the source paper/documentation from the original folder to the
implemented/subfolder (e.g.,references/Ehlers Papers/implemented/). - Discover new work? Create linked issue:
br create "Found bug" --description="Details about what was found" -p 1 --deps discovered-from:<parent-id>
- Complete:
br close <id> --reason "Done"
Unlike bd (which auto-committed to a Dolt server), br never touches git on its own:
- Mutating commands (
create,update,close,dep add, ...) auto-flush.beads/issues.jsonllocally by default. - Nothing is committed or pushed until you run
git add .beads/ && git commityourself. - Run
br sync --flush-onlyas an idempotent final export check before staging.beads/(useful after--no-auto-flushruns or before landing the plane). - There is no
bd dolt push/bd dolt pullequivalent — plaingit push/git pullon.beads/issues.jsonlis the sync mechanism now.
- ✅ Use br for ALL task tracking
- ✅ Always use
--jsonflag for programmatic use - ✅ Link discovered work with
discovered-fromdependencies - ✅ Check
br readybefore asking "what should I work on?" - ✅
git add .beads/ && git commitafter issue-tracker mutations you want preserved — br will not do this for you - ❌ Do NOT create markdown TODO lists
- ❌ Do NOT use external issue trackers
- ❌ Do NOT duplicate tracking systems
For more details, see README.md and docs/QUICKSTART.md.
When ending a work session, you MUST complete ALL steps below. Work is NOT complete until git push succeeds.
MANDATORY WORKFLOW:
- File issues for remaining work - Create issues for anything that needs follow-up
- Run quality gates (if code changed) - Tests, linters, builds
- Update IndicatorMetadata for Rust indicators — If any new indicator is added or an existing one is significantly changed (in
quantwave-core/src/indicators/or related), you MUST create or update itsXXX_METADATAconstant (of typeIndicatorMetadata) in the same session. This metadata is the single source of truth consumed by documentation (mkdocs) and the Python package. See taskquantwave-i9dn. - Update issue status - Close finished work, update in-progress items
- PUSH TO REMOTE - This is MANDATORY:
git pull --rebase br sync --flush-only git add .beads/ && git commit -m "sync beads" || true # no-op if nothing changed git push git status # MUST show "up to date with origin"
- Clean up - Clear stashes, prune remote branches
- Verify - All changes committed AND pushed
- Hand off - Provide context for next session
CRITICAL RULES:
-
Work is NOT complete until
git pushsucceeds -
NEVER stop before pushing - that leaves work stranded locally
-
NEVER say "ready to push when you are" - YOU must push
-
If push fails, resolve and retry until it succeeds
-
IndicatorMetadata rule (quantwave-i9dn): Adding or modifying any Rust indicator without also creating/updating its
IndicatorMetadata(theXXX_METADATAconstant) is not permitted. This metadata is the source of truth for both documentation and Python DX. It must be done as part of landing the plane, beforegit push. See taskquantwave-i9dn.