nautechsystems/nautilus_trader · error
CFD swap acknowledgement count {}, expected {}
Error message
CFD swap acknowledgement count {}, expected {} What it means
This error is raised in the CFD swap module's `acknowledge` method when the number of account adjustment outcomes passed back by the caller does not match the number of pending swap adjustments recorded when the rollover batch completed. The backtest module requires a one-to-one acknowledgement of every adjustment it applied. A count mismatch means the driver loop submitted an outcome vector that does not correspond to the current batch.
Source
Thrown at crates/backtest/src/modules/cfd_swap.rs:460
.as_mut()
.ok_or_else(|| anyhow::anyhow!("CFD swap rollover day is not initialized"))?;
day.pending_adjustments = Some(batch);
day.pending_end_date = Some(batch_end_date);
Ok(SimulationModuleResult::Completed(adjustments))
}
fn acknowledge(&self, outcomes: &[AccountAdjustmentOutcome]) -> anyhow::Result<()> {
let (adjustments, batch_end_date) = {
let mut day = self.rollover_day.borrow_mut();
let day = day
.as_mut()
.ok_or_else(|| anyhow::anyhow!("CFD swap rollover day is not initialized"))?;
let adjustment_count = day
.pending_adjustments
.as_ref()
.ok_or_else(|| anyhow::anyhow!("no completed CFD swap batch to acknowledge"))?
.len();
anyhow::ensure!(
outcomes.len() == adjustment_count,
"CFD swap acknowledgement count {}, expected {}",
outcomes.len(),
adjustment_count
);
let adjustments = day
.pending_adjustments
.take()
.ok_or_else(|| anyhow::anyhow!("no completed CFD swap batch to acknowledge"))?;
let end_date = day
.pending_end_date
.ok_or_else(|| anyhow::anyhow!("CFD swap batch end date was not recorded"))?;
(adjustments, end_date)
};
let mut failed = Vec::new();
for (adjustment, outcome) in adjustments.into_iter().zip(outcomes) {View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the caller collects exactly one AccountAdjustmentOutcome per pending adjustment in the same order the adjustments were generated.
- Call `acknowledge` exactly once per completed swap batch; do not re-call after a partial acknowledgement.
- If filtering outcomes, keep placeholders (e.g. Failed outcomes) rather than removing entries so the count stays aligned.
- Log both lengths (outcomes.len() and the pending count) at the call site to identify where the divergence occurs.
Example fix
// before let outcomes: Vec<_> = results.into_iter().filter(|r| r.is_ok()).collect(); engine.acknowledge(&outcomes)?; // after let outcomes: Vec<_> = results.into_iter().collect(); // keep 1:1 with adjustments engine.acknowledge(&outcomes)?;
Defensive patterns
Strategy: validation
Validate before calling
let pending_count = engine.pending_adjustment_count()?;
anyhow::ensure!(outcomes.len() == pending_count, "outcome count {} != pending {}", outcomes.len(), pending_count);
engine.acknowledge(&outcomes)?; Try / catch
match engine.acknowledge(&outcomes) {
Ok(()) => {},
Err(e) if e.to_string().contains("acknowledgement count") => log::error!("outcome/batch misalignment: {e}"),
Err(e) => return Err(e),
} Prevention
- Keep outcomes and adjustments strictly 1:1 and in order
- Never filter outcome vectors before acknowledgement
- Acknowledge each batch exactly once
When it happens
Trigger: Calling `acknowledge` with an `outcomes` slice whose length differs from `day.pending_adjustments.len()`. Typically happens when outcomes are collected across multiple days, filtered (e.g. dropping failed adjustments), duplicated, or `acknowledge` is called twice for one batch.
Common situations: Backtest drivers that pre-allocate or truncate outcome vectors, or that batch acknowledgements after retry loops which skip some outcomes. Also occurs if `begin_rollover`/batch completion was re-run between generating outcomes and acknowledging them, replacing the pending batch.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- cannot calculate CFD swap for {instrument_id}: midpoint over
- cannot calculate CFD swap for position {}: adjustment overfl
- cannot calculate CFD swap for position {}: currency conversi
- CFD swap rollover day is not initialized
- no completed CFD swap batch to acknowledge
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e51e16e730345ee8.
Report an issue: GitHub.