{"record":{"id":"d8d0373e86805353","repo":"nautechsystems/nautilus_trader","slug":"invalid-confidence-for-valueatrisk","errorCode":null,"errorMessage":"Invalid `confidence` for `ValueAtRisk`","messagePattern":"Invalid `confidence` for `ValueAtRisk`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/analysis/src/statistics/value_at_risk.rs","lineNumber":84,"sourceCode":"    ///\n    /// Returns an error if `confidence` is not finite and in the range `(0, 1)`.\n    pub fn new_checked(confidence: Option<f64>) -> anyhow::Result<Self> {\n        let confidence = confidence.unwrap_or(0.95);\n        check_predicate_true(\n            confidence.is_finite() && confidence > 0.0 && confidence < 1.0,\n            \"confidence must be finite and in the range (0, 1)\",\n        )?;\n        Ok(Self { confidence })\n    }\n\n    /// Creates a new [`ValueAtRisk`] instance.\n    ///\n    /// # Panics\n    ///\n    /// Panics if `confidence` is not finite and in the range `(0, 1)`.\n    #[must_use]\n    pub fn new(confidence: Option<f64>) -> Self {\n        Self::new_checked(confidence).expect(\"Invalid `confidence` for `ValueAtRisk`\")\n    }\n}\n\nimpl Display for ValueAtRisk {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        write!(f, \"Value at Risk (confidence {})\", self.confidence)\n    }\n}\n\n/// Returns the `q`-th percentile (`q` in `[0, 100]`) of `sorted_values` using\n/// linear interpolation between closest ranks, matching `numpy.percentile`.\n///\n/// `sorted_values` must be sorted ascending and non-empty.\npub(crate) fn percentile_linear(sorted_values: &[f64], q: f64) -> f64 {\n    debug_assert!(\n        !sorted_values.is_empty(),\n        \"percentile requires a non-empty slice\"\n    );","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/analysis/src/statistics/value_at_risk.rs#L66-L102","documentation":"ValueAtRisk::new is the infallible constructor for the ValueAtRisk statistic. It delegates to new_checked and unwraps the Result with expect(), so it panics whenever the supplied confidence level is not finite or lies outside the open interval (0, 1). The panic guards the mathematical validity of the VaR calculation, which requires a probability strictly between 0 and 1.","triggerScenarios":"Calling ValueAtRisk::new with Some(f64) where the value is NaN, INFINITY, 0.0, 1.0, negative, or >= 1.0 (e.g. ValueAtRisk::new(Some(0.95).ok) is fine but Some(1.0) or Some(f64::NAN) panic). Also triggered by passing a percentage like 95.0 instead of the fraction 0.95.","commonSituations":"Config mistakes where a confidence level is read from YAML/JSON as '95' (percent) rather than 0.95; unit-config values parsed as f64 producing out-of-range or NaN values from empty/invalid strings; arithmetic producing inf (e.g. division by zero) before constructing the estimator.","solutions":["Pass a finite value strictly between 0 and 1, e.g. 0.95 or 0.99 for the confidence level","If the config stores percentages, divide by 100 before constructing ValueAtRisk","Use ValueAtRisk::new_checked(confidence) instead and handle the Err to avoid the panic","Validate the parsed config field (finite and 0 < c < 1) at startup before reaching the constructor"],"exampleFix":"// before\nlet var = ValueAtRisk::new(Some(confidence_percent)); // 95.0 -> panic\n// after\nlet var = ValueAtRisk::new(Some(confidence_percent / 100.0)); // 0.95\n// or non-panicking:\nlet var = ValueAtRisk::new_checked(Some(confidence))\n    .expect(\"confidence must be in (0, 1)\");","handlingStrategy":"validation","validationCode":"fn is_valid_confidence(c: f64) -> bool {\n    c.is_finite() && c > 0.0 && c < 1.0\n}\nassert!(is_valid_confidence(confidence), \"confidence must be in (0, 1)\");\nlet var = ValueAtRisk::new(Some(confidence));","typeGuard":"fn is_valid_confidence(c: Option<f64>) -> bool {\n    matches!(c, Some(v) if v.is_finite() && v > 0.0 && v < 1.0) || c.is_none()\n}","tryCatchPattern":"let var = match ValueAtRisk::new_checked(Some(confidence)) {\n    Ok(v) => v,\n    Err(e) => { log::error!(\"invalid confidence: {e}\"); return Err(e); }\n};","preventionTips":["Validate confidence config fields at startup (finite, 0 < c < 1)","Store confidence as a fraction (0.95), never a percentage","Prefer new_checked over new in fallible code paths","Clamp/parse numeric config with explicit range checks before constructing statistics"],"tags":["rust","panic","statistics","value-at-risk","argument-validation"],"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"}