bidradar 0.1.0

Auction bid radar and market analyzer for real-time bidding analysis
use crate::numerics::linalg;

pub struct DetectionResult {
    pub risk_score: f64,
    pub clustering_detected: bool,
    pub price_anomaly: bool,
    pub confidence: f64,
}

pub fn detect(bids: &[f64], refs: &[f64]) -> DetectionResult {
    let n = bids.len();
    if n >= 3 {
        let matrix: Vec<Vec<f64>> = bids.iter().map(|&b| vec![b, 1.0]).collect();
        if let Ok(svd) = linalg::SVD::new().decompose(&matrix) {
            let cn = if *svd.s.last().unwrap() > 0.0 { svd.s[0] / svd.s.last().unwrap() } else { 1e6 };
            let mean_bid = bids.iter().sum::<f64>() / n as f64;
            let mean_ref = refs.iter().sum::<f64>() / refs.len() as f64;
            let dev = (mean_bid - mean_ref).abs() / mean_ref;
            let clustering = cn > 100.0;
            let anomaly = dev > 0.15;
            let score = (cn.min(1e4) / 1e4 * 0.6 + dev.min(1.0) * 0.4).min(1.0);
            let confidence = if clustering { 0.85 } else { 0.60 + score * 0.3 };
            return DetectionResult {
                risk_score: (score * 100.0).round() / 100.0,
                clustering_detected: clustering,
                price_anomaly: anomaly,
                confidence,
            };
        }
    }
    DetectionResult { risk_score: 0.0, clustering_detected: false, price_anomaly: false, confidence: 0.5 }
}