* test(wma): cover period/warmup/name + kill dead naive panic arm
Codecov flagged 10 lines in crates/wickra-core/src/indicators/wma.rs
(file at 92.48%): const accessor period (56-58), Indicator-impl
warmup_period (111-113), name (119-121), and line 186 — the
`_ => panic!("warmup mismatch")` arm in matches_naive_over_random_
inputs, an invariant guard that never fires when both streams share
a warmup period.
Add accessors_and_metadata covering the three metadata methods.
Refactor matches_naive_over_random_inputs to assert the warmup-shape
invariant via assert_eq!(g.is_some(), w.is_some()) + if let,
removing the dead panic arm.
wma.rs is now at 133/133 lines, no behavioural change.
* test(aroon_oscillator): cover period/value accessors + name metadata
Codecov flagged 9 lines in crates/wickra-core/src/indicators/aroon_
oscillator.rs (file at 90.42%): const accessors period (57-59),
value (62-64) and Indicator-impl name (90-92). warmup_period is
already covered by warmup_period_matches_aroon.
Add accessors_and_metadata asserting period == 7, name ==
"AroonOscillator", and value() across the None (pre-warmup) and
Some (post-warmup) branches.
aroon_oscillator.rs is now at 94/94 lines, no behavioural change.
* test(atr): cover period/value accessors + name metadata
Codecov flagged 9 lines in crates/wickra-core/src/indicators/atr.rs
(file at 93.70%): const accessors period (54-57), value (59-62) and
Indicator-impl name body (103-105). warmup_period is exercised
indirectly via downstream indicators; the metadata getters were
never queried directly.
Add accessors_and_metadata asserting period == 14, name == "ATR",
and value() across the None (pre-warmup) and Some (post-warmup)
branches.
atr.rs is now at 143/143 lines, no behavioural change.
* test(awesome_oscillator): cover periods accessor + warmup/name metadata
Codecov flagged 9 lines in crates/wickra-core/src/indicators/awesome_
oscillator.rs (file at 88.15%): const accessor periods (59-61),
Indicator-impl warmup_period (83-85), name (91-93). The classic()
constructor is covered indirectly through the existing tests; only
the metadata methods were dead.
Add accessors_and_metadata asserting periods == (5, 34),
warmup_period == 34 (= slow_period), name == "AwesomeOscillator".
awesome_oscillator.rs is now at 76/76 lines, no behavioural change.
* test(cci): cover period accessor + warmup/name metadata
Codecov flagged 9 lines in crates/wickra-core/src/indicators/cci.rs
(file at 89.65%): const accessor period (68-70), Indicator-impl
warmup_period (102-104), name (110-112). Existing tests never
inspected the metadata surface.
Add accessors_and_metadata asserting period == 20, warmup_period ==
20, name == "CCI".
cci.rs is now at 87/87 lines, no behavioural change.
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.
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.