Commit Graph
5 Commits
Author SHA1 Message Date
kingchencandGitHub aacb9280f1 Honest tiered cross-library benchmark + streaming/batch perf (#186)
## Summary

An honest, tiered cross-library benchmark — and the optimization pass it triggered.

### Performance (wickra-core, outputs unchanged)
Profiling against the other Rust TA crates exposed real inefficiencies. Each
benchmarked indicator is now **5–79% faster** in both streaming and batch:

- **SMA, Bollinger**: flat `Box<[f64]>` ring buffers replace `VecDeque` (−69…79%).
- **RSI**: `100·ag/(ag+al)` collapses three divisions into one; Wilder smoothing
  hoists `1/period` out of the hot path (−46%).
- **ATR**: reciprocal hoisted (−42%).
- **EMA/RSI/ATR**: per-tick `Option<f64>` hot state → bare `f64` + ready flag.

Net result vs `kand`: Wickra now wins **RSI, Bollinger and ATR** (streaming), and
ties `ta-rs` on SMA — up from losing every indicator 1.5–6× before.

### Benchmark harness
New `crates/wickra-bench` (publish=false): a Criterion benchmark comparing Wickra
against `kand`, `ta-rs` and `yata` on an identical BTCUSDT candle series, in
streaming and batch modes. Peer APIs were verified against their source, not
guessed. Wired into the nightly `cross-library-bench` workflow as a separate job.

### Honest README
The benchmark section is rewritten into three layered tables (Rust core vs Rust
crates; Python vs the Python ecosystem) that **show the losses as well as the
wins**. The "only library that combines…" claim is gone; the new framing is
breadth + multi-language reach + the deliberate safety trade-off that costs raw
speed. Added an origin/why-slower rationale and a star CTA.

### Python benchmark
Added `tulipy` runners and expanded per-tick streaming coverage to SMA/EMA/RSI/
MACD/Bollinger. `bench.in`/`bench.txt` now lock `TA-Lib` + `tulipy` (hash-pinned);
`pandas-ta` stays out (it requires Python ≥ 3.12, the bench runs on 3.11).

### Notes
- TA-Lib/tulipy numbers in the README Python table are marked ⧗ — they are
  produced by the CI Linux job (C extensions don't build cleanly on every
  desktop), not measured locally.
- The matching `wickra-docs` prose update is committed separately and will be
  pushed with the release, per the docs-don't-lead-the-registries rule.

Verified locally: `cargo fmt`, `cargo test --workspace --all-features` (3413 core
+ bindings), `cargo clippy --workspace --all-targets --all-features -D warnings`,
Node build + 498 tests, and pytest all green.
2026-06-06 20:57:31 +02:00
kingchencandGitHub adc8488939 test: 100% coverage for ema + historical_volatility + kama + linreg_angle + mass_index (#24)
* test(ema): cover period accessor + warmup/name metadata

Codecov flagged 9 lines in crates/wickra-core/src/indicators/ema.rs
(file at 94.03%): const accessor period (74-77), Indicator-impl
warmup_period (123-125), name (131-133). ema.rs now at 151/151.

* test(historical_volatility): cover periods/value accessors + name metadata

Codecov flagged 9 lines in crates/wickra-core/src/indicators/historical_volatility.rs
(file at 93.87%): const accessors periods (80-83), value (85-88) and
Indicator-impl name (153-155). historical_volatility.rs now at 147/147.

* test(kama): cover periods accessor + warmup/name metadata

Codecov flagged 9 lines in crates/wickra-core/src/indicators/kama.rs
(file at 91.26%): accessor periods (65-67), Indicator-impl
warmup_period (115-117), name (123-125). kama.rs now at 103/103.

* test(linreg_angle): cover period accessor + warmup/name metadata

Codecov flagged 9 lines in crates/wickra-core/src/indicators/linreg_angle.rs
(file at 88.15%): const accessor period (50-52), Indicator-impl
warmup_period (67-69), name (75-77). linreg_angle.rs now at 76/76.

* test(mass_index): cover periods/value accessors + name metadata

Codecov flagged 9 lines in crates/wickra-core/src/indicators/mass_index.rs
(file at 91.42%): const accessors periods (80-82), value (85-87) and
Indicator-impl name (134-136). mass_index.rs now at 105/105.
2026-05-24 00:48:35 +02:00
kingchenc 4b3227a15f E15: add a runnable doctest to every indicator type
Only two doctests existed in wickra-core; none of the 25 indicator
types carried a runnable rustdoc example.

Add an "# Example" doctest to every public indicator type (all 26,
including RollingVwap): construct the indicator and stream 80 inputs
through update, asserting a value is produced. The candle-input
indicators build valid OHLCV candles inline. cargo test --doc
-p wickra-core now runs 28 doctests, all passing; fmt and clippy clean.
2026-05-22 16:41:43 +02:00
kingchenc 5627612d44 A3: close core test-coverage gaps
Adds the reset tests the audit named as missing (aroon, awesome
oscillator, donchian, keltner, williams_r, and both VWAP variants),
non-finite-input tests for every scalar indicator that guards is_finite
(WMA, RSI, MACD, Bollinger, KAMA), and naive-reference proptests for EMA,
RSI and ATR. 189 core tests pass.
2026-05-22 03:34:19 +02:00
kingchenc 3be267cb03 Wickra 0.1.0: streaming-first technical indicators
A multi-language technical analysis library: 25 indicators across trend,
momentum, volatility, and volume families, every one a state machine with
O(1) per-tick updates. Batch evaluation is provided by a blanket extension
trait over the streaming primitive, so live trading bots and historical
backtests run the same code path.

What ships in this initial drop:

  crates/wickra-core   - 25 indicators, Indicator/BatchExt/Chain traits,
                          OHLCV types with validation; 171 unit tests,
                          property tests, Wilder/Bollinger textbook tests.
  crates/wickra        - top-level facade + criterion benches for every
                          indicator at 1K/10K/100K series sizes.
  crates/wickra-data   - streaming CSV reader, tick-to-candle aggregator,
                          multi-timeframe resampler, Binance Spot kline
                          WebSocket adapter behind feature live-binance;
                          11 unit + 1 doctest.
  bindings/python      - PyO3 + maturin, NumPy I/O, type stubs (.pyi),
                          56 pytest tests including streaming==batch
                          equivalence, Wilder reference values, lifecycle.
  bindings/node        - napi-rs native module, TypeScript .d.ts
                          auto-generated, 7 node --test cases.
  bindings/wasm        - wasm-bindgen ES module for browser/bundler/Node;
                          interactive HTML demo at examples/index.html.
  examples/            - Python and Rust scripts: backtest, live trading,
                          parallel multi-asset, multi-timeframe, Binance.
  benchmarks/          - cross-library comparison against TA-Lib,
                          pandas-ta, finta, talipp; Wickra wins every
                          category by 11-1030x (batch) and 17x+ streaming.
  .github/workflows/   - CI matrix (Rust + Python + Node + WASM on
                          Linux/macOS/Windows), release pipeline for
                          PyPI wheels and npm.

Indicators (25):
  Trend       SMA EMA WMA DEMA TEMA HMA KAMA
  Momentum    RSI MACD Stochastic CCI ROC WilliamsR ADX MFI TRIX
              AwesomeOscillator Aroon
  Volatility  BollingerBands ATR Keltner Donchian PSAR
  Volume      OBV VWAP (cumulative + rolling)

cargo clippy --workspace --all-targets -D warnings is clean. License: Apache-2.0.
2026-05-21 17:50:45 +02:00