feat: TA-Lib candlestick patterns — hikkake-mod/pigeon/neck-lines (part 5 of 9) (#137)

* feat: add hikkake-modified, homing-pigeon and neck-line candlestick patterns

Five patterns, all `Input = Candle`, `Output = f64`:

- Modified Hikkake (CDLHIKKAKEMOD) — a close-confirmed Hikkake: an inside bar
  then a breakout that closes back inside the inside-bar range; bullish +1,
  bearish -1.
- Homing Pigeon (CDLHOMINGPIGEON) — two black candles, the second a small body
  inside the first, a bullish reversal; +1.
- On-Neck (CDLONNECK) — long black bar then a white bar closing at its low (the
  neckline), a bearish continuation; -1.
- In-Neck (CDLINNECK) — long black bar then a white bar closing just into its
  body, a bearish continuation; -1.
- Thrusting (CDLTHRUSTING) — long black bar then a white bar closing well into
  but below the midpoint of its body, a bearish continuation; -1.

Counter 264 -> 269 (mod-count == lib counted block; FAMILIES total 259 -> 264).

* chore: sync indicator count to 269

---------

Co-authored-by: wickra-bot <wickra-bot@users.noreply.github.com>
This commit is contained in:
kingchenc
2026-06-02 17:03:49 +02:00
committed by GitHub
parent d43bc9ddf3
commit e4ca9c3f8f
19 changed files with 1106 additions and 28 deletions
@@ -603,6 +603,26 @@ CANDLE_SCALAR = {
lambda: ta.Hikkake(),
lambda ind, h, l, c, v: ind.batch(c, h, l, c),
),
"HikkakeModified": (
lambda: ta.HikkakeModified(),
lambda ind, h, l, c, v: ind.batch(c, h, l, c),
),
"HomingPigeon": (
lambda: ta.HomingPigeon(),
lambda ind, h, l, c, v: ind.batch(c, h, l, c),
),
"OnNeck": (
lambda: ta.OnNeck(),
lambda ind, h, l, c, v: ind.batch(c, h, l, c),
),
"InNeck": (
lambda: ta.InNeck(),
lambda ind, h, l, c, v: ind.batch(c, h, l, c),
),
"Thrusting": (
lambda: ta.Thrusting(),
lambda ind, h, l, c, v: ind.batch(c, h, l, c),
),
}
@@ -1784,6 +1804,37 @@ def test_hikkake_reference():
assert t.update((11.0, 13.0, 8.0, 12.0, 1.0, 1)) == pytest.approx(0.0)
assert t.update((9.0, 12.0, 6.0, 7.0, 1.0, 2)) == pytest.approx(1.0)
def test_hikkake_modified_reference():
t = ta.HikkakeModified()
assert t.update((10.0, 15.0, 5.0, 12.0, 1.0, 0)) == pytest.approx(0.0)
assert t.update((11.0, 13.0, 8.0, 12.0, 1.0, 1)) == pytest.approx(0.0)
assert t.update((9.0, 12.0, 6.0, 9.0, 1.0, 2)) == pytest.approx(1.0)
def test_homing_pigeon_reference():
t = ta.HomingPigeon()
assert t.update((15.0, 15.1, 9.9, 10.0, 1.0, 0)) == pytest.approx(0.0)
assert t.update((14.0, 14.1, 10.9, 11.0, 1.0, 1)) == pytest.approx(1.0)
def test_on_neck_reference():
t = ta.OnNeck()
assert t.update((15.0, 15.1, 9.0, 10.0, 1.0, 0)) == pytest.approx(0.0)
assert t.update((7.0, 9.1, 6.9, 9.0, 1.0, 1)) == pytest.approx(-1.0)
def test_in_neck_reference():
t = ta.InNeck()
assert t.update((15.0, 15.1, 9.0, 10.0, 1.0, 0)) == pytest.approx(0.0)
assert t.update((7.0, 10.3, 6.9, 10.2, 1.0, 1)) == pytest.approx(-1.0)
def test_thrusting_reference():
t = ta.Thrusting()
assert t.update((15.0, 15.1, 9.0, 10.0, 1.0, 0)) == pytest.approx(0.0)
assert t.update((7.0, 11.6, 6.9, 11.5, 1.0, 1)) == pytest.approx(-1.0)
# --- Lifecycle ------------------------------------------------------------