Adds `crates/wickra-core/tests/invariants.rs` — a property-based (`proptest`) harness asserting three invariants for **every** indicator and bar-builder in the catalogue (every module entry implementing `Indicator` or `BarBuilder`; the lone non-indicator helper `pattern_swing`/`SwingTracker` is excluded by design) — and fixes the non-finite bugs the harness surfaced. ## Invariants 1. **batch == streaming** — `batch()` must replay `update()` exactly. 2. **reset == fresh** — after `reset()`, re-feeding the same data matches a fresh instance. 3. **non-finite rejected without poisoning** (`f64` / `(f64, f64)` families) — a NaN/inf tick returns `None` and leaves state identical to never having seen it. ## How it works - A single generic `check_seq<I: Indicator>` covers **all** input families — `f64`, `Candle`, `(f64, f64)`, and the exotic `CrossSection`, `Trade`, `DerivativesTick`, `OrderBook`, `TradeQuote` — via per-family `proptest` generators that produce *valid* inputs (e.g. order books are strictly monotonic and uncrossed). - `check_bars<B: BarBuilder>` covers the bar-builder trait. - Outputs are compared by `Debug` string so bit-identical `NaN` outputs count as equal — these properties test **determinism**, not NaN-freeness. ## The 38 non-finite fixes The harness surfaced **38 more** scalar/pairwise indicators that let a NaN/inf tick poison their state — the same class as the 16 pairwise indicators fixed earlier (#251), but missed by the grep-based audit (`kalman_hedge_ratio` and `spread_bollinger_bands` carried `is_finite` on their **constructor** params, not the update input). All 38 now reject non-finite input via the established first-statement guard; signatures unchanged, so every binding inherits the fix. With these in, the non-finite invariant is enforced for every `f64`/`(f64,f64)` indicator going forward — the permanent regression net that would have caught #251. Warmup-exactness was evaluated and **left out** (not universal — many multi-component/candlestick indicators emit before `warmup_period` by design). ## Verification - `cargo test -p wickra-core`: 4225 unit + harness + 464 doc/integration, all green. - `cargo clippy --workspace --all-targets --all-features -- -D warnings`: clean. - Coverage runs integration tests, so the new guard branches are exercised by the harness's NaN feed. Also documents the harness in README's Testing section and adds the pending 0.8.4 entries to CHANGELOG `[Unreleased]`.
1076 lines
43 KiB
Rust
1076 lines
43 KiB
Rust
//! Property-based invariants every indicator must uphold.
|
|
//!
|
|
//! Three properties are checked against random input sequences, rolled out over
|
|
//! the whole catalogue so a regression in any single indicator surfaces here:
|
|
//!
|
|
//! 1. **batch == streaming** — `batch()` must replay `update()` exactly.
|
|
//! 2. **reset == fresh** — after `reset()`, re-feeding the same data must match
|
|
//! a freshly constructed instance.
|
|
//! 3. **non-finite is rejected without poisoning** — a NaN/inf tick returns
|
|
//! `None` and leaves state identical to never having seen it. `Candle` and the
|
|
//! other validated input types cannot be non-finite, so this applies to the
|
|
//! `f64` and `(f64, f64)` families. This is the regression net that would have
|
|
//! caught the pairwise non-finite bug (#251).
|
|
|
|
use proptest::prelude::*;
|
|
use wickra_core::*;
|
|
|
|
// --- generic invariant bodies ------------------------------------------------
|
|
|
|
// One generic body for every `Indicator` family. Inputs are compared via Debug
|
|
// so bit-identical NaN outputs count as equal (NaN != NaN would otherwise break
|
|
// equality for indicators that emit NaN on degenerate input — these properties
|
|
// are about determinism, not NaN-freeness).
|
|
fn check_seq<I>(make: impl Fn() -> I, xs: &[I::Input]) -> std::result::Result<(), TestCaseError>
|
|
where
|
|
I: Indicator,
|
|
I::Input: Clone,
|
|
I::Output: std::fmt::Debug,
|
|
{
|
|
let batch = make().batch(xs);
|
|
let mut s = make();
|
|
let stream: Vec<_> = xs.iter().map(|x| s.update(x.clone())).collect();
|
|
prop_assert_eq!(
|
|
format!("{batch:?}"),
|
|
format!("{stream:?}"),
|
|
"batch != streaming"
|
|
);
|
|
|
|
let mut a = make();
|
|
let _ = a.batch(xs);
|
|
a.reset();
|
|
let after: Vec<_> = xs.iter().map(|x| a.update(x.clone())).collect();
|
|
prop_assert_eq!(
|
|
format!("{after:?}"),
|
|
format!("{stream:?}"),
|
|
"reset != fresh"
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
// BarBuilder has a different shape (`update(Candle) -> Vec<Bar>`), so it gets its
|
|
// own body. `batch` concatenates per-candle bars; streaming flat-maps them.
|
|
fn check_bars<B>(make: impl Fn() -> B, candles: &[Candle]) -> std::result::Result<(), TestCaseError>
|
|
where
|
|
B: BarBuilder,
|
|
B::Bar: std::fmt::Debug,
|
|
{
|
|
let batch = make().batch(candles);
|
|
let mut s = make();
|
|
let stream: Vec<_> = candles.iter().flat_map(|&c| s.update(c)).collect();
|
|
prop_assert_eq!(
|
|
format!("{batch:?}"),
|
|
format!("{stream:?}"),
|
|
"batch != streaming"
|
|
);
|
|
|
|
let mut a = make();
|
|
let _ = a.batch(candles);
|
|
a.reset();
|
|
let after: Vec<_> = candles.iter().flat_map(|&c| a.update(c)).collect();
|
|
prop_assert_eq!(
|
|
format!("{after:?}"),
|
|
format!("{stream:?}"),
|
|
"reset != fresh"
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
// Non-finite rejection for the `f64` family: a NaN/inf tick returns `None` and
|
|
// does not poison state (the poisoned run must match a clean one). Only applies
|
|
// to scalar/pairwise inputs — `Candle` and the exotic types validate finiteness
|
|
// at construction.
|
|
fn check_scalar_nonfinite<I>(
|
|
make: impl Fn() -> I,
|
|
xs: &[f64],
|
|
) -> std::result::Result<(), TestCaseError>
|
|
where
|
|
I: Indicator<Input = f64>,
|
|
I::Output: std::fmt::Debug,
|
|
{
|
|
let mut s = make();
|
|
let clean: Vec<_> = xs.iter().map(|&x| s.update(x)).collect();
|
|
let mut g = make();
|
|
prop_assert!(g.update(f64::NAN).is_none(), "NaN not rejected");
|
|
prop_assert!(g.update(f64::INFINITY).is_none(), "inf not rejected");
|
|
prop_assert!(g.update(f64::NEG_INFINITY).is_none(), "-inf not rejected");
|
|
let poisoned: Vec<_> = xs.iter().map(|&x| g.update(x)).collect();
|
|
prop_assert_eq!(
|
|
format!("{poisoned:?}"),
|
|
format!("{clean:?}"),
|
|
"non-finite poisoned state"
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
// Non-finite rejection for the `(f64, f64)` family.
|
|
fn check_pairwise_nonfinite<I>(
|
|
make: impl Fn() -> I,
|
|
xs: &[(f64, f64)],
|
|
) -> std::result::Result<(), TestCaseError>
|
|
where
|
|
I: Indicator<Input = (f64, f64)>,
|
|
I::Output: std::fmt::Debug,
|
|
{
|
|
let mut s = make();
|
|
let clean: Vec<_> = xs.iter().map(|&p| s.update(p)).collect();
|
|
let mut g = make();
|
|
prop_assert!(g.update((f64::NAN, 1.0)).is_none(), "NaN not rejected");
|
|
prop_assert!(g.update((1.0, f64::INFINITY)).is_none(), "inf not rejected");
|
|
let poisoned: Vec<_> = xs.iter().map(|&p| g.update(p)).collect();
|
|
prop_assert_eq!(
|
|
format!("{poisoned:?}"),
|
|
format!("{clean:?}"),
|
|
"non-finite poisoned state"
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
// --- per-family roll-out macros ----------------------------------------------
|
|
|
|
macro_rules! scalar_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(24))]
|
|
#[test]
|
|
fn $name(xs in prop::collection::vec(-1.0e6f64..1.0e6, 0..160)) {
|
|
check_seq(|| { $($ctor)+ }, &xs)?;
|
|
check_scalar_nonfinite(|| { $($ctor)+ }, &xs)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! candle_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(24))]
|
|
#[test]
|
|
fn $name(
|
|
raw in prop::collection::vec(
|
|
(1.0e1f64..1.0e4, 0.0f64..200.0, 0.0f64..1.0, 0.0f64..1.0),
|
|
0..160,
|
|
)
|
|
) {
|
|
// (low, range, open_frac, close_frac) -> a valid OHLC candle.
|
|
let candles: Vec<Candle> = raw
|
|
.iter()
|
|
.map(|&(low, range, of, cf)| {
|
|
Candle::new(low + range * of, low + range, low, low + range * cf, 1.0, 0)
|
|
.expect("constructed valid candle")
|
|
})
|
|
.collect();
|
|
check_seq(|| { $($ctor)+ }, &candles)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! pair_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(24))]
|
|
#[test]
|
|
fn $name(
|
|
xs in prop::collection::vec((-1.0e6f64..1.0e6, -1.0e6f64..1.0e6), 0..160)
|
|
) {
|
|
check_seq(|| { $($ctor)+ }, &xs)?;
|
|
check_pairwise_nonfinite(|| { $($ctor)+ }, &xs)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! cross_section_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(16))]
|
|
#[test]
|
|
fn $name(
|
|
raw in prop::collection::vec(
|
|
prop::collection::vec(
|
|
(-1.0e3f64..1.0e3, 0.0f64..1.0e6, any::<bool>(), any::<bool>(), any::<bool>(), any::<bool>()),
|
|
4..=4,
|
|
),
|
|
0..80,
|
|
)
|
|
) {
|
|
let ticks: Vec<CrossSection> = raw
|
|
.iter()
|
|
.map(|members| {
|
|
let m = members
|
|
.iter()
|
|
.map(|&(c, v, nh, nl, a, o)| Member::with_signals(c, v, nh, nl, a, o))
|
|
.collect();
|
|
CrossSection::new(m, 0).expect("valid cross-section")
|
|
})
|
|
.collect();
|
|
check_seq(|| { $($ctor)+ }, &ticks)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! trade_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(24))]
|
|
#[test]
|
|
fn $name(raw in prop::collection::vec((1.0f64..1.0e5, 0.0f64..1.0e4, any::<bool>()), 0..160)) {
|
|
let ticks: Vec<Trade> = raw
|
|
.iter()
|
|
.map(|&(p, s, b)| Trade::new(p, s, if b { Side::Buy } else { Side::Sell }, 0).expect("valid trade"))
|
|
.collect();
|
|
check_seq(|| { $($ctor)+ }, &ticks)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! deriv_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(16))]
|
|
#[test]
|
|
fn $name(
|
|
raw in prop::collection::vec(
|
|
(
|
|
(-1.0f64..1.0, 1.0f64..1.0e5, 1.0f64..1.0e5, 1.0f64..1.0e5),
|
|
(0.0f64..1.0e6, 0.0f64..1.0e6, 0.0f64..1.0e6, 0.0f64..1.0e6),
|
|
(0.0f64..1.0e6, 0.0f64..1.0e6, 0.0f64..1.0e6),
|
|
),
|
|
0..120,
|
|
)
|
|
) {
|
|
let ticks: Vec<DerivativesTick> = raw
|
|
.iter()
|
|
.map(|&((fr, mk, ix, fu), (oi, ls, ss, tbv), (tsv, ll, sl))| {
|
|
DerivativesTick::new(fr, mk, ix, fu, oi, ls, ss, tbv, tsv, ll, sl, 0).expect("valid deriv tick")
|
|
})
|
|
.collect();
|
|
check_seq(|| { $($ctor)+ }, &ticks)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! orderbook_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(16))]
|
|
#[test]
|
|
fn $name(raw in prop::collection::vec((1.0e2f64..1.0e4, 0.1f64..10.0, 0.0f64..1.0e4), 0..100)) {
|
|
// mid +/- k*gap gives strictly-monotonic, uncrossed books (best_bid < best_ask).
|
|
let books: Vec<OrderBook> = raw
|
|
.iter()
|
|
.map(|&(mid, gap, sz)| {
|
|
let asks = (1..=3).map(|k| Level::new(mid + f64::from(k) * gap, sz).expect("ask")).collect();
|
|
let bids = (1..=3).map(|k| Level::new(mid - f64::from(k) * gap, sz).expect("bid")).collect();
|
|
OrderBook::new(bids, asks).expect("valid book")
|
|
})
|
|
.collect();
|
|
check_seq(|| { $($ctor)+ }, &books)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! tradequote_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(24))]
|
|
#[test]
|
|
fn $name(raw in prop::collection::vec((1.0f64..1.0e5, 0.0f64..1.0e4, any::<bool>(), 1.0f64..1.0e5), 0..160)) {
|
|
let tqs: Vec<TradeQuote> = raw
|
|
.iter()
|
|
.map(|&(p, s, b, mid)| {
|
|
let tr = Trade::new(p, s, if b { Side::Buy } else { Side::Sell }, 0).expect("trade");
|
|
TradeQuote::new(tr, mid).expect("valid trade-quote")
|
|
})
|
|
.collect();
|
|
check_seq(|| { $($ctor)+ }, &tqs)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! bar_inv {
|
|
($name:ident, $($ctor:tt)+) => {
|
|
proptest! {
|
|
#![proptest_config(ProptestConfig::with_cases(24))]
|
|
#[test]
|
|
fn $name(
|
|
raw in prop::collection::vec(
|
|
(1.0e1f64..1.0e4, 0.0f64..200.0, 0.0f64..1.0, 0.0f64..1.0),
|
|
0..160,
|
|
)
|
|
) {
|
|
let candles: Vec<Candle> = raw
|
|
.iter()
|
|
.map(|&(low, range, of, cf)| {
|
|
Candle::new(low + range * of, low + range, low, low + range * cf, 1.0, 0)
|
|
.expect("constructed valid candle")
|
|
})
|
|
.collect();
|
|
check_bars(|| { $($ctor)+ }, &candles)?;
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
// --- catalogue: full roll-out over the whole catalogue (513 of 514 mod entries:
|
|
// 503 Indicator + 10 BarBuilder; pattern_swing is neither, see below). ---
|
|
|
|
// --- scalar (167) ---
|
|
scalar_inv!(inv_adaptive_cycle, AdaptiveCycle::new());
|
|
scalar_inv!(
|
|
inv_adaptive_laguerre_filter,
|
|
AdaptiveLaguerreFilter::new(13).unwrap()
|
|
);
|
|
scalar_inv!(inv_adaptive_rsi, AdaptiveRsi::new(14).unwrap());
|
|
scalar_inv!(inv_alma, Alma::new(9, 0.85, 6.0).unwrap());
|
|
scalar_inv!(inv_anchored_rsi, AnchoredRsi::new());
|
|
scalar_inv!(inv_apo, Apo::new(12, 26).unwrap());
|
|
scalar_inv!(inv_autocorrelation, Autocorrelation::new(20, 1).unwrap());
|
|
scalar_inv!(
|
|
inv_autocorrelation_periodogram,
|
|
AutocorrelationPeriodogram::new(10, 48).unwrap()
|
|
);
|
|
scalar_inv!(inv_average_drawdown, AverageDrawdown::new(10).unwrap());
|
|
scalar_inv!(inv_bandpass_filter, BandpassFilter::new(20, 0.3).unwrap());
|
|
scalar_inv!(inv_bipower_variation, BipowerVariation::new(20).unwrap());
|
|
scalar_inv!(inv_bollinger, BollingerBands::new(5, 2.0).unwrap());
|
|
scalar_inv!(
|
|
inv_bollinger_bandwidth,
|
|
BollingerBandwidth::new(20, 2.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_bomar_bands, BomarBands::new(20, 0.85).unwrap());
|
|
scalar_inv!(inv_burke_ratio, BurkeRatio::new(12).unwrap());
|
|
scalar_inv!(inv_calmar_ratio, CalmarRatio::new(20).unwrap());
|
|
scalar_inv!(inv_center_of_gravity, CenterOfGravity::new(10).unwrap());
|
|
scalar_inv!(inv_cfo, Cfo::new(14).unwrap());
|
|
scalar_inv!(inv_cmo, Cmo::new(14).unwrap());
|
|
scalar_inv!(
|
|
inv_coefficient_of_variation,
|
|
CoefficientOfVariation::new(20).unwrap()
|
|
);
|
|
scalar_inv!(inv_common_sense_ratio, CommonSenseRatio::new(20).unwrap());
|
|
scalar_inv!(
|
|
inv_conditional_value_at_risk,
|
|
ConditionalValueAtRisk::new(100, 0.95).unwrap()
|
|
);
|
|
scalar_inv!(inv_connors_rsi, ConnorsRsi::new(3, 2, 5).unwrap());
|
|
scalar_inv!(inv_coppock, Coppock::new(14, 11, 10).unwrap());
|
|
scalar_inv!(
|
|
inv_correlation_trend_indicator,
|
|
CorrelationTrendIndicator::new(20).unwrap()
|
|
);
|
|
scalar_inv!(inv_cybernetic_cycle, CyberneticCycle::new(10).unwrap());
|
|
scalar_inv!(inv_decycler, Decycler::new(20).unwrap());
|
|
scalar_inv!(
|
|
inv_decycler_oscillator,
|
|
DecyclerOscillator::new(10, 30).unwrap()
|
|
);
|
|
scalar_inv!(inv_dema, Dema::new(3).unwrap());
|
|
scalar_inv!(
|
|
inv_derivative_oscillator,
|
|
DerivativeOscillator::new(14, 5, 3, 9).unwrap()
|
|
);
|
|
scalar_inv!(inv_detrended_std_dev, DetrendedStdDev::new(14).unwrap());
|
|
scalar_inv!(inv_disparity_index, DisparityIndex::new(14).unwrap());
|
|
scalar_inv!(
|
|
inv_double_bollinger,
|
|
DoubleBollinger::new(20, 1.0, 2.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_dpo, Dpo::new(20).unwrap());
|
|
scalar_inv!(inv_drawdown_duration, DrawdownDuration::new());
|
|
scalar_inv!(
|
|
inv_dynamic_momentum_index,
|
|
DynamicMomentumIndex::new(14).unwrap()
|
|
);
|
|
scalar_inv!(inv_ehlers_stochastic, EhlersStochastic::new(20).unwrap());
|
|
scalar_inv!(inv_ehma, Ehma::new(9).unwrap());
|
|
scalar_inv!(inv_elder_impulse, ElderImpulse::new(3, 2, 4, 3).unwrap());
|
|
scalar_inv!(inv_ema, Ema::new(3).unwrap());
|
|
scalar_inv!(
|
|
inv_empirical_mode_decomposition,
|
|
EmpiricalModeDecomposition::new(20, 0.5).unwrap()
|
|
);
|
|
scalar_inv!(
|
|
inv_even_better_sinewave,
|
|
EvenBetterSinewave::new(40, 10).unwrap()
|
|
);
|
|
scalar_inv!(inv_ewma_volatility, EwmaVolatility::new(0.94).unwrap());
|
|
scalar_inv!(inv_expectancy, Expectancy::new(4).unwrap());
|
|
scalar_inv!(inv_fama, Fama::new(0.5, 0.05).unwrap());
|
|
scalar_inv!(inv_fisher_rsi, FisherRsi::new(9).unwrap());
|
|
scalar_inv!(inv_fisher_transform, FisherTransform::new(10).unwrap());
|
|
scalar_inv!(inv_frama, Frama::new(16).unwrap());
|
|
scalar_inv!(inv_gain_loss_ratio, GainLossRatio::new(10).unwrap());
|
|
scalar_inv!(inv_gain_to_pain_ratio, GainToPainRatio::new(12).unwrap());
|
|
scalar_inv!(inv_garch11, Garch11::new(0.000_002, 0.10, 0.88).unwrap());
|
|
scalar_inv!(inv_generalized_dema, GeneralizedDema::new(5, 0.7).unwrap());
|
|
scalar_inv!(inv_geometric_ma, GeometricMa::new(5).unwrap());
|
|
scalar_inv!(inv_highpass_filter, HighpassFilter::new(48).unwrap());
|
|
scalar_inv!(inv_hilbert_dominant_cycle, HilbertDominantCycle::new());
|
|
scalar_inv!(
|
|
inv_historical_volatility,
|
|
HistoricalVolatility::new(20, 252).unwrap()
|
|
);
|
|
scalar_inv!(inv_hma, Hma::new(9).unwrap());
|
|
scalar_inv!(inv_holt_winters, HoltWinters::new(0.2, 0.1).unwrap());
|
|
scalar_inv!(inv_ht_dcphase, HtDcPhase::new());
|
|
scalar_inv!(inv_ht_phasor, HtPhasor::new());
|
|
scalar_inv!(inv_ht_trendmode, HtTrendMode::new());
|
|
scalar_inv!(inv_hurst_exponent, HurstExponent::new(100, 4).unwrap());
|
|
scalar_inv!(
|
|
inv_instantaneous_trendline,
|
|
InstantaneousTrendline::new(20).unwrap()
|
|
);
|
|
scalar_inv!(
|
|
inv_inverse_fisher_transform,
|
|
InverseFisherTransform::new(1.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_jarque_bera, JarqueBera::new(50).unwrap());
|
|
scalar_inv!(inv_jma, Jma::new(14, 0.0, 2).unwrap());
|
|
scalar_inv!(inv_jump_indicator, JumpIndicator::new(20, 3.0).unwrap());
|
|
scalar_inv!(inv_k_ratio, KRatio::new(30).unwrap());
|
|
scalar_inv!(inv_kama, Kama::new(10, 2, 30).unwrap());
|
|
scalar_inv!(inv_kelly_criterion, KellyCriterion::new(10).unwrap());
|
|
scalar_inv!(inv_kst, Kst::new(2, 3, 4, 5, 2, 2, 2, 3, 2).unwrap());
|
|
scalar_inv!(inv_kurtosis, Kurtosis::new(20).unwrap());
|
|
scalar_inv!(inv_laguerre_rsi, LaguerreRsi::new(0.5).unwrap());
|
|
scalar_inv!(inv_linreg, LinearRegression::new(14).unwrap());
|
|
scalar_inv!(inv_linreg_angle, LinRegAngle::new(14).unwrap());
|
|
scalar_inv!(inv_linreg_channel, LinRegChannel::new(20, 2.0).unwrap());
|
|
scalar_inv!(inv_linreg_intercept, LinRegIntercept::new(14).unwrap());
|
|
scalar_inv!(inv_linreg_slope, LinRegSlope::new(14).unwrap());
|
|
scalar_inv!(inv_log_return, LogReturn::new(1).unwrap());
|
|
scalar_inv!(inv_m2_measure, M2Measure::new(20, 0.0, 0.02).unwrap());
|
|
scalar_inv!(inv_ma_envelope, MaEnvelope::new(20, 0.025).unwrap());
|
|
scalar_inv!(inv_macd, MacdIndicator::new(3, 6, 3).unwrap());
|
|
scalar_inv!(
|
|
inv_macd_ext,
|
|
MacdExt::new(12, MaType::Ema, 26, MaType::Ema, 9, MaType::Sma).unwrap()
|
|
);
|
|
scalar_inv!(inv_macd_fix, MacdFix::new(9).unwrap());
|
|
scalar_inv!(inv_macd_histogram, MacdHistogram::new(12, 26, 9).unwrap());
|
|
scalar_inv!(inv_mama, Mama::new(0.5, 0.05).unwrap());
|
|
scalar_inv!(inv_martin_ratio, MartinRatio::new(14).unwrap());
|
|
scalar_inv!(inv_max_drawdown, MaxDrawdown::new(10).unwrap());
|
|
scalar_inv!(inv_mcginley_dynamic, McGinleyDynamic::new(10).unwrap());
|
|
scalar_inv!(
|
|
inv_median_absolute_deviation,
|
|
MedianAbsoluteDeviation::new(20).unwrap()
|
|
);
|
|
scalar_inv!(inv_median_channel, MedianChannel::new(20, 2.0).unwrap());
|
|
scalar_inv!(inv_median_ma, MedianMa::new(5).unwrap());
|
|
scalar_inv!(inv_mid_point, MidPoint::new(5).unwrap());
|
|
scalar_inv!(inv_mom, Mom::new(3).unwrap());
|
|
scalar_inv!(inv_omega_ratio, OmegaRatio::new(20, 0.0).unwrap());
|
|
scalar_inv!(inv_pain_index, PainIndex::new(10).unwrap());
|
|
scalar_inv!(inv_percent_b, PercentB::new(20, 2.0).unwrap());
|
|
scalar_inv!(
|
|
inv_percentage_trailing_stop,
|
|
PercentageTrailingStop::new(5.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_pmo, Pmo::new(35, 20).unwrap());
|
|
scalar_inv!(
|
|
inv_polarized_fractal_efficiency,
|
|
PolarizedFractalEfficiency::new(10, 5).unwrap()
|
|
);
|
|
scalar_inv!(inv_ppo, Ppo::new(12, 26).unwrap());
|
|
scalar_inv!(inv_ppo_histogram, PpoHistogram::new(12, 26, 9).unwrap());
|
|
scalar_inv!(inv_profit_factor, ProfitFactor::new(20).unwrap());
|
|
scalar_inv!(inv_qqe, Qqe::new(14, 5, 4.236).unwrap());
|
|
scalar_inv!(inv_quartile_bands, QuartileBands::new(20).unwrap());
|
|
scalar_inv!(inv_r_squared, RSquared::new(14).unwrap());
|
|
scalar_inv!(
|
|
inv_realized_volatility,
|
|
RealizedVolatility::new(20).unwrap()
|
|
);
|
|
scalar_inv!(inv_recovery_factor, RecoveryFactor::new());
|
|
scalar_inv!(inv_reflex, Reflex::new(20).unwrap());
|
|
scalar_inv!(inv_regime_label, RegimeLabel::new(5, 20).unwrap());
|
|
scalar_inv!(
|
|
inv_renko_trailing_stop,
|
|
RenkoTrailingStop::new(1.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_rmi, Rmi::new(14, 5).unwrap());
|
|
scalar_inv!(inv_roc, Roc::new(3).unwrap());
|
|
scalar_inv!(inv_rocp, Rocp::new(3).unwrap());
|
|
scalar_inv!(inv_rocr, Rocr::new(3).unwrap());
|
|
scalar_inv!(inv_rocr100, Rocr100::new(3).unwrap());
|
|
scalar_inv!(inv_rolling_iqr, RollingIqr::new(20).unwrap());
|
|
scalar_inv!(
|
|
inv_rolling_min_max_scaler,
|
|
RollingMinMaxScaler::new(14).unwrap()
|
|
);
|
|
scalar_inv!(
|
|
inv_rolling_percentile_rank,
|
|
RollingPercentileRank::new(20).unwrap()
|
|
);
|
|
scalar_inv!(inv_rolling_quantile, RollingQuantile::new(5, 0.5).unwrap());
|
|
scalar_inv!(inv_roofing_filter, RoofingFilter::new(10, 48).unwrap());
|
|
scalar_inv!(inv_rsi, Rsi::new(3).unwrap());
|
|
scalar_inv!(inv_rsx, Rsx::new(14).unwrap());
|
|
scalar_inv!(inv_rvi_volatility, RviVolatility::new(10).unwrap());
|
|
scalar_inv!(inv_sample_entropy, SampleEntropy::new(50, 2, 0.2).unwrap());
|
|
scalar_inv!(inv_shannon_entropy, ShannonEntropy::new(32, 8).unwrap());
|
|
scalar_inv!(inv_sharpe_ratio, SharpeRatio::new(20, 0.0).unwrap());
|
|
scalar_inv!(inv_sine_wave, SineWave::new());
|
|
scalar_inv!(inv_sine_weighted_ma, SineWeightedMa::new(5).unwrap());
|
|
scalar_inv!(inv_skewness, Skewness::new(20).unwrap());
|
|
scalar_inv!(inv_sma, Sma::new(3).unwrap());
|
|
scalar_inv!(inv_smma, Smma::new(3).unwrap());
|
|
scalar_inv!(inv_sortino_ratio, SortinoRatio::new(20, 0.0).unwrap());
|
|
scalar_inv!(inv_standard_error, StandardError::new(14).unwrap());
|
|
scalar_inv!(
|
|
inv_standard_error_bands,
|
|
StandardErrorBands::new(21, 2.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_stc, Stc::new(3, 5, 4, 0.5).unwrap());
|
|
scalar_inv!(inv_std_dev, StdDev::new(20).unwrap());
|
|
scalar_inv!(inv_step_trailing_stop, StepTrailingStop::new(1.0).unwrap());
|
|
scalar_inv!(inv_sterling_ratio, SterlingRatio::new(12).unwrap());
|
|
scalar_inv!(inv_stoch_rsi, StochRsi::new(14, 14).unwrap());
|
|
scalar_inv!(inv_super_smoother, SuperSmoother::new(10).unwrap());
|
|
scalar_inv!(inv_t3, T3::new(5, 0.7).unwrap());
|
|
scalar_inv!(inv_tail_ratio, TailRatio::new(20).unwrap());
|
|
scalar_inv!(inv_tema, Tema::new(3).unwrap());
|
|
scalar_inv!(inv_tii, Tii::new(20, 10).unwrap());
|
|
scalar_inv!(inv_trend_label, TrendLabel::new(10).unwrap());
|
|
scalar_inv!(
|
|
inv_trend_strength_index,
|
|
TrendStrengthIndex::new(20).unwrap()
|
|
);
|
|
scalar_inv!(inv_trendflex, Trendflex::new(20).unwrap());
|
|
scalar_inv!(inv_trima, Trima::new(5).unwrap());
|
|
scalar_inv!(inv_trix, Trix::new(3).unwrap());
|
|
scalar_inv!(inv_tsf, Tsf::new(14).unwrap());
|
|
scalar_inv!(inv_tsf_oscillator, TsfOscillator::new(14).unwrap());
|
|
scalar_inv!(inv_tsi, Tsi::new(25, 13).unwrap());
|
|
scalar_inv!(inv_ulcer_index, UlcerIndex::new(14).unwrap());
|
|
scalar_inv!(
|
|
inv_universal_oscillator,
|
|
UniversalOscillator::new(20).unwrap()
|
|
);
|
|
scalar_inv!(
|
|
inv_upside_potential_ratio,
|
|
UpsidePotentialRatio::new(20, 0.0).unwrap()
|
|
);
|
|
scalar_inv!(inv_value_at_risk, ValueAtRisk::new(100, 0.95).unwrap());
|
|
scalar_inv!(inv_variance, Variance::new(20).unwrap());
|
|
scalar_inv!(
|
|
inv_vertical_horizontal_filter,
|
|
VerticalHorizontalFilter::new(28).unwrap()
|
|
);
|
|
scalar_inv!(inv_vidya, Vidya::new(14, 9).unwrap());
|
|
scalar_inv!(
|
|
inv_volatility_of_volatility,
|
|
VolatilityOfVolatility::new(20, 20).unwrap()
|
|
);
|
|
scalar_inv!(inv_wave_pm, WavePm::new(10, 3).unwrap());
|
|
scalar_inv!(inv_win_rate, WinRate::new(4).unwrap());
|
|
scalar_inv!(inv_wma, Wma::new(3).unwrap());
|
|
scalar_inv!(inv_z_score, ZScore::new(20).unwrap());
|
|
scalar_inv!(inv_zero_lag_macd, ZeroLagMacd::new(3, 5, 3).unwrap());
|
|
scalar_inv!(inv_zlema, Zlema::new(10).unwrap());
|
|
|
|
// --- candle (261) ---
|
|
candle_inv!(inv_abandoned_baby, AbandonedBaby::new());
|
|
candle_inv!(inv_abcd, Abcd::new());
|
|
candle_inv!(
|
|
inv_acceleration_bands,
|
|
AccelerationBands::new(20, 0.001).unwrap()
|
|
);
|
|
candle_inv!(
|
|
inv_accelerator_oscillator,
|
|
AcceleratorOscillator::new(5, 34, 5).unwrap()
|
|
);
|
|
candle_inv!(inv_ad_oscillator, AdOscillator::new());
|
|
candle_inv!(inv_adaptive_cci, AdaptiveCci::new(20).unwrap());
|
|
candle_inv!(inv_adl, Adl::new());
|
|
candle_inv!(inv_advance_block, AdvanceBlock::new());
|
|
candle_inv!(inv_adx, Adx::new(5).unwrap());
|
|
candle_inv!(inv_adxr, Adxr::new(5).unwrap());
|
|
candle_inv!(inv_alligator, Alligator::new(5, 3, 2).unwrap());
|
|
candle_inv!(inv_anchored_vwap, AnchoredVwap::new());
|
|
candle_inv!(inv_andrews_pitchfork, AndrewsPitchfork::new(2).unwrap());
|
|
candle_inv!(inv_aroon, Aroon::new(5).unwrap());
|
|
candle_inv!(inv_aroon_oscillator, AroonOscillator::new(5).unwrap());
|
|
candle_inv!(inv_atr, Atr::new(5).unwrap());
|
|
candle_inv!(inv_atr_bands, AtrBands::new(14, 3.0).unwrap());
|
|
candle_inv!(inv_atr_ratchet, AtrRatchet::new(14, 4.0, 0.1).unwrap());
|
|
candle_inv!(
|
|
inv_atr_trailing_stop,
|
|
AtrTrailingStop::new(14, 3.0).unwrap()
|
|
);
|
|
candle_inv!(inv_auto_fib, AutoFib::new());
|
|
candle_inv!(
|
|
inv_average_daily_range,
|
|
AverageDailyRange::new(2, 0).unwrap()
|
|
);
|
|
candle_inv!(inv_avg_price, AvgPrice::new());
|
|
candle_inv!(
|
|
inv_awesome_oscillator,
|
|
AwesomeOscillator::new(3, 10).unwrap()
|
|
);
|
|
candle_inv!(
|
|
inv_awesome_oscillator_histogram,
|
|
AwesomeOscillatorHistogram::new(3, 5, 3).unwrap()
|
|
);
|
|
candle_inv!(inv_balance_of_power, BalanceOfPower::new());
|
|
candle_inv!(inv_bat, Bat::new());
|
|
candle_inv!(inv_belt_hold, BeltHold::new());
|
|
candle_inv!(inv_better_volume, BetterVolume::new(20).unwrap());
|
|
candle_inv!(inv_body_size_pct, BodySizePct::new());
|
|
candle_inv!(inv_breakaway, Breakaway::new());
|
|
candle_inv!(inv_butterfly, Butterfly::new());
|
|
candle_inv!(inv_camarilla_pivots, Camarilla::new());
|
|
candle_inv!(inv_candle_volume, CandleVolume::new(14).unwrap());
|
|
candle_inv!(inv_cci, Cci::new(5).unwrap());
|
|
candle_inv!(inv_central_pivot_range, CentralPivotRange::new());
|
|
candle_inv!(
|
|
inv_chaikin_oscillator,
|
|
ChaikinOscillator::new(3, 10).unwrap()
|
|
);
|
|
candle_inv!(
|
|
inv_chaikin_volatility,
|
|
ChaikinVolatility::new(10, 10).unwrap()
|
|
);
|
|
candle_inv!(
|
|
inv_chande_kroll_stop,
|
|
ChandeKrollStop::new(10, 1.0, 9).unwrap()
|
|
);
|
|
candle_inv!(inv_chandelier_exit, ChandelierExit::new(22, 3.0).unwrap());
|
|
candle_inv!(inv_choppiness_index, ChoppinessIndex::new(14).unwrap());
|
|
candle_inv!(inv_classic_pivots, ClassicPivots::new());
|
|
candle_inv!(inv_close_vs_open, CloseVsOpen::new());
|
|
candle_inv!(inv_closing_marubozu, ClosingMarubozu::new());
|
|
candle_inv!(inv_cmf, ChaikinMoneyFlow::new(20).unwrap());
|
|
candle_inv!(
|
|
inv_composite_profile,
|
|
CompositeProfile::new(100, 50, 0.70).unwrap()
|
|
);
|
|
candle_inv!(inv_concealing_baby_swallow, ConcealingBabySwallow::new());
|
|
candle_inv!(inv_counterattack, Counterattack::new());
|
|
candle_inv!(inv_crab, Crab::new());
|
|
candle_inv!(inv_cup_and_handle, CupAndHandle::new());
|
|
candle_inv!(inv_cypher, Cypher::new());
|
|
candle_inv!(inv_day_of_week_profile, DayOfWeekProfile::new(0));
|
|
candle_inv!(inv_demand_index, DemandIndex::new(10).unwrap());
|
|
candle_inv!(inv_demark_pivots, DemarkPivots::new());
|
|
candle_inv!(inv_doji, Doji::new());
|
|
candle_inv!(inv_doji_star, DojiStar::new());
|
|
candle_inv!(inv_donchian, Donchian::new(5).unwrap());
|
|
candle_inv!(inv_donchian_stop, DonchianStop::new(10).unwrap());
|
|
candle_inv!(inv_double_top_bottom, DoubleTopBottom::new());
|
|
candle_inv!(
|
|
inv_downside_gap_three_methods,
|
|
DownsideGapThreeMethods::new()
|
|
);
|
|
candle_inv!(inv_dragonfly_doji, DragonflyDoji::new());
|
|
candle_inv!(inv_dumpling_top, DumplingTop::new(9).unwrap());
|
|
candle_inv!(inv_dx, Dx::new(5).unwrap());
|
|
candle_inv!(inv_ease_of_movement, EaseOfMovement::new(14).unwrap());
|
|
candle_inv!(inv_elder_ray, ElderRay::new(13).unwrap());
|
|
candle_inv!(inv_elder_safezone, ElderSafeZone::new(14, 2.0).unwrap());
|
|
candle_inv!(inv_engulfing, Engulfing::new());
|
|
candle_inv!(inv_equivolume, Equivolume::new(14).unwrap());
|
|
candle_inv!(inv_evening_doji_star, EveningDojiStar::new());
|
|
candle_inv!(inv_evwma, Evwma::new(20).unwrap());
|
|
candle_inv!(inv_falling_three_methods, FallingThreeMethods::new());
|
|
candle_inv!(inv_fib_arcs, FibArcs::new());
|
|
candle_inv!(inv_fib_channel, FibChannel::new());
|
|
candle_inv!(inv_fib_confluence, FibConfluence::new());
|
|
candle_inv!(inv_fib_extension, FibExtension::new());
|
|
candle_inv!(inv_fib_fan, FibFan::new());
|
|
candle_inv!(inv_fib_projection, FibProjection::new());
|
|
candle_inv!(inv_fib_retracement, FibRetracement::new());
|
|
candle_inv!(inv_fib_time_zones, FibTimeZones::new());
|
|
candle_inv!(inv_fibonacci_pivots, FibonacciPivots::new());
|
|
candle_inv!(inv_flag_pennant, FlagPennant::new());
|
|
candle_inv!(inv_force_index, ForceIndex::new(13).unwrap());
|
|
candle_inv!(inv_fractal_chaos_bands, FractalChaosBands::new(2).unwrap());
|
|
candle_inv!(inv_fry_pan_bottom, FryPanBottom::new(9).unwrap());
|
|
candle_inv!(inv_gap_side_by_side_white, GapSideBySideWhite::new());
|
|
candle_inv!(
|
|
inv_garman_klass,
|
|
GarmanKlassVolatility::new(20, 252).unwrap()
|
|
);
|
|
candle_inv!(inv_gartley, Gartley::new());
|
|
candle_inv!(inv_gator_oscillator, GatorOscillator::new(5, 3, 2).unwrap());
|
|
candle_inv!(inv_golden_pocket, GoldenPocket::new());
|
|
candle_inv!(inv_gravestone_doji, GravestoneDoji::new());
|
|
candle_inv!(inv_hammer, Hammer::new());
|
|
candle_inv!(inv_hanging_man, HangingMan::new());
|
|
candle_inv!(inv_harami, Harami::new());
|
|
candle_inv!(inv_harami_cross, HaramiCross::new());
|
|
candle_inv!(inv_head_and_shoulders, HeadAndShoulders::new());
|
|
candle_inv!(inv_heikin_ashi, HeikinAshi::new());
|
|
candle_inv!(
|
|
inv_heikin_ashi_oscillator,
|
|
HeikinAshiOscillator::new(5).unwrap()
|
|
);
|
|
candle_inv!(inv_high_low_range, HighLowRange::new());
|
|
candle_inv!(
|
|
inv_high_low_volume_nodes,
|
|
HighLowVolumeNodes::new(20, 24).unwrap()
|
|
);
|
|
candle_inv!(inv_high_wave, HighWave::new());
|
|
candle_inv!(inv_hikkake, Hikkake::new());
|
|
candle_inv!(inv_hikkake_modified, HikkakeModified::new());
|
|
candle_inv!(inv_hilo_activator, HiLoActivator::new(3).unwrap());
|
|
candle_inv!(inv_homing_pigeon, HomingPigeon::new());
|
|
candle_inv!(inv_hurst_channel, HurstChannel::new(10, 0.5).unwrap());
|
|
candle_inv!(inv_ichimoku, Ichimoku::new(5, 10, 20, 10).unwrap());
|
|
candle_inv!(inv_identical_three_crows, IdenticalThreeCrows::new());
|
|
candle_inv!(inv_in_neck, InNeck::new());
|
|
candle_inv!(inv_inertia, Inertia::new(14, 20).unwrap());
|
|
candle_inv!(inv_initial_balance, InitialBalance::new(3).unwrap());
|
|
candle_inv!(inv_intraday_intensity, IntradayIntensity::new());
|
|
candle_inv!(
|
|
inv_intraday_momentum_index,
|
|
IntradayMomentumIndex::new(14).unwrap()
|
|
);
|
|
candle_inv!(
|
|
inv_intraday_volatility_profile,
|
|
IntradayVolatilityProfile::new(24, 0).unwrap()
|
|
);
|
|
candle_inv!(inv_inverted_hammer, InvertedHammer::new());
|
|
candle_inv!(inv_kase_devstop, KaseDevStop::new(30, 1.0).unwrap());
|
|
candle_inv!(
|
|
inv_kase_permission_stochastic,
|
|
KasePermissionStochastic::new(9, 3).unwrap()
|
|
);
|
|
candle_inv!(inv_keltner, Keltner::new(5, 5, 2.0).unwrap());
|
|
candle_inv!(inv_kicking, Kicking::new());
|
|
candle_inv!(inv_kicking_by_length, KickingByLength::new());
|
|
candle_inv!(inv_kvo, Kvo::new(34, 55).unwrap());
|
|
candle_inv!(inv_ladder_bottom, LadderBottom::new());
|
|
candle_inv!(inv_long_legged_doji, LongLeggedDoji::new());
|
|
candle_inv!(inv_long_line, LongLine::new());
|
|
candle_inv!(
|
|
inv_market_facilitation_index,
|
|
MarketFacilitationIndex::new()
|
|
);
|
|
candle_inv!(inv_marubozu, Marubozu::new());
|
|
candle_inv!(inv_mass_index, MassIndex::new(9, 25).unwrap());
|
|
candle_inv!(inv_mat_hold, MatHold::new());
|
|
candle_inv!(inv_matching_low, MatchingLow::new());
|
|
candle_inv!(inv_median_price, MedianPrice::new());
|
|
candle_inv!(inv_mfi, Mfi::new(5).unwrap());
|
|
candle_inv!(inv_mid_price, MidPrice::new(5).unwrap());
|
|
candle_inv!(inv_minus_di, MinusDi::new(5).unwrap());
|
|
candle_inv!(inv_minus_dm, MinusDm::new(5).unwrap());
|
|
candle_inv!(inv_modified_ma_stop, ModifiedMaStop::new(14).unwrap());
|
|
candle_inv!(inv_morning_doji_star, MorningDojiStar::new());
|
|
candle_inv!(inv_morning_evening_star, MorningEveningStar::new());
|
|
candle_inv!(inv_murrey_math_lines, MurreyMathLines::new(64).unwrap());
|
|
candle_inv!(inv_naked_poc, NakedPoc::new(20, 24).unwrap());
|
|
candle_inv!(inv_natr, Natr::new(14).unwrap());
|
|
candle_inv!(inv_new_price_lines, NewPriceLines::new(8).unwrap());
|
|
candle_inv!(inv_nrtr, Nrtr::new(2.0).unwrap());
|
|
candle_inv!(inv_nvi, Nvi::new());
|
|
candle_inv!(inv_obv, Obv::new());
|
|
candle_inv!(inv_on_neck, OnNeck::new());
|
|
candle_inv!(inv_opening_marubozu, OpeningMarubozu::new());
|
|
candle_inv!(inv_opening_range, OpeningRange::new(2).unwrap());
|
|
candle_inv!(inv_overnight_gap, OvernightGap::new(0));
|
|
candle_inv!(
|
|
inv_overnight_intraday_return,
|
|
OvernightIntradayReturn::new(0)
|
|
);
|
|
candle_inv!(inv_parkinson, ParkinsonVolatility::new(20, 252).unwrap());
|
|
candle_inv!(inv_pgo, Pgo::new(14).unwrap());
|
|
candle_inv!(inv_piercing_dark_cloud, PiercingDarkCloud::new());
|
|
candle_inv!(inv_pivot_reversal, PivotReversal::new(2, 2).unwrap());
|
|
candle_inv!(inv_plus_di, PlusDi::new(5).unwrap());
|
|
candle_inv!(inv_plus_dm, PlusDm::new(5).unwrap());
|
|
candle_inv!(inv_profile_shape, ProfileShape::new(20, 24).unwrap());
|
|
candle_inv!(inv_projection_bands, ProjectionBands::new(14).unwrap());
|
|
candle_inv!(
|
|
inv_projection_oscillator,
|
|
ProjectionOscillator::new(14).unwrap()
|
|
);
|
|
candle_inv!(inv_psar, Psar::new(0.02, 0.02, 0.2).unwrap());
|
|
candle_inv!(inv_pvi, Pvi::new());
|
|
candle_inv!(inv_qstick, Qstick::new(5).unwrap());
|
|
candle_inv!(inv_rectangle_range, RectangleRange::new());
|
|
candle_inv!(inv_rickshaw_man, RickshawMan::new());
|
|
candle_inv!(inv_rising_three_methods, RisingThreeMethods::new());
|
|
candle_inv!(
|
|
inv_rogers_satchell,
|
|
RogersSatchellVolatility::new(20, 252).unwrap()
|
|
);
|
|
candle_inv!(inv_rvi, Rvi::new(10).unwrap());
|
|
candle_inv!(inv_rwi, Rwi::new(14).unwrap());
|
|
candle_inv!(
|
|
inv_sar_ext,
|
|
SarExt::new(0.0, 0.0, 0.02, 0.02, 0.2, 0.02, 0.02, 0.2).unwrap()
|
|
);
|
|
candle_inv!(inv_seasonal_z_score, SeasonalZScore::new(0));
|
|
candle_inv!(inv_separating_lines, SeparatingLines::new());
|
|
candle_inv!(inv_session_high_low, SessionHighLow::new(0));
|
|
candle_inv!(inv_session_range, SessionRange::new(0));
|
|
candle_inv!(inv_session_vwap, SessionVwap::new(0));
|
|
candle_inv!(inv_shark, Shark::new());
|
|
candle_inv!(inv_shooting_star, ShootingStar::new());
|
|
candle_inv!(inv_short_line, ShortLine::new());
|
|
candle_inv!(inv_single_prints, SinglePrints::new(20, 24).unwrap());
|
|
candle_inv!(inv_smi, Smi::new(5, 3, 3).unwrap());
|
|
candle_inv!(
|
|
inv_smoothed_heikin_ashi,
|
|
SmoothedHeikinAshi::new(10).unwrap()
|
|
);
|
|
candle_inv!(inv_spinning_top, SpinningTop::new());
|
|
candle_inv!(inv_stalled_pattern, StalledPattern::new());
|
|
candle_inv!(inv_starc_bands, StarcBands::new(6, 15, 2.0).unwrap());
|
|
candle_inv!(inv_stick_sandwich, StickSandwich::new());
|
|
candle_inv!(inv_stochastic, Stochastic::new(5, 3).unwrap());
|
|
candle_inv!(inv_stochastic_cci, StochasticCci::new(14).unwrap());
|
|
candle_inv!(inv_super_trend, SuperTrend::new(10, 3.0).unwrap());
|
|
candle_inv!(inv_takuri, Takuri::new());
|
|
candle_inv!(inv_tasuki_gap, TasukiGap::new());
|
|
candle_inv!(inv_td_camouflage, TdCamouflage::new());
|
|
candle_inv!(inv_td_clop, TdClop::new());
|
|
candle_inv!(inv_td_clopwin, TdClopwin::new());
|
|
candle_inv!(inv_td_combo, TdCombo::new(4, 9, 2, 13).unwrap());
|
|
candle_inv!(inv_td_countdown, TdCountdown::new(4, 9, 2, 13).unwrap());
|
|
candle_inv!(inv_td_demarker, TdDeMarker::new(14).unwrap());
|
|
candle_inv!(inv_td_differential, TdDifferential::new());
|
|
candle_inv!(inv_td_dwave, TdDWave::new(2).unwrap());
|
|
candle_inv!(inv_td_lines, TdLines::new(4, 9).unwrap());
|
|
candle_inv!(inv_td_moving_average, TdMovingAverage::new(5, 13).unwrap());
|
|
candle_inv!(inv_td_open, TdOpen::new());
|
|
candle_inv!(inv_td_pressure, TdPressure::new(5).unwrap());
|
|
candle_inv!(inv_td_propulsion, TdPropulsion::new());
|
|
candle_inv!(inv_td_range_projection, TdRangeProjection::new());
|
|
candle_inv!(inv_td_rei, TdRei::new(5).unwrap());
|
|
candle_inv!(inv_td_risk_level, TdRiskLevel::new(4, 9).unwrap());
|
|
candle_inv!(inv_td_sequential, TdSequential::new(4, 9, 2, 13).unwrap());
|
|
candle_inv!(inv_td_setup, TdSetup::new(4, 9).unwrap());
|
|
candle_inv!(inv_td_trap, TdTrap::new());
|
|
candle_inv!(inv_three_drives, ThreeDrives::new());
|
|
candle_inv!(inv_three_inside, ThreeInside::new());
|
|
candle_inv!(inv_three_line_break, ThreeLineBreak::new(3).unwrap());
|
|
candle_inv!(inv_three_line_strike, ThreeLineStrike::new());
|
|
candle_inv!(inv_three_outside, ThreeOutside::new());
|
|
candle_inv!(inv_three_soldiers_or_crows, ThreeSoldiersOrCrows::new());
|
|
candle_inv!(inv_three_stars_in_south, ThreeStarsInSouth::new());
|
|
candle_inv!(inv_thrusting, Thrusting::new());
|
|
candle_inv!(inv_time_based_stop, TimeBasedStop::new(5).unwrap());
|
|
candle_inv!(
|
|
inv_time_of_day_return_profile,
|
|
TimeOfDayReturnProfile::new(24, 0).unwrap()
|
|
);
|
|
candle_inv!(inv_tower_top_bottom, TowerTopBottom::new());
|
|
candle_inv!(inv_tpo_profile, TpoProfile::new(5, 10).unwrap());
|
|
candle_inv!(inv_trade_volume_index, TradeVolumeIndex::new(0.5).unwrap());
|
|
candle_inv!(inv_triangle, Triangle::new());
|
|
candle_inv!(inv_triple_top_bottom, TripleTopBottom::new());
|
|
candle_inv!(inv_tristar, Tristar::new());
|
|
candle_inv!(inv_true_range, TrueRange::new());
|
|
candle_inv!(inv_tsv, Tsv::new(18).unwrap());
|
|
candle_inv!(inv_ttm_squeeze, TtmSqueeze::new(20, 2.0, 1.5).unwrap());
|
|
candle_inv!(inv_ttm_trend, TtmTrend::new(6).unwrap());
|
|
candle_inv!(inv_turn_of_month, TurnOfMonth::new(3, 1, 0).unwrap());
|
|
candle_inv!(inv_tweezer, Tweezer::new());
|
|
candle_inv!(inv_twiggs_money_flow, TwiggsMoneyFlow::new(21).unwrap());
|
|
candle_inv!(inv_two_crows, TwoCrows::new());
|
|
candle_inv!(inv_typical_price, TypicalPrice::new());
|
|
candle_inv!(
|
|
inv_ultimate_oscillator,
|
|
UltimateOscillator::new(7, 14, 28).unwrap()
|
|
);
|
|
candle_inv!(inv_unique_three_river, UniqueThreeRiver::new());
|
|
candle_inv!(inv_upside_gap_three_methods, UpsideGapThreeMethods::new());
|
|
candle_inv!(inv_upside_gap_two_crows, UpsideGapTwoCrows::new());
|
|
candle_inv!(inv_value_area, ValueArea::new(5, 50, 0.70).unwrap());
|
|
candle_inv!(inv_volatility_cone, VolatilityCone::new(20, 60).unwrap());
|
|
candle_inv!(inv_volatility_ratio, VolatilityRatio::new(14).unwrap());
|
|
candle_inv!(inv_volty_stop, VoltyStop::new(14, 2.0).unwrap());
|
|
candle_inv!(
|
|
inv_volume_by_time_profile,
|
|
VolumeByTimeProfile::new(24, 0).unwrap()
|
|
);
|
|
candle_inv!(
|
|
inv_volume_oscillator,
|
|
VolumeOscillator::new(14, 28).unwrap()
|
|
);
|
|
candle_inv!(inv_volume_profile, VolumeProfile::new(5, 10).unwrap());
|
|
candle_inv!(inv_volume_rsi, VolumeRsi::new(14).unwrap());
|
|
candle_inv!(
|
|
inv_volume_weighted_macd,
|
|
VolumeWeightedMacd::new(12, 26, 9).unwrap()
|
|
);
|
|
candle_inv!(inv_volume_weighted_sr, VolumeWeightedSr::new(20).unwrap());
|
|
candle_inv!(inv_vortex, Vortex::new(14).unwrap());
|
|
candle_inv!(inv_vpt, VolumePriceTrend::new());
|
|
candle_inv!(inv_vwap, Vwap::new());
|
|
candle_inv!(inv_vwap_stddev_bands, VwapStdDevBands::new(2.0).unwrap());
|
|
candle_inv!(inv_vwma, Vwma::new(5).unwrap());
|
|
candle_inv!(inv_vzo, Vzo::new(14).unwrap());
|
|
candle_inv!(inv_wad, Wad::new());
|
|
candle_inv!(inv_wave_trend, WaveTrend::new(5, 8, 3).unwrap());
|
|
candle_inv!(inv_wedge, Wedge::new());
|
|
candle_inv!(inv_weighted_close, WeightedClose::new());
|
|
candle_inv!(inv_wick_ratio, WickRatio::new());
|
|
candle_inv!(inv_williams_fractals, WilliamsFractals::new());
|
|
candle_inv!(inv_williams_r, WilliamsR::new(5).unwrap());
|
|
candle_inv!(inv_woodie_pivots, WoodiePivots::new());
|
|
candle_inv!(inv_yang_zhang, YangZhangVolatility::new(20, 252).unwrap());
|
|
candle_inv!(inv_yoyo_exit, YoyoExit::new(14, 2.0).unwrap());
|
|
candle_inv!(inv_zig_zag, ZigZag::new(0.10).unwrap());
|
|
|
|
// --- pairwise (24) ---
|
|
pair_inv!(inv_alpha, Alpha::new(20, 0.001).unwrap());
|
|
pair_inv!(inv_beta, Beta::new(20).unwrap());
|
|
pair_inv!(inv_beta_neutral_spread, BetaNeutralSpread::new(20).unwrap());
|
|
pair_inv!(inv_cointegration, Cointegration::new(30, 1).unwrap());
|
|
pair_inv!(inv_distance_ssd, DistanceSsd::new(20).unwrap());
|
|
pair_inv!(inv_granger_causality, GrangerCausality::new(60, 1).unwrap());
|
|
pair_inv!(
|
|
inv_hasbrouck_information_share,
|
|
HasbrouckInformationShare::new(20).unwrap()
|
|
);
|
|
pair_inv!(inv_information_ratio, InformationRatio::new(10).unwrap());
|
|
pair_inv!(
|
|
inv_kalman_hedge_ratio,
|
|
KalmanHedgeRatio::new(1e-2, 1e-3).unwrap()
|
|
);
|
|
pair_inv!(inv_kendall_tau, KendallTau::new(20).unwrap());
|
|
pair_inv!(
|
|
inv_lead_lag_cross_correlation,
|
|
LeadLagCrossCorrelation::new(12, 5).unwrap()
|
|
);
|
|
pair_inv!(inv_ou_half_life, OuHalfLife::new(40).unwrap());
|
|
pair_inv!(inv_pair_spread_zscore, PairSpreadZScore::new(2, 2).unwrap());
|
|
pair_inv!(inv_pairwise_beta, PairwiseBeta::new(10).unwrap());
|
|
pair_inv!(
|
|
inv_pearson_correlation,
|
|
PearsonCorrelation::new(20).unwrap()
|
|
);
|
|
pair_inv!(
|
|
inv_relative_strength_ab,
|
|
RelativeStrengthAB::new(5, 5).unwrap()
|
|
);
|
|
pair_inv!(
|
|
inv_rolling_correlation,
|
|
RollingCorrelation::new(10).unwrap()
|
|
);
|
|
pair_inv!(inv_rolling_covariance, RollingCovariance::new(5).unwrap());
|
|
pair_inv!(
|
|
inv_spearman_correlation,
|
|
SpearmanCorrelation::new(10).unwrap()
|
|
);
|
|
pair_inv!(
|
|
inv_spread_ar1_coefficient,
|
|
SpreadAr1Coefficient::new(40).unwrap()
|
|
);
|
|
pair_inv!(
|
|
inv_spread_bollinger_bands,
|
|
SpreadBollingerBands::new(20, 2.0).unwrap()
|
|
);
|
|
pair_inv!(inv_spread_hurst, SpreadHurst::new(60).unwrap());
|
|
pair_inv!(inv_treynor_ratio, TreynorRatio::new(20, 0.001).unwrap());
|
|
pair_inv!(inv_variance_ratio, VarianceRatio::new(60, 2).unwrap());
|
|
|
|
// --- cross_section_inv (15) ---
|
|
cross_section_inv!(inv_absolute_breadth_index, AbsoluteBreadthIndex::new());
|
|
cross_section_inv!(inv_ad_volume_line, AdVolumeLine::new());
|
|
cross_section_inv!(inv_advance_decline, AdvanceDecline::new());
|
|
cross_section_inv!(inv_advance_decline_ratio, AdvanceDeclineRatio::new());
|
|
cross_section_inv!(inv_breadth_thrust, BreadthThrust::new(2).unwrap());
|
|
cross_section_inv!(inv_bullish_percent_index, BullishPercentIndex::new());
|
|
cross_section_inv!(inv_cumulative_volume_index, CumulativeVolumeIndex::new());
|
|
cross_section_inv!(inv_high_low_index, HighLowIndex::new(2).unwrap());
|
|
cross_section_inv!(inv_mcclellan_oscillator, McClellanOscillator::new());
|
|
cross_section_inv!(
|
|
inv_mcclellan_summation_index,
|
|
McClellanSummationIndex::new()
|
|
);
|
|
cross_section_inv!(inv_new_highs_new_lows, NewHighsNewLows::new());
|
|
cross_section_inv!(inv_percent_above_ma, PercentAboveMa::new());
|
|
cross_section_inv!(inv_tick_index, TickIndex::new());
|
|
cross_section_inv!(inv_trin, Trin::new());
|
|
cross_section_inv!(inv_up_down_volume_ratio, UpDownVolumeRatio::new());
|
|
|
|
// --- trade_inv (9) ---
|
|
trade_inv!(inv_amihud_illiquidity, AmihudIlliquidity::new(20).unwrap());
|
|
trade_inv!(inv_cvd, CumulativeVolumeDelta::new());
|
|
trade_inv!(inv_footprint, Footprint::new(1.0).unwrap());
|
|
trade_inv!(inv_pin, Pin::new(20).unwrap());
|
|
trade_inv!(inv_roll_measure, RollMeasure::new(20).unwrap());
|
|
trade_inv!(inv_signed_volume, SignedVolume::new());
|
|
trade_inv!(inv_trade_imbalance, TradeImbalance::new(2).unwrap());
|
|
trade_inv!(
|
|
inv_trade_sign_autocorrelation,
|
|
TradeSignAutocorrelation::new(20).unwrap()
|
|
);
|
|
trade_inv!(inv_vpin, Vpin::new(10.0, 2).unwrap());
|
|
|
|
// --- deriv_inv (17) ---
|
|
deriv_inv!(inv_calendar_spread, CalendarSpread::new());
|
|
deriv_inv!(inv_estimated_leverage_ratio, EstimatedLeverageRatio::new());
|
|
deriv_inv!(inv_funding_basis, FundingBasis::new());
|
|
deriv_inv!(
|
|
inv_funding_implied_apr,
|
|
FundingImpliedApr::new(1095.0).unwrap()
|
|
);
|
|
deriv_inv!(inv_funding_rate, FundingRate::new());
|
|
deriv_inv!(inv_funding_rate_mean, FundingRateMean::new(2).unwrap());
|
|
deriv_inv!(inv_funding_rate_zscore, FundingRateZScore::new(2).unwrap());
|
|
deriv_inv!(inv_liquidation_features, LiquidationFeatures::new());
|
|
deriv_inv!(inv_long_short_ratio, LongShortRatio::new());
|
|
deriv_inv!(inv_oi_delta, OpenInterestDelta::new());
|
|
deriv_inv!(inv_oi_price_divergence, OIPriceDivergence::new(1).unwrap());
|
|
deriv_inv!(inv_oi_to_volume_ratio, OiToVolumeRatio::new());
|
|
deriv_inv!(inv_oi_weighted, OIWeighted::new());
|
|
deriv_inv!(
|
|
inv_open_interest_momentum,
|
|
OpenInterestMomentum::new(5).unwrap()
|
|
);
|
|
deriv_inv!(inv_perpetual_premium_index, PerpetualPremiumIndex::new());
|
|
deriv_inv!(inv_taker_buy_sell_ratio, TakerBuySellRatio::new());
|
|
deriv_inv!(inv_term_structure_basis, TermStructureBasis::new());
|
|
|
|
// --- orderbook_inv (7) ---
|
|
orderbook_inv!(inv_depth_slope, DepthSlope::new());
|
|
orderbook_inv!(inv_microprice, Microprice::new());
|
|
orderbook_inv!(inv_ob_imbalance_full, OrderBookImbalanceFull::new());
|
|
orderbook_inv!(inv_ob_imbalance_top1, OrderBookImbalanceTop1::new());
|
|
orderbook_inv!(
|
|
inv_ob_imbalance_topn,
|
|
OrderBookImbalanceTopN::new(2).unwrap()
|
|
);
|
|
orderbook_inv!(
|
|
inv_order_flow_imbalance,
|
|
OrderFlowImbalance::new(20).unwrap()
|
|
);
|
|
orderbook_inv!(inv_quoted_spread, QuotedSpread::new());
|
|
|
|
// --- tradequote_inv (3) ---
|
|
tradequote_inv!(inv_effective_spread, EffectiveSpread::new());
|
|
tradequote_inv!(inv_kyles_lambda, KylesLambda::new(8).unwrap());
|
|
tradequote_inv!(inv_realized_spread, RealizedSpread::new(1).unwrap());
|
|
|
|
// --- bar_inv (10) ---
|
|
bar_inv!(inv_dollar_bars, DollarBars::new(1000.0).unwrap());
|
|
bar_inv!(inv_imbalance_bars, ImbalanceBars::new(3.0).unwrap());
|
|
bar_inv!(inv_kagi_bars, KagiBars::new(2.0).unwrap());
|
|
bar_inv!(
|
|
inv_point_and_figure_bars,
|
|
PointAndFigureBars::new(1.0, 3).unwrap()
|
|
);
|
|
bar_inv!(inv_range_bars, RangeBars::new(1.0).unwrap());
|
|
bar_inv!(inv_renko_bars, RenkoBars::new(1.0).unwrap());
|
|
bar_inv!(inv_run_bars, RunBars::new(3).unwrap());
|
|
bar_inv!(
|
|
inv_three_line_break_bars,
|
|
ThreeLineBreakBars::new(3).unwrap()
|
|
);
|
|
bar_inv!(inv_tick_bars, TickBars::new(3).unwrap());
|
|
bar_inv!(inv_volume_bars, VolumeBars::new(100.0).unwrap());
|