feat(family-api): add FAMILIES const and family-taxonomy tests (#60)
* feat(family-api): add FAMILIES const and family-taxonomy tests Introduce `wickra_core::FAMILIES`, a `&'static [(&str, &[&str])]` mapping every built-in indicator to one of 16 families (Moving Averages, Momentum Oscillators, Trend & Directional, Price Oscillators, Volatility & Bands, Bands & Channels, Trailing Stops, Volume, Price Statistics, Ehlers / Cycle (DSP), Pivots & S/R, DeMark, Ichimoku & Charts, Candlestick Patterns, Market Profile, Risk / Performance). Two compile-time-anchored guards make sure the const stays trustworthy: - `no_duplicates_across_families`: no indicator is listed in two families - `total_count_matches_expected`: hard-coded total bumps in lockstep with the indicator catalogue (214 today), so any new indicator added without being filed under a family trips the test. Also corrects the module doc comment which falsely claimed indicators were grouped by category internally; the `mod` block is alphabetical, and the canonical taxonomy now lives in `FAMILIES`. * chore: sync indicator count to 214 --------- Co-authored-by: wickra-bot <wickra-bot@users.noreply.github.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
//! Built-in indicators. Every indicator implements [`crate::Indicator`].
|
//! Built-in indicators. Every indicator implements [`crate::Indicator`].
|
||||||
//!
|
//!
|
||||||
//! Modules are organised internally by category (trend, momentum, volatility,
|
//! Modules are listed alphabetically; the canonical family taxonomy lives in
|
||||||
//! volume) but every public name is also re-exported flat from this module and
|
//! [`FAMILIES`]. Every public name is re-exported flat from this module and
|
||||||
//! from the crate root for convenience.
|
//! from the crate root for convenience.
|
||||||
|
|
||||||
mod acceleration_bands;
|
mod acceleration_bands;
|
||||||
@@ -431,3 +431,326 @@ pub use z_score::ZScore;
|
|||||||
pub use zero_lag_macd::{ZeroLagMacd, ZeroLagMacdOutput};
|
pub use zero_lag_macd::{ZeroLagMacd, ZeroLagMacdOutput};
|
||||||
pub use zig_zag::{ZigZag, ZigZagOutput};
|
pub use zig_zag::{ZigZag, ZigZagOutput};
|
||||||
pub use zlema::Zlema;
|
pub use zlema::Zlema;
|
||||||
|
|
||||||
|
/// Family classification of every built-in indicator. The (family,
|
||||||
|
/// indicators) list is the single source of truth used by `family_tests`
|
||||||
|
/// below; README and Wiki taxonomy tables should be kept in sync with it.
|
||||||
|
///
|
||||||
|
/// Each indicator appears in exactly one family. Names are the public
|
||||||
|
/// struct identifiers re-exported from this module (and the crate root).
|
||||||
|
pub const FAMILIES: &[(&str, &[&str])] = &[
|
||||||
|
(
|
||||||
|
"Moving Averages",
|
||||||
|
&[
|
||||||
|
"Sma",
|
||||||
|
"Ema",
|
||||||
|
"Wma",
|
||||||
|
"Dema",
|
||||||
|
"Tema",
|
||||||
|
"Hma",
|
||||||
|
"Kama",
|
||||||
|
"Smma",
|
||||||
|
"Trima",
|
||||||
|
"Zlema",
|
||||||
|
"T3",
|
||||||
|
"Vwma",
|
||||||
|
"Alma",
|
||||||
|
"McGinleyDynamic",
|
||||||
|
"Frama",
|
||||||
|
"Vidya",
|
||||||
|
"Jma",
|
||||||
|
"Alligator",
|
||||||
|
"Evwma",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Momentum Oscillators",
|
||||||
|
&[
|
||||||
|
"Rsi",
|
||||||
|
"Stochastic",
|
||||||
|
"Cci",
|
||||||
|
"Roc",
|
||||||
|
"WilliamsR",
|
||||||
|
"Mfi",
|
||||||
|
"AwesomeOscillator",
|
||||||
|
"Mom",
|
||||||
|
"Cmo",
|
||||||
|
"Tsi",
|
||||||
|
"Pmo",
|
||||||
|
"StochRsi",
|
||||||
|
"UltimateOscillator",
|
||||||
|
"Rvi",
|
||||||
|
"Pgo",
|
||||||
|
"Kst",
|
||||||
|
"Smi",
|
||||||
|
"LaguerreRsi",
|
||||||
|
"ConnorsRsi",
|
||||||
|
"Inertia",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Trend & Directional",
|
||||||
|
&[
|
||||||
|
"MacdIndicator",
|
||||||
|
"Adx",
|
||||||
|
"Adxr",
|
||||||
|
"Aroon",
|
||||||
|
"Trix",
|
||||||
|
"AroonOscillator",
|
||||||
|
"Vortex",
|
||||||
|
"Rwi",
|
||||||
|
"Tii",
|
||||||
|
"WaveTrend",
|
||||||
|
"MassIndex",
|
||||||
|
"ChoppinessIndex",
|
||||||
|
"VerticalHorizontalFilter",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Price Oscillators",
|
||||||
|
&[
|
||||||
|
"Ppo",
|
||||||
|
"Dpo",
|
||||||
|
"Coppock",
|
||||||
|
"AcceleratorOscillator",
|
||||||
|
"BalanceOfPower",
|
||||||
|
"Apo",
|
||||||
|
"AwesomeOscillatorHistogram",
|
||||||
|
"Cfo",
|
||||||
|
"ZeroLagMacd",
|
||||||
|
"ElderImpulse",
|
||||||
|
"Stc",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Volatility & Bands",
|
||||||
|
&[
|
||||||
|
"Atr",
|
||||||
|
"BollingerBands",
|
||||||
|
"Keltner",
|
||||||
|
"Donchian",
|
||||||
|
"Natr",
|
||||||
|
"StdDev",
|
||||||
|
"UlcerIndex",
|
||||||
|
"HistoricalVolatility",
|
||||||
|
"BollingerBandwidth",
|
||||||
|
"PercentB",
|
||||||
|
"TrueRange",
|
||||||
|
"ChaikinVolatility",
|
||||||
|
"RviVolatility",
|
||||||
|
"ParkinsonVolatility",
|
||||||
|
"GarmanKlassVolatility",
|
||||||
|
"RogersSatchellVolatility",
|
||||||
|
"YangZhangVolatility",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Bands & Channels",
|
||||||
|
&[
|
||||||
|
"MaEnvelope",
|
||||||
|
"AccelerationBands",
|
||||||
|
"StarcBands",
|
||||||
|
"AtrBands",
|
||||||
|
"HurstChannel",
|
||||||
|
"LinRegChannel",
|
||||||
|
"StandardErrorBands",
|
||||||
|
"DoubleBollinger",
|
||||||
|
"TtmSqueeze",
|
||||||
|
"FractalChaosBands",
|
||||||
|
"VwapStdDevBands",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Trailing Stops",
|
||||||
|
&[
|
||||||
|
"Psar",
|
||||||
|
"SuperTrend",
|
||||||
|
"ChandelierExit",
|
||||||
|
"ChandeKrollStop",
|
||||||
|
"AtrTrailingStop",
|
||||||
|
"HiLoActivator",
|
||||||
|
"VoltyStop",
|
||||||
|
"YoyoExit",
|
||||||
|
"DonchianStop",
|
||||||
|
"PercentageTrailingStop",
|
||||||
|
"StepTrailingStop",
|
||||||
|
"RenkoTrailingStop",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Volume",
|
||||||
|
&[
|
||||||
|
"Obv",
|
||||||
|
"Vwap",
|
||||||
|
"RollingVwap",
|
||||||
|
"Adl",
|
||||||
|
"VolumePriceTrend",
|
||||||
|
"ChaikinMoneyFlow",
|
||||||
|
"ChaikinOscillator",
|
||||||
|
"ForceIndex",
|
||||||
|
"EaseOfMovement",
|
||||||
|
"Kvo",
|
||||||
|
"VolumeOscillator",
|
||||||
|
"Nvi",
|
||||||
|
"Pvi",
|
||||||
|
"AdOscillator",
|
||||||
|
"AnchoredVwap",
|
||||||
|
"DemandIndex",
|
||||||
|
"Tsv",
|
||||||
|
"Vzo",
|
||||||
|
"MarketFacilitationIndex",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Price Statistics",
|
||||||
|
&[
|
||||||
|
"TypicalPrice",
|
||||||
|
"MedianPrice",
|
||||||
|
"WeightedClose",
|
||||||
|
"LinearRegression",
|
||||||
|
"LinRegSlope",
|
||||||
|
"ZScore",
|
||||||
|
"LinRegAngle",
|
||||||
|
"Variance",
|
||||||
|
"CoefficientOfVariation",
|
||||||
|
"Skewness",
|
||||||
|
"Kurtosis",
|
||||||
|
"StandardError",
|
||||||
|
"DetrendedStdDev",
|
||||||
|
"RSquared",
|
||||||
|
"MedianAbsoluteDeviation",
|
||||||
|
"Autocorrelation",
|
||||||
|
"HurstExponent",
|
||||||
|
"PearsonCorrelation",
|
||||||
|
"Beta",
|
||||||
|
"SpearmanCorrelation",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Ehlers / Cycle (DSP)",
|
||||||
|
&[
|
||||||
|
"Mama",
|
||||||
|
"Fama",
|
||||||
|
"FisherTransform",
|
||||||
|
"InverseFisherTransform",
|
||||||
|
"SuperSmoother",
|
||||||
|
"HilbertDominantCycle",
|
||||||
|
"SineWave",
|
||||||
|
"Decycler",
|
||||||
|
"DecyclerOscillator",
|
||||||
|
"RoofingFilter",
|
||||||
|
"CenterOfGravity",
|
||||||
|
"CyberneticCycle",
|
||||||
|
"AdaptiveCycle",
|
||||||
|
"EmpiricalModeDecomposition",
|
||||||
|
"EhlersStochastic",
|
||||||
|
"InstantaneousTrendline",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Pivots & S/R",
|
||||||
|
&[
|
||||||
|
"ClassicPivots",
|
||||||
|
"FibonacciPivots",
|
||||||
|
"Camarilla",
|
||||||
|
"WoodiePivots",
|
||||||
|
"DemarkPivots",
|
||||||
|
"WilliamsFractals",
|
||||||
|
"ZigZag",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"DeMark",
|
||||||
|
&[
|
||||||
|
"TdSetup",
|
||||||
|
"TdSequential",
|
||||||
|
"TdDeMarker",
|
||||||
|
"TdRei",
|
||||||
|
"TdPressure",
|
||||||
|
"TdCombo",
|
||||||
|
"TdCountdown",
|
||||||
|
"TdLines",
|
||||||
|
"TdRangeProjection",
|
||||||
|
"TdDifferential",
|
||||||
|
"TdOpen",
|
||||||
|
"TdRiskLevel",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
("Ichimoku & Charts", &["Ichimoku", "HeikinAshi"]),
|
||||||
|
(
|
||||||
|
"Candlestick Patterns",
|
||||||
|
&[
|
||||||
|
"Doji",
|
||||||
|
"Hammer",
|
||||||
|
"InvertedHammer",
|
||||||
|
"HangingMan",
|
||||||
|
"ShootingStar",
|
||||||
|
"Engulfing",
|
||||||
|
"Harami",
|
||||||
|
"MorningEveningStar",
|
||||||
|
"ThreeSoldiersOrCrows",
|
||||||
|
"PiercingDarkCloud",
|
||||||
|
"Marubozu",
|
||||||
|
"Tweezer",
|
||||||
|
"SpinningTop",
|
||||||
|
"ThreeInside",
|
||||||
|
"ThreeOutside",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Market Profile",
|
||||||
|
&["ValueArea", "InitialBalance", "OpeningRange"],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Risk / Performance",
|
||||||
|
&[
|
||||||
|
"SharpeRatio",
|
||||||
|
"SortinoRatio",
|
||||||
|
"CalmarRatio",
|
||||||
|
"OmegaRatio",
|
||||||
|
"MaxDrawdown",
|
||||||
|
"AverageDrawdown",
|
||||||
|
"DrawdownDuration",
|
||||||
|
"PainIndex",
|
||||||
|
"ValueAtRisk",
|
||||||
|
"ConditionalValueAtRisk",
|
||||||
|
"ProfitFactor",
|
||||||
|
"GainLossRatio",
|
||||||
|
"RecoveryFactor",
|
||||||
|
"KellyCriterion",
|
||||||
|
"TreynorRatio",
|
||||||
|
"InformationRatio",
|
||||||
|
"Alpha",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod family_tests {
|
||||||
|
use super::FAMILIES;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_duplicates_across_families() {
|
||||||
|
let mut names: Vec<&str> = FAMILIES
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, ns)| ns.iter().copied())
|
||||||
|
.collect();
|
||||||
|
let len_before = names.len();
|
||||||
|
names.sort_unstable();
|
||||||
|
names.dedup();
|
||||||
|
assert_eq!(
|
||||||
|
names.len(),
|
||||||
|
len_before,
|
||||||
|
"duplicate indicator across families"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn total_count_matches_expected() {
|
||||||
|
// Bump together with new indicators. Drift between this number and
|
||||||
|
// the actual indicator count is the early-warning signal that an
|
||||||
|
// indicator was added without being assigned a family.
|
||||||
|
let total: usize = FAMILIES.iter().map(|(_, ns)| ns.len()).sum();
|
||||||
|
assert_eq!(total, 214, "FAMILIES total drifted from indicator count");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ pub use indicators::{
|
|||||||
VolumeOscillator, VolumePriceTrend, Vortex, VortexOutput, Vwap, VwapStdDevBands,
|
VolumeOscillator, VolumePriceTrend, Vortex, VortexOutput, Vwap, VwapStdDevBands,
|
||||||
VwapStdDevBandsOutput, Vwma, Vzo, WaveTrend, WaveTrendOutput, WeightedClose, WilliamsFractals,
|
VwapStdDevBandsOutput, Vwma, Vzo, WaveTrend, WaveTrendOutput, WeightedClose, WilliamsFractals,
|
||||||
WilliamsFractalsOutput, WilliamsR, Wma, WoodiePivots, WoodiePivotsOutput, YangZhangVolatility,
|
WilliamsFractalsOutput, WilliamsR, Wma, WoodiePivots, WoodiePivotsOutput, YangZhangVolatility,
|
||||||
YoyoExit, ZScore, ZeroLagMacd, ZeroLagMacdOutput, ZigZag, ZigZagOutput, Zlema, T3,
|
YoyoExit, ZScore, ZeroLagMacd, ZeroLagMacdOutput, ZigZag, ZigZagOutput, Zlema, FAMILIES, T3,
|
||||||
};
|
};
|
||||||
pub use ohlcv::{Candle, Tick};
|
pub use ohlcv::{Candle, Tick};
|
||||||
pub use traits::{BatchExt, Chain, Indicator};
|
pub use traits::{BatchExt, Chain, Indicator};
|
||||||
|
|||||||
Reference in New Issue
Block a user