nautechsystems/nautilus_trader · error

callbackRate % out of Binance range [ , ]

Error message

callbackRate {rate}% out of Binance range [{min_rate}, {max_rate}]

What it means

trailing_offset_to_callback_rate converts a Nautilus trailing-stop offset (percent) into Binance's callbackRate (percent as a 0-10 decimal fraction). Binance only accepts callbackRate between 1% and 10% (i.e. 0.01-0.10); offsets outside that range are rejected with this error.

Solutions

  1. Clamp the trailing offset into the 1-10% range before submitting the order
  2. Set the strategy's trailing offset parameter within [1, 10] percent
  3. Catch the error in validate_order and surface a clear configuration error to the user

Example fix

// before
let offset = Decimal::new(15, 0); // 15%
let rate = trailing_offset_to_callback_rate(offset)?;
// after
let offset = Decimal::new(15, 0).min(Decimal::from(10)).max(Decimal::from(1));
let rate = trailing_offset_to_callback_rate(offset)?;
Defensive patterns

Strategy: validation

Validate before calling

use rust_decimal::Decimal;
fn is_binance_callback_rate_ok(offset_pct: Decimal) -> bool {
    offset_pct >= Decimal::ONE && offset_pct <= Decimal::from(10)
}

Type guard

fn is_valid_trailing_offset(offset: Decimal) -> bool {
    offset >= Decimal::ONE && offset <= Decimal::from(10)
}

Try / catch

match trailing_offset_to_callback_rate_string(offset) {
    Err(e) if e.to_string().contains("out of Binance range") => {
        let clamped = offset.clamp(Decimal::ONE, Decimal::from(10));
        trailing_offset_to_callback_rate_string(clamped)?
    }
    r => r?,
}

Prevention

When it happens

Trigger: Submitting or validating a TRAILING_STOP/trailing-stop-market order whose trailing offset is < 1% or > 10%, e.g. offset=0.5 or offset=15; also reached via trailing_offset_to_callback_rate_string and validate_order.

Common situations: Porting a strategy from another venue with looser trailing-stop bounds (e.g. 0.1% or 20% trails); computing the offset from volatility and landing outside Binance's allowed band; confusing percent vs fraction units.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/futures/conversions.rs:100

        Some(true)
    } else {
        None
    }
}

/// Converts a Nautilus trailing offset (percent) into a Binance `callbackRate` decimal.
///
/// # Errors
///
/// Returns an error if the computed rate is outside the Binance accepted range
/// `[0.1%, 10.0%]`.
pub(crate) fn trailing_offset_to_callback_rate(offset: Decimal) -> anyhow::Result<Decimal> {
    let rate = offset / rust_decimal::Decimal::ONE_HUNDRED;
    let min_rate = rust_decimal::Decimal::new(1, 1);
    let max_rate = rust_decimal::Decimal::new(100, 1);

    if rate < min_rate || rate > max_rate {
        anyhow::bail!("callbackRate {rate}% out of Binance range [{min_rate}, {max_rate}]");
    }

    Ok(rate)
}

/// Converts a Nautilus trailing offset (percent) into a Binance `callbackRate` string.
///
/// # Errors
///
/// Returns an error if the computed rate is outside the Binance accepted range.
pub(crate) fn trailing_offset_to_callback_rate_string(offset: Decimal) -> anyhow::Result<String> {
    let rate = trailing_offset_to_callback_rate(offset)?;
    Ok(format_callback_rate(rate))
}

/// Formats a `callbackRate` decimal for Binance request params.
///
/// Whole percents are rendered with a trailing `.0` to match Binance examples.

View on GitHub (pinned to 18893faf8b)