nautechsystems/nautilus_trader · error

Binance Futures fill report end time requires start time for

Error message

Binance Futures fill report end time requires start time for a complete range

What it means

Binance's user-trades endpoint paginates by trade ID; querying only an `end` time with no `start` cannot yield a well-defined complete range (the ID cursor would need to start at 0 and scan everything). The adapter therefore rejects a GenerateFillReports command that sets `end` without `start`.

Source

Thrown at crates/adapters/binance/src/futures/execution.rs:2527

                    }

                    let next_from_id = max_trade_id
                        .checked_add(1)
                        .context("Binance user trade ID overflow during pagination")?;
                    anyhow::ensure!(
                        from_id.is_none_or(|cursor| next_from_id > cursor),
                        "Binance user-trades pagination made no progress"
                    );
                    from_id = Some(next_from_id);
                }

                if window_end >= query_end_time {
                    break;
                }
                window_start = window_end.saturating_add(1);
            }
        } else {
            anyhow::ensure!(
                cmd.end.is_none(),
                "Binance Futures fill report end time requires start time for a complete range"
            );
            let mut from_id = 0;

            loop {
                let params = BinanceUserTradesParamsBuilder::default()
                    .symbol(symbol.clone())
                    .from_id(from_id)
                    .limit(USER_TRADES_PAGE_LIMIT)
                    .build()
                    .map_err(|e| anyhow::anyhow!("{e}"))?;
                let page = self.http_client.query_user_trades(&params).await?;

                if page.is_empty() {
                    break;
                }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Always provide a `start` timestamp when calling generate_fill_reports; add `end` only if you need a bounded range.
  2. To bound only the upper edge, compute a start (e.g. account activation time or now - lookback) and pass both.
  3. Filter the returned fill reports by ts_event afterwards if you only need recent trades, as generate_mass_status itself does.

Example fix

// before
let cmd = GenerateFillReportsBuilder::default()
    .ts_init(ts_now)
    .end(Some(end))
    .build()?;
// after
let cmd = GenerateFillReportsBuilder::default()
    .ts_init(ts_now)
    .start(Some(start))
    .end(Some(end))
    .build()?;
Defensive patterns

Strategy: validation

Validate before calling

if let (None, Some(_)) = (cmd.start, cmd.end) {
    return Err(anyhow::anyhow!("fill report end time requires start time"));
}

Prevention

When it happens

Trigger: Building GenerateFillReports with `.end(...)` set and `.start(None)`, then calling generate_fill_reports (typically via generate_mass_status).

Common situations: Developers wanting 'trades up to now' or 'trades in the last hour' pass only an end bound; or code that conditionally sets start/end leaves end populated while start is omitted.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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