feat: TA-Lib candlestick patterns — tasuki-gap/unique-three-river/marubozu-pair/concealing-baby-swallow (part 9 of 9) (#141)

The final batch of the TA-Lib candlestick roadmap. Adds five patterns, each a streaming `Indicator<Input = Candle, Output = f64>` emitting the family's uniform `±1.0 / 0.0` sign convention, fully wired across the Rust core, Python / Node / WASM bindings, fuzz target and reference tests.

- **Tasuki Gap** (`CDLTASUKIGAP`) — a 3-bar continuation: two same-coloured candles gap in the trend direction, then an opposite candle opens within the second body and closes back into the gap without filling it; upside +1, downside -1.
- **Unique Three River** (`CDLUNIQUE3RIVER`) — a 3-bar bullish reversal: a long black candle, a black candle probing a new low with its body inside the first, then a small white candle held below it; bullish +1.
- **Closing Marubozu** (`CDLCLOSINGMARUBOZU`) — a single long-bodied candle with no shadow on the close end; +1 (white, closes at the high) or -1 (black, closes at the low).
- **Opening Marubozu** — a single long-bodied candle with no shadow on the open end; +1 (white, opens at the low) or -1 (black, opens at the high). No direct TA-Lib equivalent — completes the pair with the closing marubozu.
- **Concealing Baby Swallow** (`CDLCONCEALBABYSWALL`) — a rare 4-bar bullish capitulation: two black marubozu, a black candle gapping down with an upper shadow into the second, then a large black candle engulfing it entirely; bullish +1.

Body and shadow thresholds follow the geometric house style (fixed fractions of the bar range) rather than TA-Lib's rolling averages.

Counter 284 → 289 (mod-count == lib counted block; FAMILIES total 279 → 284).

Stacked on #140 (`feat/cdl-gap-methods`); base retargets to `main` as the stack merges down.
This commit is contained in:
kingchenc
2026-06-02 17:27:39 +02:00
committed by GitHub
parent 4d0bc08efd
commit 124efb4432
19 changed files with 1385 additions and 40 deletions
+14
View File
@@ -11688,6 +11688,15 @@ candle_pattern_no_param!(
candle_pattern_no_param!(PyStalledPattern, wc::StalledPattern, "StalledPattern");
candle_pattern_no_param!(PyStickSandwich, wc::StickSandwich, "StickSandwich");
candle_pattern_no_param!(PyTakuri, wc::Takuri, "Takuri");
candle_pattern_no_param!(PyClosingMarubozu, wc::ClosingMarubozu, "ClosingMarubozu");
candle_pattern_no_param!(PyOpeningMarubozu, wc::OpeningMarubozu, "OpeningMarubozu");
candle_pattern_no_param!(PyTasukiGap, wc::TasukiGap, "TasukiGap");
candle_pattern_no_param!(PyUniqueThreeRiver, wc::UniqueThreeRiver, "UniqueThreeRiver");
candle_pattern_no_param!(
PyConcealingBabySwallow,
wc::ConcealingBabySwallow,
"ConcealingBabySwallow"
);
// ============================== Microstructure: Order Book ==============================
//
// Order-book indicators consume a depth snapshot rather than OHLCV. Streaming
@@ -14224,6 +14233,11 @@ fn _wickra(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<PyStalledPattern>()?;
m.add_class::<PyStickSandwich>()?;
m.add_class::<PyTakuri>()?;
m.add_class::<PyClosingMarubozu>()?;
m.add_class::<PyOpeningMarubozu>()?;
m.add_class::<PyTasukiGap>()?;
m.add_class::<PyUniqueThreeRiver>()?;
m.add_class::<PyConcealingBabySwallow>()?;
// Microstructure: order book.
m.add_class::<PyOrderBookImbalanceTop1>()?;
m.add_class::<PyOrderBookImbalanceTopN>()?;