feat(family-11): add DeMark suite (TD Setup, Sequential, DeMarker, REI, Pressure) (#48)
* feat(family-11): add DeMark suite (TD Setup, Sequential, DeMarker, REI, Pressure)
Family 11 (DeMark) was previously empty; this PR adds five
streaming-first DeMark indicators in one batch.
- **TD Setup** (`TdSetup`): parameterised buy/sell setup counter.
Counts consecutive bars whose close is less-than (buy) or
greater-than (sell) the close `lookback` bars earlier, saturating
at `target`. Emits a signed `f64` so callers read direction from
the sign and run length from the magnitude. Classic config:
`lookback = 4`, `target = 9`.
- **TD Sequential** (`TdSequential`): the canonical Setup + Countdown
exhaustion pattern. Output struct `{ setup, countdown, direction }`
exposes both phase counts as signed numbers plus the active
countdown direction (+1 buy / -1 sell / 0 none). Countdown
activates when a setup completes and tracks the close-vs-high/low
comparison `countdown_lookback` bars back, capped at
`countdown_target`. Classic: 4/9/2/13.
- **TD DeMarker** (`TdDeMarker`): bounded [0, 1] oscillator from the
rolling average of upward high expansion (DeMax) and downward low
expansion (DeMin). Falls back to the neutral 0.5 on a flat market
(denominator zero).
- **TD REI** (`TdRei`): Range Expansion Index, bounded [-100, 100].
Per-bar numerator gated on a range-overlap condition vs the bars
5 and 6 back, normalised by a `period`-bar sum of absolute moves.
Classic period = 5. Saturates at +100 in a slow steady uptrend
and at -100 in the mirror downtrend; emits 0 on a flat market.
- **TD Pressure** (`TdPressure`): volume-weighted buying / selling
pressure normalised to [-100, 100]. Per-bar pressure is the
intra-bar close-vs-open ratio scaled by volume; the output is the
rolling mean divided by the rolling mean volume. Zero-range bars
contribute zero (avoid the undefined ratio) and a flat zero-volume
window falls back to 0.
Bindings: all five exposed in Python (`ta.TDSetup`, `ta.TDSequential`,
`ta.TDDeMarker`, `ta.TDREI`, `ta.TDPressure`), Node (`wickra.TDSetup`
etc.), and WASM. Multi-output classes (`TDSequential`) return either
a struct `{ setup, countdown, direction }` per bar (streaming) or a
flat interleaved Float64Array of length `3 * n` (batch).
Tests: 47 unit tests across the five new core files (pure-trend
saturation, flat-market neutral fallback, batch-equals-streaming,
zero-parameter rejection, reset semantics, accessors). Python
test_new_indicators.py picks up all five plus a multi-output TD
Sequential block. Node indicators.test.js picks up all five.
Reference values added to test_known_values.py.
Fuzz: candle fuzz target sweeps all five DeMark indicators with the
existing `Vec<f64>` -> `Vec<Candle>` driver.
Benches: BTCUSDT 1-minute dataset benches for each DeMark indicator
in `crates/wickra/benches/indicators.rs`.
Docs: README family table gains a "DeMark" row; indicator counter
bumped 71 -> 76. CHANGELOG entry added under [Unreleased]. Wiki
drafts (deep-dive pages + Sidebar / Overview / Warmup-Periods / Home
deltas) live under `indicator-ideas/families/wiki/family-11-demark/`
for manual merge into the wiki repo.
* feat(family-11): add 7 missing DeMark indicators
Complete the DeMark suite (family 11) with the seven indicators not
covered by the first commit: TD Combo, TD Countdown, TD Lines (TDST),
TD Range Projection, TD Differential, TD Open, and TD Risk Level.
- TdCombo: aggressive countdown variant with three strictness rules
on top of the classic close-vs-low/high lookback rule (monotone
low/high, monotone close vs prior bar).
- TdCountdown: standalone 13-bar countdown packaging only the signed
countdown count (the setup machine runs internally).
- TdLines: TDST horizontal support/resistance levels from the
highest-high / lowest-low bars of the most-recently-completed
setup, exposed as a multi-output struct.
- TdRangeProjection: DeMark X-projection of the next bar's high and
low from the current bar's OHLC via an open-vs-close-weighted
pivot (three branches: close<open, close>open, close==open).
- TdDifferential: two-bar buying-pressure vs selling-pressure
reversal pattern emitting +1/-1/0.
- TdOpen: gap-and-fade reversal pattern (open outside prior range
with subsequent recovery into it) emitting +1/-1/0.
- TdRiskLevel: protective stop levels derived from the setup
extreme bar +/- its true range.
All seven are wired through Rust core, Python, Node and WASM
bindings, registered in the candle-stream fuzz target, given
benchmark entries on the BTCUSDT 1-minute dataset, and covered by
streaming-vs-batch equivalence, reference-value, lifecycle and
input-validation tests on the Python and Node sides. README counter
moves 76 -> 83 and the CHANGELOG "family 11" entry is extended to
list all twelve indicators.
* fix(td_risk_level tests): check first emission at idx 12, not last bar
TdRiskLevel re-ratchets the sell-risk level on each subsequent setup
completion, so a strictly rising series produces 22.0 at idx 19 (latest
setup) rather than 15.0 (first setup). The test comment already named
idx 12 as the reference; switch the assertion from out[-1] to out[12]
to match the reference computation.
* test(family-11): cover buy-direction branches in TD indicators
Add downtrend tests to TdSequential, TdCombo and TdCountdown so the
buy-side countdown/combo increment branches are exercised; remove an
empty `if buy_countdown == target {}` block in TdSequential whose
behavior is already enforced by the outer strict `<` guard.
Closes codecov/patch gaps reported on PR #48 (10 missed lines across
the three files).
This commit is contained in:
+20
-1
@@ -310,7 +310,7 @@ if (!nativeBinding) {
|
||||
throw new Error(`Failed to load native binding`)
|
||||
}
|
||||
|
||||
const { version, SMA, EMA, WMA, RSI, DEMA, TEMA, HMA, ROC, TRIX, SMMA, TRIMA, ZLEMA, MOM, CMO, DPO, StdDev, UlcerIndex, VerticalHorizontalFilter, ZScore, MACD, BollingerBands, ATR, Stochastic, OBV, ADX, ADXR, CCI, WilliamsR, MFI, PSAR, Keltner, Donchian, VWAP, RollingVWAP, AwesomeOscillator, Aroon, KAMA, RVI, PGO, KST, SMI, LaguerreRSI, ConnorsRSI, Inertia, ALMA, McGinleyDynamic, FRAMA, VIDYA, JMA, Alligator, EVWMA, APO, AwesomeOscillatorHistogram, CFO, ZeroLagMACD, ElderImpulse, STC, T3, TSI, PMO, TII, ADL, VolumePriceTrend, ChaikinMoneyFlow, ChaikinOscillator, ForceIndex, EaseOfMovement, KVO, VolumeOscillator, NVI, PVI, WilliamsAD, AnchoredVWAP, DemandIndex, TSV, VZO, MarketFacilitationIndex, SuperTrend, ChandelierExit, ChandeKrollStop, AtrTrailingStop, HiLoActivator, VoltyStop, YoyoExit, DonchianStop, PercentageTrailingStop, StepTrailingStop, RenkoTrailingStop, TypicalPrice, MedianPrice, WeightedClose, LinearRegression, LinRegSlope, AcceleratorOscillator, BalanceOfPower, ChoppinessIndex, TrueRange, ChaikinVolatility, LinRegAngle, BollingerBandwidth, PercentB, NATR, HistoricalVolatility, AroonOscillator, Vortex, RWI, WaveTrend, MassIndex, StochRSI, UltimateOscillator, PPO, Coppock, VWMA, RVIVolatility, ParkinsonVolatility, GarmanKlassVolatility, RogersSatchellVolatility, YangZhangVolatility, MaEnvelope, AccelerationBands, StarcBands, AtrBands, HurstChannel, LinRegChannel, StandardErrorBands, DoubleBollinger, TtmSqueeze, FractalChaosBands, VwapStdDevBands } = nativeBinding
|
||||
const { version, SMA, EMA, WMA, RSI, DEMA, TEMA, HMA, ROC, TRIX, SMMA, TRIMA, ZLEMA, MOM, CMO, DPO, StdDev, UlcerIndex, VerticalHorizontalFilter, ZScore, MACD, BollingerBands, ATR, Stochastic, OBV, ADX, ADXR, CCI, WilliamsR, MFI, PSAR, Keltner, Donchian, VWAP, RollingVWAP, AwesomeOscillator, Aroon, KAMA, RVI, PGO, KST, SMI, LaguerreRSI, ConnorsRSI, Inertia, ALMA, McGinleyDynamic, FRAMA, VIDYA, JMA, Alligator, EVWMA, APO, AwesomeOscillatorHistogram, CFO, ZeroLagMACD, ElderImpulse, STC, T3, TSI, PMO, TII, ADL, VolumePriceTrend, ChaikinMoneyFlow, ChaikinOscillator, ForceIndex, EaseOfMovement, KVO, VolumeOscillator, NVI, PVI, WilliamsAD, AnchoredVWAP, DemandIndex, TSV, VZO, MarketFacilitationIndex, SuperTrend, ChandelierExit, ChandeKrollStop, AtrTrailingStop, HiLoActivator, VoltyStop, YoyoExit, DonchianStop, PercentageTrailingStop, StepTrailingStop, RenkoTrailingStop, TypicalPrice, MedianPrice, WeightedClose, LinearRegression, LinRegSlope, AcceleratorOscillator, BalanceOfPower, ChoppinessIndex, TrueRange, ChaikinVolatility, LinRegAngle, BollingerBandwidth, PercentB, NATR, HistoricalVolatility, AroonOscillator, Vortex, RWI, WaveTrend, MassIndex, StochRSI, UltimateOscillator, PPO, Coppock, VWMA, RVIVolatility, ParkinsonVolatility, GarmanKlassVolatility, RogersSatchellVolatility, YangZhangVolatility, MaEnvelope, AccelerationBands, StarcBands, AtrBands, HurstChannel, LinRegChannel, StandardErrorBands, DoubleBollinger, TtmSqueeze, FractalChaosBands, VwapStdDevBands, ClassicPivots, FibonacciPivots, Camarilla, WoodiePivots, DemarkPivots, WilliamsFractals, ZigZag, TDSetup, TDSequential, TDDeMarker, TDREI, TDPressure, TDCombo, TDCountdown, TDLines, TDRangeProjection, TDDifferential, TDOpen, TDRiskLevel } = nativeBinding
|
||||
|
||||
module.exports.version = version
|
||||
module.exports.SMA = SMA
|
||||
@@ -442,3 +442,22 @@ module.exports.DoubleBollinger = DoubleBollinger
|
||||
module.exports.TtmSqueeze = TtmSqueeze
|
||||
module.exports.FractalChaosBands = FractalChaosBands
|
||||
module.exports.VwapStdDevBands = VwapStdDevBands
|
||||
module.exports.ClassicPivots = ClassicPivots
|
||||
module.exports.FibonacciPivots = FibonacciPivots
|
||||
module.exports.Camarilla = Camarilla
|
||||
module.exports.WoodiePivots = WoodiePivots
|
||||
module.exports.DemarkPivots = DemarkPivots
|
||||
module.exports.WilliamsFractals = WilliamsFractals
|
||||
module.exports.ZigZag = ZigZag
|
||||
module.exports.TDSetup = TDSetup
|
||||
module.exports.TDSequential = TDSequential
|
||||
module.exports.TDDeMarker = TDDeMarker
|
||||
module.exports.TDREI = TDREI
|
||||
module.exports.TDPressure = TDPressure
|
||||
module.exports.TDCombo = TDCombo
|
||||
module.exports.TDCountdown = TDCountdown
|
||||
module.exports.TDLines = TDLines
|
||||
module.exports.TDRangeProjection = TDRangeProjection
|
||||
module.exports.TDDifferential = TDDifferential
|
||||
module.exports.TDOpen = TDOpen
|
||||
module.exports.TDRiskLevel = TDRiskLevel
|
||||
|
||||
Reference in New Issue
Block a user