nautechsystems/nautilus_trader · error

CFD swap rollover day is not initialized

Error message

CFD swap rollover day is not initialized

What it means

During process(), when the engine asks for already-completed pending adjustments, the rollover_day cell is None — the CFD swap module was never initialized with a rollover day. The module cannot return results for a day it does not know about, so it throws.

Source

Thrown at crates/backtest/src/modules/cfd_swap.rs:391

                    Some(Self::next_weekday(day.date)?)
                }
                Some(_) => None,
            }
        };

        if let Some(date) = initialize_date {
            self.initialize_rollover_day(date);
        }

        if self.rollover_completed.get() {
            return Ok(SimulationModuleResult::NotReady);
        }

        {
            let day = self.rollover_day.borrow();
            let day = day
                .as_ref()
                .ok_or_else(|| anyhow::anyhow!("CFD swap rollover day is not initialized"))?;
            if let Some(adjustments) = &day.pending_adjustments {
                return Ok(SimulationModuleResult::Completed(
                    adjustments
                        .iter()
                        .map(|adjustment| adjustment.amount)
                        .collect(),
                ));
            }
        }

        let date = self
            .rollover_day
            .borrow()
            .as_ref()
            .ok_or_else(|| anyhow::anyhow!("CFD swap rollover day is not initialized"))?
            .date;
        if ts_now.as_u64() < self.rollover_time_ns(date)? {
            return Ok(SimulationModuleResult::NotReady);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the module's initialization path runs before the simulation loop (call its on_start / feed the first bar or time event)
  2. Verify the module is registered so its on_start receives engine config dates
  3. Check that the backtest data actually contains bars/events for the instrument before rollover processing begins

Example fix

// before: processing module before init
module.process(ts_now)?; // rollover_day is None
// after: initialize first
module.on_start(&config)?;
module.on_bar(&first_bar)?;
module.process(ts_now)?;
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure module lifecycle ran before process
module.on_start(&engine_config)?;

Try / catch

match module.process(ts_now) {
    Err(e) if e.to_string().contains("rollover day is not initialized") => {
        log::warn!("CFD swap module not initialized yet, skipping");
        SimulationModuleResult::NotReady
    }
    other => other,
}

Prevention

When it happens

Trigger: Calling process() on the CFD swap module (e.g. as part of the simulation loop) on a code path that reads pending adjustments before the module's initialization (on_start / first on_bar / set_rollover_day) has populated rollover_day.

Common situations: Running the engine without firing the module's start/initialization event; adding the module to the engine but never sending bars/dates it uses to seed the rollover day; misordered module startup.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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