feat(family-09): add 7 trailing stops (HiLo, Volty, Yo-Yo, Donchian, Pct, Step, Renko) (#46)
* feat(family-09): add 7 trailing stops (HiLo, Volty, Yo-Yo, Donchian, Pct, Step, Renko)
Rounds out the Trailing Stops family from 5 to 12 indicators:
- HiLoActivator (Crabel): SMA-of-high/SMA-of-low trail with a one-bar
lag; emits the opposite-side SMA as the trailing stop.
- VoltyStop (Cynthia Kase): ATR trail anchored on the extreme close
since the trade was opened — tighter than AtrTrailingStop on
pullbacks.
- YoyoExit: long-only ATR trail with an explicit re-entry trigger at
trail + multiplier*ATR; exposes an in_trade flag.
- DonchianStop (Turtle): lowest low / highest high over the window;
multi-output {stop_long, stop_short}.
- PercentageTrailingStop: fixed-percent trail that scales across
instruments without per-asset tuning.
- StepTrailingStop: snaps to a step_size-aligned grid; mirrors
discretionary stop-by-hand workflow.
- RenkoTrailingStop: block-anchored trail; only moves on full-block
advances, ignores intra-block noise.
All seven are wired into wickra-core, the Python / Node / WASM
bindings, the indicator_update + indicator_update_candle fuzz targets,
the wickra bench harness, and the Python + Node test suites. README
counter bumps from 71 to 78; CHANGELOG entry under [Unreleased].
* fix(family-09): satisfy pedantic clippy lints
- hilo_activator: rewrite match-Some/None as if-let-else (single_match_else),
add backticks around the HiLo identifier in module/struct doc (doc_markdown).
- percentage / step / renko trailing stop tests: use f64::from(i32) instead
of `as f64` (cast_lossless).
- bench `benches()` is now >100 lines after Family 09 was wired in; allow
too_many_lines (matches the python pymodule fn).
This commit is contained in:
@@ -20,12 +20,13 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Through
|
||||
use std::hint::black_box;
|
||||
use wickra::{
|
||||
AccelerationBands, AdOscillator, Adxr, Alma, AnchoredVwap, Atr, AtrBands, BatchExt,
|
||||
BollingerBands, Candle, DemandIndex, DoubleBollinger, Ema, FractalChaosBands, Frama,
|
||||
GarmanKlassVolatility, HurstChannel, Indicator, Jma, Kst, Kvo, LinRegChannel, MaEnvelope,
|
||||
MacdIndicator, MarketFacilitationIndex, McGinleyDynamic, Nvi, Obv, ParkinsonVolatility, Pgo,
|
||||
Pvi, RogersSatchellVolatility, Rsi, Rvi, RviVolatility, Rwi, Sma, StandardErrorBands,
|
||||
StarcBands, Stochastic, Tii, Tsv, TtmSqueeze, Vidya, VolumeOscillator, VwapStdDevBands, Vzo,
|
||||
WaveTrend, Wma, YangZhangVolatility,
|
||||
BollingerBands, Candle, DemandIndex, DonchianStop, DoubleBollinger, Ema, FractalChaosBands,
|
||||
Frama, GarmanKlassVolatility, HiLoActivator, HurstChannel, Indicator, Jma, Kst, Kvo,
|
||||
LinRegChannel, MaEnvelope, MacdIndicator, MarketFacilitationIndex, McGinleyDynamic, Nvi, Obv,
|
||||
ParkinsonVolatility, PercentageTrailingStop, Pgo, Pvi, RenkoTrailingStop,
|
||||
RogersSatchellVolatility, Rsi, Rvi, RviVolatility, Rwi, Sma, StandardErrorBands, StarcBands,
|
||||
StepTrailingStop, Stochastic, Tii, Tsv, TtmSqueeze, Vidya, VoltyStop, VolumeOscillator,
|
||||
VwapStdDevBands, Vzo, WaveTrend, Wma, YangZhangVolatility, YoyoExit,
|
||||
};
|
||||
use wickra_data::csv::CandleReader;
|
||||
|
||||
@@ -154,6 +155,7 @@ where
|
||||
group.finish();
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn benches(c: &mut Criterion) {
|
||||
let candles = load_candles();
|
||||
let closes: Vec<f64> = candles.iter().map(|c| c.close).collect();
|
||||
@@ -180,6 +182,21 @@ fn benches(c: &mut Criterion) {
|
||||
bench_candle_input(c, "stochastic", &candles, Stochastic::classic);
|
||||
bench_candle_input(c, "obv", &candles, Obv::new);
|
||||
|
||||
// --- Family 09: Trailing Stops ---
|
||||
bench_candle_input(c, "hilo_activator", &candles, HiLoActivator::classic);
|
||||
bench_candle_input(c, "volty_stop", &candles, VoltyStop::classic);
|
||||
bench_candle_input(c, "yoyo_exit", &candles, YoyoExit::classic);
|
||||
bench_candle_input(c, "donchian_stop", &candles, DonchianStop::classic);
|
||||
bench_scalar(c, "percentage_trailing_stop", &closes, || {
|
||||
PercentageTrailingStop::new(5.0).unwrap()
|
||||
});
|
||||
bench_scalar(c, "step_trailing_stop", &closes, || {
|
||||
StepTrailingStop::new(1.0).unwrap()
|
||||
});
|
||||
bench_scalar(c, "renko_trailing_stop", &closes, || {
|
||||
RenkoTrailingStop::new(1.0).unwrap()
|
||||
});
|
||||
|
||||
// --- Family 07: Volume ---
|
||||
bench_candle_input(c, "kvo", &candles, Kvo::classic);
|
||||
bench_candle_input(c, "volume_oscillator", &candles, || {
|
||||
|
||||
Reference in New Issue
Block a user