{"record":{"id":"636274bee86ca663","repo":"nautechsystems/nautilus_trader","slug":"invalid-threshold-for-omegaratio","errorCode":null,"errorMessage":"Invalid `threshold` for `OmegaRatio`","messagePattern":"Invalid `threshold` for `OmegaRatio`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/analysis/src/statistics/omega_ratio.rs","lineNumber":76,"sourceCode":"    /// Creates a new checked [`OmegaRatio`] instance.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if `threshold` is not finite.\n    pub fn new_checked(threshold: Option<f64>) -> anyhow::Result<Self> {\n        let threshold = threshold.unwrap_or(0.0);\n        check_predicate_true(threshold.is_finite(), \"threshold must be finite\")?;\n        Ok(Self { threshold })\n    }\n\n    /// Creates a new [`OmegaRatio`] instance.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `threshold` is not finite.\n    #[must_use]\n    pub fn new(threshold: Option<f64>) -> Self {\n        Self::new_checked(threshold).expect(\"Invalid `threshold` for `OmegaRatio`\")\n    }\n}\n\nimpl Display for OmegaRatio {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Omega Ratio (threshold {})\", self.threshold)\n    }\n}\n\nimpl PortfolioStatistic for OmegaRatio {\n    type Item = f64;\n\n    fn name(&self) -> String {\n        self.to_string()\n    }\n\n    fn calculate_from_returns(&self, raw_returns: &Returns) -> Option<Self::Item> {\n        if !self.check_valid_returns(raw_returns) {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/analysis/src/statistics/omega_ratio.rs#L58-L94","documentation":"OmegaRatio::new is the infallible constructor wrapping new_checked, which requires threshold to be a finite f64. The expect panics when the value is NaN or +/- infinity, because the panicking constructor assumes callers pass valid constants.","triggerScenarios":"Calling OmegaRatio::new with Some(f64::NAN), Some(f64::INFINITY), or a NaN computed from upstream data (e.g. a ratio of infinities) instead of a finite threshold.","commonSituations":"Threshold derived from market data that produced NaN/inf (0/0 divisions); config parsed to float infinity; passing an unvalidated externally supplied parameter.","solutions":["Pass a finite threshold (e.g. Some(0.0)); replace NaN/inf values before construction.","Sanitize upstream computations: check is_finite() on the derived threshold.","Use OmegaRatio::new_checked(...) and handle the Err instead of the panicking new()."],"exampleFix":"// before\nlet threshold = gains / losses; // 0/0 -> NaN\nlet ratio = OmegaRatio::new(Some(threshold)); // panics\n\n// after\nlet threshold = if gains.is_finite() && losses.is_finite() { gains / losses } else { 0.0 };\nlet ratio = OmegaRatio::new(Some(threshold));","handlingStrategy":"validation","validationCode":"fn valid_threshold(t: f64) -> bool { t.is_finite() }","typeGuard":"fn finite_f64(x: f64) -> Option<f64> {\n    if x.is_finite() { Some(x) } else { None }\n}","tryCatchPattern":"match OmegaRatio::new_checked(Some(threshold)) {\n    Ok(r) => r,\n    Err(e) => { log::error!(\"bad threshold {threshold}: {e}\"); OmegaRatio::new(None) }\n}","preventionTips":["Sanitize derived numeric parameters (NaN/inf from 0/0 or overflow) before use.","Check is_finite() on any threshold sourced from market data or config.","Prefer the *_new_checked constructors for externally supplied values."],"tags":["rust","panic","statistics","omega-ratio","validation","nan"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}