e97c3389fe
Adds five support/resistance and pivot indicators, growing the catalog 462 -> 467. ## Indicators - **CentralPivotRange** (Candle -> struct) — the classic pivot `(H+L+C)/3` flanked by two central levels (TC/BC); range width gauges trending vs balanced days. - **MurreyMathLines** (Candle -> struct) — T. H. Murrey's eighths grid over a rolling high-low frame; nine levels (0/8 .. 8/8) acting as support/resistance. - **AndrewsPitchfork** (Candle -> struct) — median line and two parallels projected forward from the last three auto-detected swing pivots (symmetric fractal of half-width `strength`). - **VolumeWeightedSr** (Candle -> struct) — a band whose edges are the volume-weighted average of recent highs (resistance) and lows (support); falls back to equal weighting when window volume is zero. - **PivotReversal** (Candle -> f64) — a `+1`/`-1` breakout signal fired on the bar where price closes through the most recently confirmed swing pivot. ## Wiring Core structs with branch-complete unit tests, Python/Node/WASM bindings, fuzz drives, reference + streaming-vs-batch tests, README + docs counter sync (FAMILIES "Pivots & S/R"), and CHANGELOG entries. Verified locally: `cargo fmt`, `cargo test -p wickra-core` (3798 lib + 425 doc), `cargo clippy --workspace --all-targets --all-features -D warnings`, `npm run build && npm test` (542), `maturin develop` + `pytest` (891).
Fuzzing Wickra
cargo-fuzz harnesses for
the parsing and stateful entry points of Wickra. Fuzzing requires a nightly
Rust toolchain.
Setup
cargo install cargo-fuzz
rustup toolchain install nightly
Targets
| Target | What it exercises |
|---|---|
csv_reader |
CandleReader over arbitrary bytes — headers, cells, BOM, binary noise. |
binance_envelope |
RawWsEnvelope deserialization from arbitrary strings. |
indicator_update |
Every scalar-input indicator (SMA / EMA / WMA / RSI / DEMA / TEMA / HMA / ROC / TRIX / SMMA / TRIMA / ZLEMA / KAMA / T3 / MOM / CMO / TSI / PMO / StochRSI / DPO / PPO / Coppock / StdDev / UlcerIndex / HistoricalVolatility / LinearRegression / LinRegSlope / LinRegAngle / VHF / ZScore / MACD / Bollinger) streamed + batched over arbitrary f64 sequences (NaN, ±inf, jumps). |
indicator_update_candle |
Every candle-input indicator (ATR, NATR, TrueRange, ChaikinVolatility, Keltner, Donchian, PSAR, SuperTrend, ChandelierExit, ChandeKrollStop, ATRTrailingStop, ADX, Aroon, AroonOscillator, Vortex, MassIndex, ChoppinessIndex, CCI, WilliamsR, AwesomeOscillator, AcceleratorOscillator, UltimateOscillator, BalanceOfPower, OBV, MFI, VWAP, RollingVWAP, VWMA, ADL, VPT, CMF, ChaikinOscillator, ForceIndex, EaseOfMovement, TypicalPrice, MedianPrice, WeightedClose, Stochastic) streamed + batched over fuzz-derived OHLCV candles. |
tick_aggregator |
TickAggregator over arbitrary (price, volume, timestamp) triples. |
Run
# From the repository root:
cargo +nightly fuzz run csv_reader
cargo +nightly fuzz run binance_envelope
cargo +nightly fuzz run indicator_update
cargo +nightly fuzz run indicator_update_candle
cargo +nightly fuzz run tick_aggregator
Each run continues until a crash is found or it is interrupted. A short time-boxed smoke run is useful in CI:
cargo +nightly fuzz run csv_reader -- -max_total_time=60
The expectation for every target is that it never panics: malformed or
adversarial input must surface as an Err, never a crash.