use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IndicatorConfig {
pub history_candles: usize,
pub ema_len: usize,
pub atr_len: usize,
pub st_factor: f64,
pub training_period: usize,
pub highvol_pct: f64,
pub midvol_pct: f64,
pub lowvol_pct: f64,
pub ts_max_length: usize,
pub ts_accel_mult: f64,
pub ts_rma_len: usize,
pub ts_hma_len: usize,
pub ts_collen: usize,
pub ts_lookback: usize,
pub ts_speed_exit_threshold: Option<f64>,
pub liq_period: usize,
pub liq_bins: usize,
pub conf_ema_fast: usize,
pub conf_ema_slow: usize,
pub conf_ema_trend: usize,
pub conf_rsi_len: usize,
pub conf_adx_len: usize,
pub conf_min_score: f64,
pub struct_swing_len: usize,
pub struct_atr_mult: f64,
pub fib_zone_enabled: bool,
pub signal_mode: String,
pub signal_confirm_bars: usize,
pub cvd_slope_bars: usize,
pub cvd_div_lookback: usize,
pub wave_pct_l: f64,
pub wave_pct_s: f64,
pub mom_pct_min: f64,
pub vol_pct_window: usize,
pub hurst_threshold: f64,
pub hurst_lookback: usize,
pub stop_atr_mult: f64,
pub min_vol_pct: f64,
pub min_hold_candles: usize,
}
impl Default for IndicatorConfig {
fn default() -> Self {
Self {
history_candles: 200,
ema_len: 9,
atr_len: 10,
st_factor: 3.0,
training_period: 100,
highvol_pct: 0.75,
midvol_pct: 0.50,
lowvol_pct: 0.25,
ts_max_length: 50,
ts_accel_mult: 5.0,
ts_rma_len: 10,
ts_hma_len: 5,
ts_collen: 100,
ts_lookback: 50,
ts_speed_exit_threshold: None,
liq_period: 100,
liq_bins: 31,
conf_ema_fast: 9,
conf_ema_slow: 21,
conf_ema_trend: 55,
conf_rsi_len: 13,
conf_adx_len: 14,
conf_min_score: 5.0,
struct_swing_len: 10,
struct_atr_mult: 0.5,
fib_zone_enabled: true,
signal_mode: "majority".into(),
signal_confirm_bars: 2,
cvd_slope_bars: 10,
cvd_div_lookback: 30,
wave_pct_l: 0.25,
wave_pct_s: 0.75,
mom_pct_min: 0.30,
vol_pct_window: 200,
hurst_threshold: 0.52,
hurst_lookback: 20,
stop_atr_mult: 1.5,
min_vol_pct: 0.20,
min_hold_candles: 2,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_signal_mode_is_majority() {
assert_eq!(IndicatorConfig::default().signal_mode, "majority");
}
#[test]
fn serde_round_trip() {
let cfg = IndicatorConfig::default();
let json = serde_json::to_string(&cfg).unwrap();
let back: IndicatorConfig = serde_json::from_str(&json).unwrap();
assert_eq!(back.ema_len, cfg.ema_len);
assert_eq!(back.signal_mode, cfg.signal_mode);
}
}