nautechsystems/nautilus_trader · error

Binance Futures aggregate trade history is limited to the…

Error message

Binance Futures aggregate trade history is limited to the past 24 hours

What it means

Binance Futures only serves aggTrades (aggregate trade) data for roughly the last 24 hours. The adapter checks the requested start/end timestamps against a 24-hour cutoff from the current clock time and rejects any request reaching further back.

Solutions

  1. Request only data within the last 24 hours (set start >= now - 24h)
  2. Use a dedicated historical data vendor (e.g. Binance data dumps, Tardis, Nautilus data catalog) for older trades
  3. Double-check the timestamps passed are in UTC and not stale cached values

Example fix

// before
let start = Timestamp::from("2024-01-01T00:00:00Z"); // far in the past
// after
let start = (now_utc() - Duration::hours(23)).into(); // within 24h window
Defensive patterns

Strategy: validation

Validate before calling

let cutoff = now_utc() - chrono::Duration::hours(24);
if let Some(start) = &start {
    assert!(start.as_datetime() >= cutoff, "start must be within last 24h");
}
if let Some(end) = &end {
    assert!(end.as_datetime() >= cutoff, "end must be within last 24h");
}

Try / catch

match client.request_trades(instrument_id, start, end, limit).await {
    Ok(trades) => trades,
    Err(e) if e.to_string().contains("limited to the past 24 hours") => {
        // switch to an archival data source
        archival_provider.request_trades(instrument_id, start, end, limit).await
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Requesting aggregate trade history (request_trades / aggTrades) with a start or end Timestamp older than 24 hours relative to now; omitting start but passing an old end also triggers it.

Common situations: Backfill jobs or backtests requesting historical trades from Binance Futures; assuming unlimited trade history like spot or data-vendor APIs; clock/timezone mistakes making timestamps appear older than 24h.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at crates/adapters/binance/src/futures/http/client.rs:2993

        Ok(result)
    }

    /// Requests bounded aggregate public trades for an instrument.
    ///
    /// # Errors
    ///
    /// Returns an error if a supplied time bound is invalid or parsing fails.
    pub async fn request_agg_trades(
        &self,
        instrument_id: InstrumentId,
        start: Option<Timestamp>,
        end: Option<Timestamp>,
        limit: Option<u32>,
    ) -> anyhow::Result<Vec<TradeTick>> {
        let cutoff =
            self.clock.get_time_ns().to_datetime_utc() - jiff::SignedDuration::from_hours(24);
        anyhow::ensure!(
            start.as_ref().is_none_or(|value| value >= &cutoff)
                && end.as_ref().is_none_or(|value| value >= &cutoff),
            "Binance Futures aggregate trade history is limited to the past 24 hours"
        );
        let (symbol, price_precision, size_precision) =
            self.cached_precisions_by_id(instrument_id)?;
        let params = BinanceAggTradesParams {
            symbol,
            from_id: None,
            start_time: start.map(|value| value.as_millisecond()),
            end_time: end.map(|value| value.as_millisecond()),
            limit,
        };
        let trades = self.inner.agg_trades(&params).await?;
        trades
            .iter()
            .map(|trade| {
                let ts_init = parse_millis(trade.time, "Futures aggregate trade time")?;

View on GitHub (pinned to 18893faf8b)