feat(patterns): add the Chart Patterns family (8 swing-based detectors) (#166)

## Summary

Adds a new **Chart Patterns** indicator family (counter 351 → 359, families 21 → 22), the first half of the A4 roadmap item (the harmonic patterns follow in a second PR).

All eight detectors are built on a shared, non-repainting swing-pivot tracker — the internal, **uncounted** `indicators::pattern_swing` module (declared `pub(crate) mod`, re-exported nowhere). Each consumes candles and emits the uniform pattern sign convention already used by the candlestick family — `+1.0` bullish / `-1.0` bearish / `0.0` otherwise, never `None`. They are parameter-free, baking the swing threshold (5%) and level tolerance (3%) in as documented constants, mirroring how candlestick patterns bake in their geometric thresholds.

## Detectors

| Indicator | Signal |
|-----------|--------|
| `DoubleTopBottom` | twin-peak / twin-trough reversal |
| `TripleTopBottom` | three matching extremes (stronger reversal) |
| `HeadAndShoulders` | central head + matching shoulders + flat neckline (and inverse) |
| `Triangle` | ascending (+1) / descending (-1) / symmetrical |
| `Wedge` | rising wedge (-1) / falling wedge (+1) |
| `FlagPennant` | shallow consolidation against a pole → continuation |
| `RectangleRange` | flat support/resistance mean-reversion |
| `CupAndHandle` | rounded base + shallow handle (and inverse) |

## Touchpoints

Core modules + `FAMILIES` group and assert, crate root re-exports, Python/Node/WASM bindings via the candle-pattern macros (Node `index.d.ts`/`index.js` regenerated), the candle fuzz target, Python reference + `CANDLE_SCALAR` registry tests and the Node candle-scalar factory, README catalogue counter + banner cache-buster + family table row + family-count word, `docs/README.md` counter, and the changelog.

## Verification

- `cargo test -p wickra-core --lib` — 2915 passed
- `cargo test -p wickra-core --doc` — 335 passed
- `cargo clippy --workspace --all-targets --all-features -- -D warnings` — clean
- Node `npm run build && npm test` — 436 passed
- Python `maturin develop --release` + `pytest` — 732 passed

Every detector branch is unit-tested; multi-condition predicates were flattened to single-line precomputed booleans to keep patch coverage at 100%.
This commit is contained in:
kingchenc
2026-06-03 22:55:36 +02:00
committed by GitHub
parent 05d2e5dc61
commit 995f119010
23 changed files with 2127 additions and 49 deletions
+16
View File
@@ -13675,6 +13675,14 @@ candle_pattern_no_param!(
wc::ConcealingBabySwallow,
"ConcealingBabySwallow"
);
candle_pattern_no_param!(PyDoubleTopBottom, wc::DoubleTopBottom, "DoubleTopBottom");
candle_pattern_no_param!(PyTripleTopBottom, wc::TripleTopBottom, "TripleTopBottom");
candle_pattern_no_param!(PyHeadAndShoulders, wc::HeadAndShoulders, "HeadAndShoulders");
candle_pattern_no_param!(PyTriangle, wc::Triangle, "Triangle");
candle_pattern_no_param!(PyWedge, wc::Wedge, "Wedge");
candle_pattern_no_param!(PyFlagPennant, wc::FlagPennant, "FlagPennant");
candle_pattern_no_param!(PyRectangleRange, wc::RectangleRange, "RectangleRange");
candle_pattern_no_param!(PyCupAndHandle, wc::CupAndHandle, "CupAndHandle");
// ============================== Microstructure: Order Book ==============================
//
// Order-book indicators consume a depth snapshot rather than OHLCV. Streaming
@@ -18196,5 +18204,13 @@ fn _wickra(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<PyDayOfWeekProfile>()?;
m.add_class::<PyIntradayVolatilityProfile>()?;
m.add_class::<PyVolumeByTimeProfile>()?;
m.add_class::<PyDoubleTopBottom>()?;
m.add_class::<PyTripleTopBottom>()?;
m.add_class::<PyHeadAndShoulders>()?;
m.add_class::<PyTriangle>()?;
m.add_class::<PyWedge>()?;
m.add_class::<PyFlagPennant>()?;
m.add_class::<PyRectangleRange>()?;
m.add_class::<PyCupAndHandle>()?;
Ok(())
}