nautechsystems/nautilus_trader · error · anyhow::Error

Binance Futures trade limit must not exceed 1000

Error message

Binance Futures trade limit must not exceed 1000

What it means

Historical trade requests are forwarded to Binance's trades/aggTrades endpoints, whose server-side maximum result limit is 1000. The adapter validates `limit <= 1000` before spawning the fetch and rejects larger values up front rather than silently clamping or truncating results.

Source

Thrown at crates/adapters/binance/src/futures/data.rs:2909

        });

        Ok(())
    }

    fn request_trades(&self, request: RequestTrades) -> anyhow::Result<()> {
        let http = self.http_client.clone();
        let sender = self.data_sender.clone();
        let instrument_id = request.instrument_id;
        let limit = request.limit.map(|n| n.get() as u32);
        let request_id = request.request_id;
        let client_id = request.client_id.unwrap_or(self.client_id);
        let params = request.params;
        let clock = self.clock;
        let start_nanos = datetime_to_unix_nanos(request.start);
        let end_nanos = datetime_to_unix_nanos(request.end);
        let start = request.start;
        let end = request.end;
        anyhow::ensure!(
            limit.is_none_or(|value| value <= 1000),
            "Binance Futures trade limit must not exceed 1000"
        );

        get_runtime().spawn(async move {
            let result = if start.is_some() || end.is_some() {
                http.request_agg_trades(instrument_id, start, end, limit)
                    .await
            } else {
                http.request_trades(instrument_id, limit).await
            };

            match result.context("failed to request trades from Binance Futures") {
                Ok(trades) => {
                    let response = DataResponse::Trades(TradesResponse::new(
                        request_id,
                        client_id,
                        instrument_id,

View on GitHub (pinned to a4b06ed870)

Solutions

  1. Set limit to 1000 or less
  2. For more history, paginate with start/end time windows (the request supports start and end), requesting at most 1000 trades per call

Example fix

# before
actor.request_trades(instrument_id, start=start_ts, limit=5000)

# after: cap each call, paginate by time window
actor.request_trades(instrument_id, start=start_ts, end=window_end, limit=1000)
Defensive patterns

Strategy: validation

Validate before calling

BINANCE_TRADE_LIMIT = 1000

def clamp_trade_limit(limit: int | None) -> int | None:
    if limit is not None and limit > BINANCE_TRADE_LIMIT:
        raise ValueError(
            f'limit {limit} exceeds Binance max {BINANCE_TRADE_LIMIT}; paginate with start/end windows instead'
        )
    return limit

Type guard

def is_valid_binance_trade_limit(limit) -> bool:
    return limit is None or limit <= 1000

Try / catch

try:
    actor.request_trades(instrument_id, start=start_ts, limit=limit)
except Exception as e:
    if 'trade limit must not exceed 1000' in str(e):
        actor.request_trades(instrument_id, start=start_ts, limit=1000)  # then paginate forward by last trade time
    else:
        raise

Prevention

When it happens

Trigger: `request_trades` with `limit` set above 1000, e.g. `limit=5000` (a value valid on some other venues' trade endpoints). Omitting limit (None) is fine — the check is `limit.is_none_or(|value| value <= 1000)`.

Common situations: Porting trade-history configs from venues allowing 5000+ per request; wanting a large backfill in one call; generic pagination code assuming uniform limits across adapters.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@a4b06ed870 (2026-08-16). Data as JSON: /api/errors/1539dc51f5962ed6. Report an issue: GitHub.