{"id":50142086,"url":"https://github.com/kingchenc/wickra","last_synced_at":"2026-05-28T06:01:37.622Z","repository":{"id":359383796,"uuid":"1245836208","full_name":"kingchenc/wickra","owner":"kingchenc","description":"Streaming-first technical indicators with a Rust core and Python, Node.js, and WebAssembly bindings. 71 indicators, O(1) per-tick updates, no system dependencies. Drop-in TA-Lib replacement.","archived":false,"fork":false,"pushed_at":"2026-05-25T02:22:13.000Z","size":3194,"stargazers_count":1,"open_issues_count":14,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-25T03:28:13.406Z","etag":null,"topics":["algotrading","backtesting","bollinger-bands","cryptocurrency","finance","indicators","macd","napi-rs","nodejs","pyo3","python","quant","rsi","rust","streaming","ta-lib","technical-analysis","trading","wasm","webassembly"],"latest_commit_sha":null,"homepage":"https://github.com/kingchenc/wickra","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kingchenc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-21T15:50:53.000Z","updated_at":"2026-05-24T09:46:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kingchenc/wickra","commit_stats":null,"previous_names":["kingchenc/wickra"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/kingchenc/wickra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kingchenc%2Fwickra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kingchenc%2Fwickra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kingchenc%2Fwickra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kingchenc%2Fwickra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kingchenc","download_url":"https://codeload.github.com/kingchenc/wickra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kingchenc%2Fwickra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33503230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T03:12:49.672Z","status":"ssl_error","status_checked_at":"2026-05-26T03:12:47.976Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algotrading","backtesting","bollinger-bands","cryptocurrency","finance","indicators","macd","napi-rs","nodejs","pyo3","python","quant","rsi","rust","streaming","ta-lib","technical-analysis","trading","wasm","webassembly"],"created_at":"2026-05-24T02:02:42.396Z","updated_at":"2026-05-28T06:01:37.587Z","avatar_url":"https://github.com/kingchenc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wickra\n\n[![CI](https://github.com/kingchenc/wickra/actions/workflows/ci.yml/badge.svg)](https://github.com/kingchenc/wickra/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/kingchenc/wickra/branch/main/graph/badge.svg)](https://codecov.io/gh/kingchenc/wickra)\n[![crates.io](https://img.shields.io/crates/v/wickra.svg?logo=rust\u0026color=orange)](https://crates.io/crates/wickra)\n[![PyPI](https://img.shields.io/pypi/v/wickra.svg?logo=pypi\u0026color=blue)](https://pypi.org/project/wickra/)\n[![npm](https://img.shields.io/npm/v/wickra.svg?logo=npm\u0026color=red)](https://www.npmjs.com/package/wickra)\n[![License: PolyForm-NC](https://img.shields.io/badge/license-PolyForm--NC--1.0.0-purple)](LICENSE)\n\n**Streaming-first technical indicators. Install with `pip install wickra` — no system dependencies.**\n\nWickra is a multi-language technical-analysis library with a Rust core and\nbindings for Python, Node.js, and WebAssembly. Every indicator is a state\nmachine that updates in O(1) per new data point, so live trading bots and\nhistorical backtests share the exact same implementation.\n\n```python\nimport numpy as np\nimport wickra as ta\n\n# Batch: classic TA-Lib-style usage\nprices = np.linspace(100, 200, 1000)\nrsi = ta.RSI(14)\nvalues = rsi.batch(prices)              # numpy array, NaN during warmup\n\n# Streaming: same indicator, fed tick by tick\nrsi = ta.RSI(14)\nfor price in live_feed:\n    value = rsi.update(price)           # O(1) — no recomputation over history\n    if value is not None and value \u003e 70:\n        print(\"overbought\")\n```\n\n## Why Wickra exists\n\nThe Python TA ecosystem has plenty of libraries — TA-Lib, pandas-ta, finta,\ntalipp, tulipy — and every one of them shares the same blind spot:\n\n| Library                | Install pain    | Streaming | Multi-language | Active |\n|------------------------|-----------------|-----------|----------------|--------|\n| **★\u0026nbsp;Wickra**      | **clean**       | **yes**   | **Python + Node + WASM + Rust** | **yes** |\n| TA-Lib (Python)        | yes (C deps)    | no        | no             | barely |\n| pandas-ta              | clean           | no        | no             | slow   |\n| finta                  | clean           | no        | no             | stale  |\n| ta-lib-python          | yes (C deps)    | no        | no             | barely |\n| talipp                 | clean           | yes       | no             | yes    |\n| Tulip Indicators       | yes (C deps)    | no        | partial        | stale  |\n| ooples (C#)            | clean           | no        | C# only        | yes    |\n\nWickra is the only library that combines all of: clean install, streaming,\nmulti-language reach, and active maintenance.\n\n## Benchmark: how much faster is \"streaming-first\"?\n\nThe numbers below were measured on a single developer workstation and are not\nguaranteed to reproduce identically on different hardware — absolute µs values\ndepend on CPU, memory clock and OS scheduler. Read them as **relative\nspeedups** between libraries on identical input, not as a universal\nperformance contract.\n\n- **Reproduced on:** Windows 11 Pro 26200, AMD Ryzen 9 7950X3D, 64 GB DDR5,\n  Rust 1.92 (release profile, `lto = \"fat\"`, `codegen-units = 1`),\n  Python 3.12, Node 20.\n- **Reproduce yourself:** `pip install -e bindings/python[bench]` then\n  `python -m benchmarks.compare_libraries`. The script auto-detects every\n  installed peer library and runs them on the same generated inputs as\n  Wickra. The CI job `cross-library-bench` runs the same script on every\n  push and uploads the raw report as a build artefact.\n\nLower µs/op = faster. Wickra wins every batch category outright, and the\nstreaming gap widens linearly with how much history a batch-only library has\nto recompute on every tick.\n\n### Batch — single full pass over a 20 000-bar series\n\nReading the table: each cell shows that library's runtime, plus how many times\nslower it is than Wickra in parentheses. **★** marks the winner per row.\n\n| Indicator           | **★\u0026nbsp;Wickra**   | finta                       | talipp                        |\n|---------------------|---------------------|-----------------------------|-------------------------------|\n| SMA(20)             | **95.6 µs ★**       | 343.5 µs (3.6× slower)      | 7 640.6 µs (79.9× slower)     |\n| EMA(20)             | **64.6 µs ★**       | 223.1 µs (3.5× slower)      | 12 160.9 µs (188.2× slower)   |\n| RSI(14)             | **126.2 µs ★**      | 1 107.1 µs (8.8× slower)    | 15 792.2 µs (125.1× slower)   |\n| MACD(12, 26, 9)     | **119.0 µs ★**      | 531.8 µs (4.5× slower)      | 49 788.1 µs (418.2× slower)   |\n| Bollinger(20, 2.0)  | **105.3 µs ★**      | 812.0 µs (7.7× slower)      | 130 938.3 µs (1 243.7× slower)|\n| ATR(14)             | **123.5 µs ★**      | 5 144.8 µs (41.7× slower)   | 28 816.0 µs (233.4× slower)   |\n\n### Streaming — per-tick latency after seeding with 5 000 historical bars\n\nA batch-only library has to re-run its full indicator over the entire history on\nevery new tick; Wickra updates state in O(1).\n\n| Indicator | **★\u0026nbsp;Wickra (per tick)** | talipp (per tick)         |\n|-----------|---------------------|---------------------------|\n| RSI(14)   | **0.119 µs ★**      | 1.644 µs (13.8× slower)   |\n\n\u003e TA-Lib and pandas-ta are not included here because both fail to install\n\u003e cleanly on Windows without C build tooling — which is precisely the install\n\u003e pain Wickra was built to remove. The benchmark script auto-detects every\n\u003e peer library it can find and runs them on the same inputs as Wickra; install\n\u003e them in your environment to see those rows light up too.\n\nRun the suite yourself:\n\n```bash\npip install -e bindings/python[bench]\npython -m benchmarks.compare_libraries\n```\n\n## Indicators\n\n71 streaming-first indicators across eight families. Every one passes the\n`batch == streaming` equivalence test, reference-value tests, and reset\nsemantics tests.\n\n| Family | Indicators |\n|--------|-----------|\n| Moving Averages      | SMA, EMA, WMA, DEMA, TEMA, HMA, KAMA, SMMA, TRIMA, ZLEMA, T3, VWMA |\n| Momentum Oscillators | RSI (Wilder), Stochastic, CCI, ROC, Williams %R, MFI, Awesome Oscillator, MOM, CMO, TSI, PMO, StochRSI, Ultimate Oscillator |\n| Trend \u0026 Directional  | MACD, ADX (+DI/-DI), Aroon, TRIX, Aroon Oscillator, Vortex, Mass Index, Choppiness Index, Vertical Horizontal Filter |\n| Price Oscillators    | PPO, DPO, Coppock, Accelerator Oscillator, Balance of Power |\n| Volatility \u0026 Bands   | ATR, Bollinger Bands, Keltner Channels, Donchian Channels, NATR, StdDev, Ulcer Index, Historical Volatility, Bollinger Bandwidth, %B, True Range, Chaikin Volatility |\n| Trailing Stops       | Parabolic SAR, SuperTrend, Chandelier Exit, Chande Kroll Stop, ATR Trailing Stop |\n| Volume               | OBV, VWAP (cumulative + rolling), ADL, Volume-Price Trend, Chaikin Money Flow, Chaikin Oscillator, Force Index, Ease of Movement |\n| Price Statistics     | Typical Price, Median Price, Weighted Close, Linear Regression, Linear Regression Slope, Z-Score, Linear Regression Angle |\n\nAdding a new indicator means implementing one trait in Rust; all four bindings\ninherit it automatically.\n\n## Languages\n\n| Binding           | Install                                       | Example |\n|-------------------|-----------------------------------------------|---------|\n| Python (PyO3)     | `pip install wickra`                          | `examples/python/backtest.py` |\n| Node.js (napi-rs) | `npm install wickra`                          | `examples/node/backtest.js` |\n| Browser / WASM    | `npm install wickra-wasm`                     | `examples/wasm/index.html` |\n| Rust              | `cargo add wickra`                            | `examples/rust/src/bin/backtest.rs` |\n\nEach binding ships several runnable examples (streaming, backtest, live feed);\n[`examples/README.md`](examples/README.md) is the full cross-language index.\n\nThe wickra-core crate is `unsafe`-forbidden, so every binding inherits a\nmemory-safe implementation.\n\n## Rust API\n\n```rust\nuse wickra::{Indicator, BatchExt, Chain, Ema, Rsi, Sma};\n\n// Streaming or batch — same trait, same code.\nlet mut sma = Sma::new(14)?;\nlet out: Vec\u003cOption\u003cf64\u003e\u003e = sma.batch(\u0026[1.0, 2.0, 3.0, 4.0, 5.0]);\n\nlet mut rsi = Rsi::new(14)?;\nfor price in live_feed {\n    if let Some(v) = rsi.update(price) {\n        println!(\"RSI = {v}\");\n    }\n}\n\n// Compose indicators: RSI(7) on top of EMA(14).\nlet mut chain = Chain::new(Ema::new(14)?, Rsi::new(7)?);\nchain.update(price);\n```\n\n## Live data sources\n\n`wickra-data` (separate crate, opt-in) ships:\n\n- A streaming OHLCV **CSV reader**.\n- A **tick-to-candle aggregator** with arbitrary timeframes.\n- A **candle resampler** for multi-timeframe analysis (1m → 5m → 1h on the fly).\n- A **Binance Spot WebSocket** kline adapter (feature `live-binance`).\n\n```rust\nuse wickra::{Indicator, Rsi};\nuse wickra_data::live::binance::{BinanceKlineStream, Interval};\n\nlet mut stream = BinanceKlineStream::connect(\u0026[\"BTCUSDT\".into()], Interval::OneMinute).await?;\nlet mut rsi = Rsi::new(14)?;\nwhile let Some(event) = stream.next_event().await? {\n    if event.is_closed {\n        if let Some(v) = rsi.update(event.candle.close) {\n            println!(\"RSI = {v:.2}\");\n        }\n    }\n}\n```\n\nA Python live-trading example using the public `websockets` package lives at\n`examples/python/live_trading.py`.\n\n## Project layout\n\n```\nwickra/\n├── crates/\n│   ├── wickra-core/         core engine + all 71 indicators\n│   ├── wickra/              top-level facade crate (publishes on crates.io) + benches/\n│   └── wickra-data/         CSV reader, tick aggregator, live exchange feeds\n├── bindings/\n│   ├── python/              PyO3 + maturin (publishes on PyPI)\n│   ├── node/                napi-rs (publishes on npm)\n│   └── wasm/                wasm-bindgen (browsers, bundlers, Node)\n├── examples/                examples/README.md indexes every language\n│   ├── data/                real BTCUSDT OHLCV datasets, one per timeframe\n│   ├── rust/                Rust workspace member (`wickra-examples`)\n│   ├── python/              backtest, live trading, parallel assets, multi-tf\n│   ├── node/                streaming, backtest, live trading (load `wickra`)\n│   └── wasm/                browser demo for `wickra-wasm`\n└── .github/workflows/       CI and release pipelines\n```\n\nRust benchmarks live in `crates/wickra/benches/`; runnable Rust examples live\nin the workspace member crate at `examples/rust/`. There is no top-level\n`benches/` directory.\n\n## Building everything from source\n\n```bash\n# Rust core + tests\ncargo test --workspace\ncargo clippy --workspace --all-targets -- -D warnings\ncargo bench -p wickra\n\n# Python binding (requires Rust toolchain + maturin)\ncd bindings/python\nmaturin develop --release\npytest\n\n# WASM binding (requires wasm-pack + wasm32-unknown-unknown target)\nwasm-pack build bindings/wasm --target web --release --features panic-hook\n\n# Node binding (requires @napi-rs/cli)\ncd bindings/node \u0026\u0026 npm install \u0026\u0026 npm run build \u0026\u0026 npm test\n```\n\n## Testing\n\nEvery layer is covered; run the suites with the commands in\n[Building everything from source](#building-everything-from-source).\n\n- `wickra-core`: unit tests per indicator — textbook reference values\n  (Wilder RSI, Bollinger Bands, MACD, ATR, Stochastic), `batch == streaming`\n  equivalence, `reset` semantics, NaN/Inf handling, and property tests.\n- `wickra-data`: unit tests for CSV decoding, the tick aggregator, the\n  resampler, and the Binance payload parser.\n- `bindings/python`: pytest covering smoke checks, streaming/batch\n  equivalence, reference values, lifecycle, input validation, and\n  dict/tuple candle inputs.\n- `bindings/node`: `node --test` cases for batch, streaming, and reference\n  values across all indicators.\n- `bindings/wasm`: `wasm-bindgen-test` cases for constructors, equivalence,\n  and reference values.\n\n## Contributing\n\nContributions are very welcome — issues, bug reports, ideas, and pull requests\nall land in the same place: \u003chttps://github.com/kingchenc/wickra\u003e.\n\nA short orientation for first-time contributors:\n\n- **Adding an indicator.** Implement the `Indicator` trait in\n  `crates/wickra-core/src/indicators/\u003cname\u003e.rs`, wire it into\n  `indicators/mod.rs` and the crate root, and add reference-value tests,\n  a `batch == streaming` equivalence test, and (where it makes sense) a\n  proptest. The four bindings inherit your indicator automatically once\n  you expose it in the language wrappers.\n- **Fixing a numeric bug.** Add a failing test that pins the textbook value\n  first, then fix the math. Property tests in `crates/wickra-core` catch\n  most regressions; please don't disable them.\n- **Improving a binding.** Each binding lives under `bindings/\u003clang\u003e` with\n  its own tests; please keep the `batch == streaming` invariant.\n- **Style.** `cargo fmt --all` + `cargo clippy --workspace --all-targets -- -D warnings`\n  are CI gates; running them locally before pushing keeps reviews short.\n\nFor larger architectural changes, open an issue first so we can sketch the\nshape together before you invest the time.\n\n## License\n\nLicensed under the **PolyForm Noncommercial License 1.0.0**. See [LICENSE](LICENSE).\n\nIn plain English: use it, fork it, modify it, redistribute it, file issues, send\npull requests — all welcome. Personal projects, research, education, non-profits,\ngovernment, hobby trading bots: all fine. The one thing that's not allowed is\ncommercial sale of the software or of services built around it. If you want to\nuse Wickra commercially, get in touch about a license.\n\n## Disclaimer\n\nWickra is an indicator toolkit, not a trading system. Values it computes are\ndeterministic transforms of the input data — they are not financial advice and\nthey do not predict the market. Any use of this library in a production\ntrading context is at your own risk.\n\nThe library is provided **as is**, without warranty of any kind; see\n[LICENSE](LICENSE) for the full terms.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/kingchenc/wickra/stargazers\"\u003e\n    \u003cimg alt=\"GitHub stars\" src=\"https://img.shields.io/github/stars/kingchenc/wickra?style=for-the-badge\u0026logo=github\u0026logoColor=white\u0026color=ffd866\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/kingchenc/wickra/network/members\"\u003e\n    \u003cimg alt=\"GitHub forks\" src=\"https://img.shields.io/github/forks/kingchenc/wickra?style=for-the-badge\u0026logo=github\u0026logoColor=white\u0026color=78dce8\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/kingchenc/wickra/issues\"\u003e\n    \u003cimg alt=\"GitHub issues\" src=\"https://img.shields.io/github/issues/kingchenc/wickra?style=for-the-badge\u0026logo=github\u0026logoColor=white\u0026color=ff6188\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  If Wickra saved you time, the cheapest way to say thanks is to ⭐ the repo.\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkingchenc%2Fwickra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkingchenc%2Fwickra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkingchenc%2Fwickra/lists"}