nautechsystems/nautilus_trader · error
cannot calculate CFD swap for position {}: adjustment overfl
Error message
cannot calculate CFD swap for position {}: adjustment overflow What it means
While computing a daily swap adjustment, the module multiplies the position's notional value by the daily rate and the contract multiplier using checked Decimal math. If any product overflows Decimal's maximum, the adjustment cannot be represented and this error is thrown for that position.
Source
Thrown at crates/backtest/src/modules/cfd_swap.rs:287
} else {
Decimal::ONE
};
for position in positions {
let daily_rate = if position.is_long() {
rate.long_rate
} else if position.is_short() {
rate.short_rate
} else {
continue;
};
let notional = position.try_notional_value(settlement_price)?;
let amount = notional
.as_decimal()
.checked_mul(daily_rate)
.and_then(|value| value.checked_mul(multiplier))
.ok_or_else(|| {
anyhow::anyhow!(
"cannot calculate CFD swap for position {}: adjustment overflow",
position.id
)
})?;
let (amount, currency) = if let Some(base_currency) = ctx.base_currency {
let xrate = match ctx.cache.try_get_xrate(
ctx.venue,
notional.currency,
base_currency,
PriceType::Mid,
) {
Ok(Some(xrate)) => xrate,
Ok(None) => {
self.log_calculation_failure(
booking_date,
instrument_id,
CfdSwapFailureKind::Xrate,
&format!(View on GitHub (pinned to 18893faf8b)
Solutions
- Check the configured daily swap rate and contract multiplier for scale errors (rate should be a small fraction, e.g. 0.0001)
- Validate position sizes and notional values for corruption before the rollover day
- Reduce position sizes or correct the instrument definition so notional stays within Decimal range
Example fix
// before "swap_rate": 500.0, // meant 0.05% // after "swap_rate": 0.0005,
Defensive patterns
Strategy: validation
Validate before calling
// validate config scale before running assert!(daily_rate.abs() < Decimal::new(1, 2), "swap rate should be a small fraction"); assert!(*multiplier < Decimal::from(1_000_000), "multiplier out of range");
Try / catch
match module.process(ts_now) {
Ok(r) => r,
Err(e) if e.to_string().contains("adjustment overflow") => {
log::error!("check swap rate/multiplier/position size: {e:#}");
SimulationModuleResult::NotReady
}
Err(e) => return Err(e),
} Prevention
- Express swap rates as fractions (0.0001, not 1% = 100)
- Verify contract multipliers against the instrument spec
- Monitor position sizes for corruption from upstream feed errors
When it happens
Trigger: calculate_adjustments (via process) encounters a position whose try_notional_value * daily_rate * multiplier exceeds Decimal::MAX — typically from an enormous rate, multiplier, or notional (mis-scaled rate like 1e20 instead of 1e-4, or a gigantic position size).
Common situations: Misconfigured swap rate/multiplier config (percent given as 0.05 vs 5 vs 500); corrupted position sizes from earlier feed errors; currency with wrong precision inflating notional.
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
- cannot calculate CFD swap for {instrument_id}: midpoint over
- cannot calculate CFD swap for position {}: currency conversi
- CFD swap diagnostic total overflow
- unapplied CFD swap total overflow
- CFD swap rollover day is not initialized
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5dd5aecc11372dbd.
Report an issue: GitHub.