{"record":{"id":"f7b52940f0a1bb00","repo":"nautechsystems/nautilus_trader","slug":"fixed-precision-tick-scheme-is-valid","errorCode":null,"errorMessage":"fixed precision tick scheme is valid","messagePattern":"fixed precision tick scheme is valid","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"crates/model/src/instruments/tick_scheme.rs","lineNumber":209,"sourceCode":"            (30_000_000.0, f64::INFINITY, 10_000.0),\n        ],\n        4,\n        10_000,\n    )\n    .expect(\"TOPIX100 tick scheme tiers are valid by construction\")\n});\n\nstatic FIXED_TICK_SCHEME: LazyLock<FixedTickScheme> =\n    LazyLock::new(|| FixedTickScheme::new(1.0).expect(\"fixed tick scheme is valid\"));\n\nstatic CRYPTO_0_01_TICK_SCHEME: LazyLock<FixedTickScheme> =\n    LazyLock::new(|| FixedTickScheme::new(0.01).expect(\"crypto tick scheme is valid\"));\n\nstatic FIXED_PRECISION_TICK_SCHEMES: LazyLock<Vec<FixedTickScheme>> = LazyLock::new(|| {\n    (0..=FIXED_PRECISION)\n        .map(|precision| {\n            let tick = 10_f64.powi(-i32::from(precision));\n            FixedTickScheme::new(tick).expect(\"fixed precision tick scheme is valid\")\n        })\n        .collect()\n});\n\n#[derive(Debug, Clone, Copy, PartialEq)]\npub struct FixedTickScheme {\n    tick: f64,\n}\n\nimpl Eq for FixedTickScheme {}\n\nimpl FixedTickScheme {\n    /// Creates a new [`FixedTickScheme`] with the given tick size.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if `tick` is not finite or not positive.\n    pub fn new(tick: f64) -> Result<Self, TickSchemeError> {","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/instruments/tick_scheme.rs#L191-L227","documentation":"Panic site inside the FIXED_PRECISION_TICK_SCHEMES static, which builds one FixedTickScheme per precision 0..=FIXED_PRECISION using tick = 10^-precision. Each value is positive and finite, so `FixedTickScheme::new` must succeed and this expect documents that invariant. A panic here would indicate the precision constant or constructor validation has been corrupted by a code change.","triggerScenarios":"Untriggerable normally; would fire on first access to FIXED_PRECISION_TICK_SCHEMES if FIXED_PRECISION were set so large that 10^-precision underflows to 0.0, or if the constructor's validation changed to reject tiny ticks.","commonSituations":"Encountered only by library developers after raising FIXED_PRECISION (making ticks denormal/zero) or tightening FixedTickScheme::new's checks; end users see it as a panic during static init on first use.","solutions":["Check FIXED_PRECISION — if it exceeds f64's usable exponent range, 10^-p becomes 0.0 and fails validation; cap it below ~308 and within meaningful price precision.","Review FixedTickScheme::new for epsilon-based rejection of small ticks.","Run the tick scheme tests after any change to these constants.","No caller-side mitigation; the statics must remain valid by construction."],"exampleFix":"// before\nconst FIXED_PRECISION: u8 = 250; // 10^-250 underflows toward 0\n// after\nconst FIXED_PRECISION: u8 = 16; // safe, meaningful price precision","handlingStrategy":"validation","validationCode":"// Library-internal static; if you maintain this code, ensure:\nassert!(FIXED_PRECISION <= 16, \"precision must keep 10^-p representable\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Cap FIXED_PRECISION well below f64 underflow range.","Test the generated statics for all precisions after changing constants.","Don't tighten FixedTickScheme::new validation without auditing all static call sites."],"tags":["rust","panic","static-init","invariant"],"backgroundTag":"internal-invariant-violation","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"}