nautechsystems/nautilus_trader · info

fixed precision tick scheme is valid

Error message

fixed precision tick scheme is valid

What it means

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.

Source

Thrown at crates/model/src/instruments/tick_scheme.rs:209

            (30_000_000.0, f64::INFINITY, 10_000.0),
        ],
        4,
        10_000,
    )
    .expect("TOPIX100 tick scheme tiers are valid by construction")
});

static FIXED_TICK_SCHEME: LazyLock<FixedTickScheme> =
    LazyLock::new(|| FixedTickScheme::new(1.0).expect("fixed tick scheme is valid"));

static CRYPTO_0_01_TICK_SCHEME: LazyLock<FixedTickScheme> =
    LazyLock::new(|| FixedTickScheme::new(0.01).expect("crypto tick scheme is valid"));

static FIXED_PRECISION_TICK_SCHEMES: LazyLock<Vec<FixedTickScheme>> = LazyLock::new(|| {
    (0..=FIXED_PRECISION)
        .map(|precision| {
            let tick = 10_f64.powi(-i32::from(precision));
            FixedTickScheme::new(tick).expect("fixed precision tick scheme is valid")
        })
        .collect()
});

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedTickScheme {
    tick: f64,
}

impl Eq for FixedTickScheme {}

impl FixedTickScheme {
    /// Creates a new [`FixedTickScheme`] with the given tick size.
    ///
    /// # Errors
    ///
    /// Returns an error if `tick` is not finite or not positive.
    pub fn new(tick: f64) -> Result<Self, TickSchemeError> {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. 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.
  2. Review FixedTickScheme::new for epsilon-based rejection of small ticks.
  3. Run the tick scheme tests after any change to these constants.
  4. No caller-side mitigation; the statics must remain valid by construction.

Example fix

// before
const FIXED_PRECISION: u8 = 250; // 10^-250 underflows toward 0
// after
const FIXED_PRECISION: u8 = 16; // safe, meaningful price precision
Defensive patterns

Strategy: validation

Validate before calling

// Library-internal static; if you maintain this code, ensure:
assert!(FIXED_PRECISION <= 16, "precision must keep 10^-p representable");

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/f7b52940f0a1bb00. Report an issue: GitHub.