← back to krejcif__rdex

Function bodies 248 total

All specs Real LLM only Function bodies
max_position_size function · rust · L264-L275 (12 LOC)
src/engine/adaptive.rs
    pub fn max_position_size(&self) -> f64 {
        if self.stats.total_trades < 15 {
            return 0.18;
        }

        let rr = self.stats.ema_rr_ratio;
        // rr_scale = rr / (1 + rr) — maps RR to (0, 1) range
        // rr=1.0 → 0.50, rr=1.5 → 0.60, rr=2.0 → 0.67
        let rr_scale = rr / (1.0 + rr);
        let base = self.kelly_fraction() * rr_scale;
        base.clamp(0.05, 0.30)
    }
confidence_score function · rust · L278-L296 (19 LOC)
src/engine/adaptive.rs
    fn confidence_score(&self) -> f64 {
        if self.recent_outcomes.is_empty() {
            return 0.0;
        }

        let wr = self.recent_win_rate();
        let avg_pnl = self.stats.ema_pnl;
        let pnl_std = self.pnl_std();

        // Sharpe-like: mean / std gives consistency-adjusted confidence
        let sharpe_like = (avg_pnl / pnl_std.max(0.01)).clamp(-2.0, 2.0);
        let sharpe_score = (sharpe_like / 4.0 + 0.5).clamp(0.0, 1.0); // -2→0, +2→1

        // Win rate score — centered on 50%
        let wr_score = ((wr - 0.4) / 0.3).clamp(0.0, 1.0); // 0.4→0, 0.7→1

        // Blend: Sharpe-like matters more (quality), WR for consistency
        (sharpe_score * 0.6 + wr_score * 0.4).clamp(0.0, 1.0)
    }
recent_win_rate function · rust · L299-L305 (7 LOC)
src/engine/adaptive.rs
    fn recent_win_rate(&self) -> f64 {
        if self.recent_outcomes.is_empty() {
            return 0.5;
        }
        let wins = self.recent_outcomes.iter().filter(|o| o.pnl_pct > 0.0).count();
        wins as f64 / self.recent_outcomes.len() as f64
    }
test_adaptive_params_initial function · rust · L313-L322 (10 LOC)
src/engine/adaptive.rs
    fn test_adaptive_params_initial() {
        let params = AdaptiveParams::new();
        assert_eq!(params.cooldown(), 15);
        assert_eq!(params.min_hold(), 8);
        assert_eq!(params.max_hold(), 96);
        assert!(params.trail_activation_atr() > 0.0);
        assert!(params.trail_distance_atr() > 0.0);
        assert!(params.exploration_coeff() > 0.0);
        assert!(params.reward_k() > 0.0);
    }
test_adaptive_cooldown_adjusts function · rust · L325-L347 (23 LOC)
src/engine/adaptive.rs
    fn test_adaptive_cooldown_adjusts() {
        let mut params = AdaptiveParams::new();
        // Record winning trades
        for i in 0..20 {
            params.tick_candle();
            params.tick_candle();
            params.record_trade(2.0, 10, 3.0, 1.5);
        }
        let winning_cooldown = params.cooldown();

        let mut params2 = AdaptiveParams::new();
        // Record losing trades
        for i in 0..20 {
            params2.tick_candle();
            params2.tick_candle();
            params2.record_trade(-2.0, 5, 0.5, 3.0);
        }
        let losing_cooldown = params2.cooldown();

        assert!(losing_cooldown > winning_cooldown,
            "Losing streak should produce longer cooldown: {} vs {}",
            losing_cooldown, winning_cooldown);
    }
test_adaptive_trailing_adjusts function · rust · L350-L366 (17 LOC)
src/engine/adaptive.rs
    fn test_adaptive_trailing_adjusts() {
        let mut params = AdaptiveParams::new();
        for _ in 0..30 {
            params.record_trade(3.0, 15, 6.0, 2.0);
        }
        let big_trail = params.trail_activation_atr();

        let mut params2 = AdaptiveParams::new();
        for _ in 0..30 {
            params2.record_trade(1.0, 8, 2.0, 1.5);
        }
        let small_trail = params2.trail_activation_atr();

        assert!(big_trail > small_trail,
            "Big excursions should produce higher trail activation: {} vs {}",
            big_trail, small_trail);
    }
test_confidence_increases_with_wins function · rust · L369-L376 (8 LOC)
src/engine/adaptive.rs
    fn test_confidence_increases_with_wins() {
        let mut params = AdaptiveParams::new();
        for _ in 0..30 {
            params.record_trade(3.0, 10, 4.0, 1.5);
        }
        assert!(params.kelly_fraction() > 0.1);
        assert!(params.max_position_size() > 0.05);
    }
About: code-quality intelligence by Repobility · https://repobility.com
test_exploration_decays function · rust · L379-L387 (9 LOC)
src/engine/adaptive.rs
    fn test_exploration_decays() {
        let mut params = AdaptiveParams::new();
        let initial = params.exploration_coeff();
        for _ in 0..200 {
            params.record_trade(0.5, 5, 2.0, 1.5);
        }
        let later = params.exploration_coeff();
        assert!(later < initial, "Exploration should decay: {} vs {}", later, initial);
    }
test_ema_decay_adapts function · rust · L390-L398 (9 LOC)
src/engine/adaptive.rs
    fn test_ema_decay_adapts() {
        let mut params = AdaptiveParams::new();
        let initial_decay = params.stats.ema_decay;
        for i in 0..100 {
            params.record_trade(if i % 2 == 0 { 1.0 } else { -0.5 }, 8, 3.0, 2.0);
        }
        assert!(params.stats.ema_decay > initial_decay,
            "EMA decay should increase with more trades");
    }
test_reward_k_adapts_to_volatility function · rust · L401-L415 (15 LOC)
src/engine/adaptive.rs
    fn test_reward_k_adapts_to_volatility() {
        let mut low_vol = AdaptiveParams::new();
        for _ in 0..30 {
            low_vol.record_trade(0.3, 5, 1.0, 0.5); // small moves
        }

        let mut high_vol = AdaptiveParams::new();
        for _ in 0..30 {
            high_vol.record_trade(5.0, 5, 4.0, 3.0); // large moves
        }

        assert!(low_vol.reward_k() > high_vol.reward_k(),
            "Low volatility should produce higher k: {} vs {}",
            low_vol.reward_k(), high_vol.reward_k());
    }
default function · rust · L46-L54 (9 LOC)
src/engine/learner.rs
    fn default() -> Self {
        Self {
            decay_factor: 0.995,
            plateau_window: 5,
            plateau_threshold: 0.005,
            transfer_after_n: 150,
            min_edge: 0.02,
        }
    }
new function · rust · L73-L75 (3 LOC)
src/engine/learner.rs
    fn new(initial: f64, decay: f64) -> Self {
        Self { mean: initial, count: 0, decay }
    }
update function · rust · L76-L84 (9 LOC)
src/engine/learner.rs
    fn update(&mut self, val: f64) {
        self.count += 1;
        if self.count == 1 {
            self.mean = val;
        } else {
            self.mean = self.mean * self.decay + val * (1.0 - self.decay);
        }
    }
value function · rust · L85-L88 (4 LOC)
src/engine/learner.rs
    fn value(&self) -> f64 {
        self.mean
    }
new function · rust · L92-L97 (6 LOC)
src/engine/learner.rs
    pub fn new() -> Self {
        Self {
            favorable: HashMap::new(),
            adverse: HashMap::new(),
        }
    }
Powered by Repobility — scan your code at https://repobility.com
record function · rust · L98-L126 (29 LOC)
src/engine/learner.rs
    pub fn record(&mut self, pattern_key: &str, side: &str, favorable_atr: f64, adverse_atr: f64, won: bool) {
        // Record per side+pattern for side-specific learning
        let key = format!("{}_{}", pattern_key, side);
        self.adverse
            .entry(key.clone())
            .or_insert_with(|| DecayingStat::new(2.5, 0.95))
            .update(adverse_atr.max(0.5));

        if won {
            self.favorable
                .entry(key)
                .or_insert_with(|| DecayingStat::new(4.0, 0.95))
                .update(favorable_atr.max(1.0));
        }

        // Also record pattern-only (fallback for cold-start)
        self.adverse
            .entry(pattern_key.to_string())
            .or_insert_with(|| DecayingStat::new(2.5, 0.95))
            .update(adverse_atr.max(0.5));

        if won {
            self.favorable
                .entry(pattern_key.to_string())
                .or_insert_with(|| DecayingStat::new(4.0, 0.95))
                .update(fav
get_sl_atr function · rust · L129-L135 (7 LOC)
src/engine/learner.rs
    pub fn get_sl_atr(&self, pattern_key: &str, side: &str) -> f64 {
        let side_key = format!("{}_{}", pattern_key, side);
        self.adverse.get(&side_key)
            .or_else(|| self.adverse.get(pattern_key))
            .map(|s| s.value().clamp(1.0, 5.0))
            .unwrap_or(2.5)
    }
get_tp_atr function · rust · L138-L144 (7 LOC)
src/engine/learner.rs
    pub fn get_tp_atr(&self, pattern_key: &str, side: &str) -> f64 {
        let side_key = format!("{}_{}", pattern_key, side);
        self.favorable.get(&side_key)
            .or_else(|| self.favorable.get(pattern_key))
            .map(|s| s.value().clamp(1.5, 8.0))
            .unwrap_or(4.0)
    }
new function · rust · L148-L173 (26 LOC)
src/engine/learner.rs
    pub fn new(symbols: Vec<String>, config: LearnerConfig) -> Self {
        let action_names: Vec<String> = ACTIONS.iter().map(|s| s.to_string()).collect();
        let thompson = ThompsonEngine::new(action_names, config.decay_factor);

        let mut regret = HashMap::new();
        let mut plateau = HashMap::new();
        for sym in &symbols {
            regret.insert(sym.clone(), RegretTracker::default());
            plateau.insert(
                sym.clone(),
                PlateauDetector::new(config.plateau_window, config.plateau_threshold),
            );
        }

        Self {
            thompson,
            discretizer: PatternDiscretizer::new(),
            excursions: ExcursionTracker::new(),
            regret,
            plateau,
            symbols,
            config,
            adaptive: AdaptiveParams::new(),
            last_pattern: None,
        }
    }
decide function · rust · L177-L240 (64 LOC)
src/engine/learner.rs
    pub fn decide(&mut self, state: &MarketState, rng: &mut impl Rng) -> TradingDecision {
        let features = match MarketFeatures::extract(state) {
            Some(f) => f,
            None => return self.hold_decision(),
        };

        // Feed features to adaptive discretizer (learns boundaries)
        self.discretizer.observe(&features);
        let pattern = self.discretizer.discretize(&features);
        let pattern_key = PatternDiscretizer::pattern_key(&pattern);

        // Global pooling: all symbols share Thompson state for pattern learning.
        // Crypto markets share similar microstructure across pairs.
        let pool_key = "_global";

        // Thompson Sampling selects action with adaptive exploration
        let exploration = self.adaptive.exploration_coeff();
        let action = self.thompson.select_arm_with_exploration(pool_key, &pattern, rng, exploration);

        // Store pattern for outcome recording
        self.last_pattern = Some(pattern.clone(
hold_decision function · rust · L241-L251 (11 LOC)
src/engine/learner.rs
    fn hold_decision(&self) -> TradingDecision {
        TradingDecision {
            signal: TradeSignal::Hold,
            size: 0.0,
            stop_loss: None,
            take_profit: None,
            confidence: 0.0,
            strategy_name: "hold".into(),
        }
    }
record_outcome function · rust · L254-L270 (17 LOC)
src/engine/learner.rs
    pub fn record_outcome(
        &mut self,
        symbol: &str,
        context: &MarketContext,
        strategy_id: &StrategyId,
        reward: f64,
    ) {
        // Record in global pool for shared learning
        self.thompson.record_outcome("_global", context, strategy_id, reward);

        if let Some(regret) = self.regret.get_mut(symbol) {
            regret.record(reward);
        }
        if let Some(plateau) = self.plateau.get_mut(symbol) {
            plateau.record(reward);
        }
    }
record_excursion function · rust · L273-L282 (10 LOC)
src/engine/learner.rs
    pub fn record_excursion(
        &mut self,
        pattern_key: &str,
        side: &str,
        favorable_atr: f64,
        adverse_atr: f64,
        won: bool,
    ) {
        self.excursions.record(pattern_key, side, favorable_atr, adverse_atr, won);
    }
Repobility · MCP-ready · https://repobility.com
record_hold function · rust · L285-L292 (8 LOC)
src/engine/learner.rs
    pub fn record_hold(&mut self, _symbol: &str, pattern: &MarketContext, _recent_return_pct: f64) {
        self.thompson.record_outcome(
            "_global",
            pattern,
            &StrategyId("hold".into()),
            0.5,
        );
    }
maybe_transfer function · rust · L295-L329 (35 LOC)
src/engine/learner.rs
    pub fn maybe_transfer(&mut self) -> Vec<(String, String)> {
        let mut transfers = Vec::new();

        let mut symbol_evidence: Vec<(String, f64)> = self.symbols.iter()
            .map(|s| {
                let evidence = self.regret.get(s)
                    .map(|r| r.total_observations as f64)
                    .unwrap_or(0.0);
                (s.clone(), evidence)
            })
            .collect();
        symbol_evidence.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());

        if symbol_evidence.len() < 2 { return transfers; }

        let source = &symbol_evidence[0].0;
        if symbol_evidence[0].1 < self.config.transfer_after_n as f64 {
            return transfers;
        }

        for (target, evidence) in &symbol_evidence[1..] {
            if *evidence < self.config.transfer_after_n as f64 / 2.0 {
                let should_transfer = self.plateau.get_mut(target)
                    .map(|pd| pd.check() != PlateauAction::Continue)
                    .
health_report function · rust · L330-L353 (24 LOC)
src/engine/learner.rs
    pub fn health_report(&self) -> HashMap<String, SymbolHealth> {
        let mut report: HashMap<String, SymbolHealth> = self.symbols.iter()
            .map(|s| {
                let regret = self.regret.get(s);
                let health = SymbolHealth {
                    observations: regret.map(|r| r.total_observations).unwrap_or(0),
                    average_regret: regret.map(|r| r.average_regret()).unwrap_or(0.0),
                    regret_growth_rate: regret.map(|r| r.growth_rate()).unwrap_or(1.0),
                    is_learning: regret.map(|r| r.growth_rate() < 0.8).unwrap_or(false),
                };
                (s.clone(), health)
            })
            .collect();

        report.insert("_patterns".to_string(), SymbolHealth {
            observations: self.discretizer.sample_count() as u64,
            average_regret: 0.0,
            regret_growth_rate: 0.0,
            is_learning: self.discretizer.is_warmed_up(),
        });

        report
    }
test_learning_engine_creation function · rust · L369-L376 (8 LOC)
src/engine/learner.rs
    fn test_learning_engine_creation() {
        let engine = LearningEngine::new(
            vec!["BTCUSDT".into(), "ETHUSDT".into()],
            LearnerConfig::default(),
        );
        assert_eq!(engine.symbols.len(), 2);
        assert_eq!(engine.thompson.strategy_ids.len(), 3); // long, short, hold
    }
test_learning_engine_decide_hold_initially function · rust · L379-L398 (20 LOC)
src/engine/learner.rs
    fn test_learning_engine_decide_hold_initially() {
        let mut engine = LearningEngine::new(
            vec!["BTCUSDT".into()],
            LearnerConfig::default(),
        );
        let state = MarketState {
            symbol: Symbol("BTCUSDT".into()),
            timestamp: 0,
            current_candle: Candle {
                open_time: 0, open: 100.0, high: 101.0, low: 99.0,
                close: 100.5, volume: 1000.0, close_time: 900_000,
                quote_volume: 100_000.0, trades: 500,
            },
            history: vec![],
            indicators: IndicatorSet::default(),
        };
        let mut rng = rand::thread_rng();
        let decision = engine.decide(&state, &mut rng);
        assert_eq!(decision.signal, TradeSignal::Hold);
    }
test_health_report function · rust · L401-L415 (15 LOC)
src/engine/learner.rs
    fn test_health_report() {
        let mut engine = LearningEngine::new(
            vec!["BTCUSDT".into()],
            LearnerConfig::default(),
        );
        let ctx = MarketContext {
            volatility_tier: "1111".into(),
            trend_regime: "111".into(),
        };
        for _ in 0..20 {
            engine.record_outcome("BTCUSDT", &ctx, &StrategyId("long".into()), 0.7);
        }
        let report = engine.health_report();
        assert_eq!(report.get("BTCUSDT").unwrap().observations, 20);
    }
test_excursion_tracker function · rust · L418-L425 (8 LOC)
src/engine/learner.rs
    fn test_excursion_tracker() {
        let mut tracker = ExcursionTracker::new();
        for _ in 0..20 {
            tracker.record("p", "long", 6.0, 1.5, true);
        }
        assert!(tracker.get_tp_atr("p", "long") > 4.0);
        assert!(tracker.get_sl_atr("p", "long") < 3.0);
    }
test_excursion_defaults function · rust · L428-L432 (5 LOC)
src/engine/learner.rs
    fn test_excursion_defaults() {
        let tracker = ExcursionTracker::new();
        assert_eq!(tracker.get_sl_atr("unknown", "long"), 2.5);
        assert_eq!(tracker.get_tp_atr("unknown", "long"), 4.0);
    }
Generated by Repobility's multi-pass static-analysis pipeline (https://repobility.com)
uniform function · rust · L14-L16 (3 LOC)
src/engine/thompson.rs
    pub fn uniform() -> Self {
        Self { alpha: 1.0, beta: 1.0 }
    }
mean function · rust · L17-L20 (4 LOC)
src/engine/thompson.rs
    pub fn mean(&self) -> f64 {
        self.alpha / (self.alpha + self.beta)
    }
variance function · rust · L21-L25 (5 LOC)
src/engine/thompson.rs
    pub fn variance(&self) -> f64 {
        let total = self.alpha + self.beta;
        (self.alpha * self.beta) / (total * total * (total + 1.0))
    }
sample function · rust · L26-L42 (17 LOC)
src/engine/thompson.rs
    pub fn sample(&self, rng: &mut impl Rng) -> f64 {
        // Kumaraswamy/normal approximation for Beta sampling
        let u: f64 = rng.gen_range(0.001..0.999);
        if self.alpha > 1.0 && self.beta > 1.0 {
            let mean = self.mean();
            let std = self.variance().sqrt();
            let t = if u < 0.5 {
                -(-2.0 * u.ln()).sqrt()
            } else {
                (-2.0 * (1.0 - u).ln()).sqrt()
            };
            (mean + std * t).clamp(0.001, 0.999)
        } else {
            u.powf(1.0 / self.alpha).min(1.0 - (1.0 - u).powf(1.0 / self.beta))
        }
    }
update function · rust · L43-L47 (5 LOC)
src/engine/thompson.rs
    pub fn update(&mut self, reward: f64) {
        self.alpha += reward;
        self.beta += 1.0 - reward;
    }
evidence function · rust · L48-L51 (4 LOC)
src/engine/thompson.rs
    pub fn evidence(&self) -> f64 {
        self.alpha + self.beta - 2.0
    }
new function · rust · L63-L69 (7 LOC)
src/engine/thompson.rs
    pub fn new(decay_factor: f64) -> Self {
        Self {
            params: BetaParams::uniform(),
            decay_factor: decay_factor.clamp(0.9, 1.0),
            effective_n: 0.0,
        }
    }
update function · rust · L70-L78 (9 LOC)
src/engine/thompson.rs
    pub fn update(&mut self, reward: f64) {
        // Decay old evidence
        self.params.alpha = 1.0 + (self.params.alpha - 1.0) * self.decay_factor;
        self.params.beta = 1.0 + (self.params.beta - 1.0) * self.decay_factor;
        // Add new observation
        self.params.update(reward);
        self.effective_n = self.effective_n * self.decay_factor + 1.0;
    }
About: code-quality intelligence by Repobility · https://repobility.com
effective_window function · rust · L79-L83 (5 LOC)
src/engine/thompson.rs
    pub fn effective_window(&self) -> f64 {
        if self.decay_factor >= 1.0 { self.effective_n }
        else { 1.0 / (1.0 - self.decay_factor) }
    }
new function · rust · L102-L115 (14 LOC)
src/engine/thompson.rs
    pub fn new(strategy_names: Vec<String>, decay_factor: f64) -> Self {
        let strategy_ids: Vec<StrategyId> = strategy_names.into_iter()
            .map(StrategyId)
            .collect();

        Self {
            arms: HashMap::new(),
            strategy_ids,
            decay_factor,
            exploration_coeff: 0.3,
            total_decisions: 0,
            visit_counts: HashMap::new(),
        }
    }
select_arm function · rust · L119-L126 (8 LOC)
src/engine/thompson.rs
    pub fn select_arm(
        &self,
        symbol: &str,
        context: &MarketContext,
        rng: &mut impl Rng,
    ) -> StrategyId {
        self.select_arm_with_exploration(symbol, context, rng, self.exploration_coeff)
    }
select_arm_with_exploration function · rust · L129-L151 (23 LOC)
src/engine/thompson.rs
    pub fn select_arm_with_exploration(
        &self,
        symbol: &str,
        context: &MarketContext,
        rng: &mut impl Rng,
        exploration: f64,
    ) -> StrategyId {
        let mut best_score = f64::NEG_INFINITY;
        let mut best_arm = self.strategy_ids[0].clone();

        for arm in &self.strategy_ids {
            let sample = self.get_beta(symbol, context, arm).params.sample(rng);
            let bonus = self.curiosity_bonus_with(symbol, context, arm, exploration);
            let score = sample + bonus;

            if score > best_score {
                best_score = score;
                best_arm = arm.clone();
            }
        }

        best_arm
    }
record_outcome function · rust · L154-L177 (24 LOC)
src/engine/thompson.rs
    pub fn record_outcome(
        &mut self,
        symbol: &str,
        context: &MarketContext,
        arm: &StrategyId,
        reward: f64,
    ) {
        let reward = reward.clamp(0.0, 1.0);

        // Update decaying beta
        let beta = self.arms
            .entry(symbol.to_string())
            .or_default()
            .entry(context.clone())
            .or_default()
            .entry(arm.clone())
            .or_insert_with(|| DecayingBeta::new(self.decay_factor));
        beta.update(reward);

        // Update visit counts
        let key = (symbol.to_string(), context.clone(), arm.clone());
        *self.visit_counts.entry(key).or_insert(0) += 1;
        self.total_decisions += 1;
    }
get_beta function · rust · L178-L197 (20 LOC)
src/engine/thompson.rs
    fn get_beta(&self, symbol: &str, context: &MarketContext, arm: &StrategyId) -> DecayingBeta {
        self.arms
            .get(symbol)
            .and_then(|ctx| ctx.get(context))
            .and_then(|arms| arms.get(arm))
            .cloned()
            .unwrap_or_else(|| {
                // Hold-biased prior that decays with experience.
                // Early: strong hold bias (alpha=5, mean=0.83).
                // As total_decisions grow, hold bias weakens naturally.
                let mut db = DecayingBeta::new(self.decay_factor);
                if arm.0 == "hold" {
                    let hold_alpha = 1.0 + 4.0 / (1.0 + self.total_decisions as f64 / 100.0);
                    db.params.alpha = hold_alpha;
                    db.params.beta = 1.0;
                }
                db
            })
    }
curiosity_bonus function · rust · L198-L201 (4 LOC)
src/engine/thompson.rs
    fn curiosity_bonus(&self, symbol: &str, context: &MarketContext, arm: &StrategyId) -> f64 {
        self.curiosity_bonus_with(symbol, context, arm, self.exploration_coeff)
    }
curiosity_bonus_with function · rust · L202-L212 (11 LOC)
src/engine/thompson.rs
    fn curiosity_bonus_with(&self, symbol: &str, context: &MarketContext, arm: &StrategyId, exploration: f64) -> f64 {
        if self.total_decisions < 2 { return exploration; }

        let key = (symbol.to_string(), context.clone(), arm.clone());
        let visits = self.visit_counts.get(&key).copied().unwrap_or(0);

        if visits == 0 { return exploration * 2.0; }

        exploration * ((self.total_decisions as f64).ln() / visits as f64).sqrt()
    }
Powered by Repobility — scan your code at https://repobility.com
get_arm_mean function · rust · L215-L218 (4 LOC)
src/engine/thompson.rs
    pub fn get_arm_mean(&self, symbol: &str, context: &MarketContext, arm_name: &str) -> f64 {
        let arm = StrategyId(arm_name.to_string());
        self.get_beta(symbol, context, &arm).params.mean()
    }
is_uncertain function · rust · L221-L228 (8 LOC)
src/engine/thompson.rs
    pub fn is_uncertain(&self, symbol: &str, context: &MarketContext, threshold: f64) -> bool {
        let mut means: Vec<f64> = self.strategy_ids.iter()
            .map(|arm| self.get_beta(symbol, context, arm).params.mean())
            .collect();
        means.sort_by(|a, b| b.partial_cmp(a).unwrap());
        if means.len() < 2 { return true; }
        (means[0] - means[1]) < threshold
    }
extract_priors function · rust · L231-L247 (17 LOC)
src/engine/thompson.rs
    pub fn extract_priors(&self, symbol: &str) -> HashMap<MarketContext, HashMap<StrategyId, BetaParams>> {
        self.arms
            .get(symbol)
            .map(|contexts| {
                contexts.iter()
                    .filter_map(|(ctx, arms)| {
                        let significant: HashMap<StrategyId, BetaParams> = arms.iter()
                            .filter(|(_, db)| db.params.evidence() > 10.0)
                            .map(|(arm, db)| (arm.clone(), db.params.clone()))
                            .collect();
                        if significant.is_empty() { None }
                        else { Some((ctx.clone(), significant)) }
                    })
                    .collect()
            })
            .unwrap_or_default()
    }
‹ prevpage 3 / 5next ›