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(¶ms).await?;
if page.is_empty() {
break;
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Always provide a `start` timestamp when calling generate_fill_reports; add `end` only if you need a bounded range.
- To bound only the upper edge, compute a start (e.g. account activation time or now - lookback) and pass both.
- 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
- Always set `start` on GenerateFillReports; treat `end` as optional refinement only.
- Centralize fill-report command construction in one helper that enforces the invariant.
- Write a unit test asserting the builder helper never emits end-without-start.
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
- Invalid time range: start={start:?} end={end:?}
- Invalid time range: start={s:?} end={e:?}
- Unsupported `OrderSide` for Binance: {value:?}
- Invalid tickSize of 0 for symbol '{}', cannot create instrum
- custom data request requires `instrument_id` metadata
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/fce2b692cb61a2da.
Report an issue: GitHub.