{"record":{"id":"6c3043565ed946a1","repo":"nautechsystems/nautilus_trader","slug":"cash-account-cannot-trade-futures-or-perpetuals","errorCode":null,"errorMessage":"Cash account cannot trade futures or perpetuals","messagePattern":"Cash account cannot trade futures or perpetuals","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/backtest/src/exchange.rs","lineNumber":459,"sourceCode":"    /// # Panics\n    ///\n    /// Panics if the instrument cannot be added to the exchange.\n    pub fn add_instrument(&mut self, instrument: InstrumentAny) -> anyhow::Result<()> {\n        check_equal(\n            &instrument.id().venue,\n            &self.id,\n            \"Venue of instrument id\",\n            \"Venue of simulated exchange\",\n        )\n        .expect_display(FAILED);\n\n        if self.account_type == AccountType::Cash\n            && (matches!(instrument, InstrumentAny::CryptoPerpetual(_))\n                || matches!(instrument, InstrumentAny::CryptoFuture(_))\n                || matches!(instrument, InstrumentAny::FuturesContract(_))\n                || matches!(instrument, InstrumentAny::PerpetualContract(_)))\n        {\n            anyhow::bail!(\"Cash account cannot trade futures or perpetuals\")\n        }\n\n        let price_protection = if self.price_protection_points == 0 {\n            None\n        } else {\n            Some(self.price_protection_points)\n        };\n\n        let matching_engine_config = OrderMatchingEngineConfig::builder()\n            .bar_execution(self.bar_execution)\n            .bar_adaptive_high_low_ordering(self.bar_adaptive_high_low_ordering)\n            .trade_execution(self.trade_execution)\n            .liquidity_consumption(self.liquidity_consumption)\n            .reject_stop_orders(self.reject_stop_orders)\n            .support_gtd_orders(self.support_gtd_orders)\n            .support_contingent_orders(self.support_contingent_orders)\n            .use_position_ids(self.use_position_ids)\n            .use_random_ids(self.use_random_ids)","sourceCodeStart":441,"sourceCodeEnd":477,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/backtest/src/exchange.rs#L441-L477","documentation":"A cash (non-margin) account cannot hold derivatives like futures, perpetuals, or crypto perpetual/future instruments, since they imply leverage and margin. add_instrument on the exchange bails when such an instrument is added to a cash-account venue.","triggerScenarios":"Configuring a venue with account_type Cash and then adding a CryptoPerpetual, CryptoFuture, FuturesContract, or PerpetualContract instrument via add_instrument (directly or through data processing paths).","commonSituations":"Reusing a cash account venue config for a perp dataset; default account_type Cash left in venue config when backtesting perpetual futures.","solutions":["Set the venue account_type to Margin (or Betting) in SimulatedVenueConfig when trading derivatives","Use spot instruments only on cash-account venues","Validate instrument types against account type before adding them"],"exampleFix":"// before\nconfig.account_type = AccountType::Cash; // with perp instruments\n// after\nconfig.account_type = AccountType::Margin; // required for futures/perpetuals","handlingStrategy":"validation","validationCode":"use nautilus_model::enums::AccountType;\nlet is_derivative = matches!(\n    instrument,\n    InstrumentAny::CryptoPerpetual(_)\n        | InstrumentAny::CryptoFuture(_)\n        | InstrumentAny::FuturesContract(_)\n        | InstrumentAny::PerpetualContract(_)\n);\nanyhow::ensure!(\n    !(is_derivative && config.account_type == AccountType::Cash),\n    \"cash account venue cannot trade derivative instruments\"\n);","typeGuard":"fn is_derivative(instrument: &InstrumentAny) -> bool {\n    matches!(\n        instrument,\n        InstrumentAny::CryptoPerpetual(_)\n            | InstrumentAny::CryptoFuture(_)\n            | InstrumentAny::FuturesContract(_)\n            | InstrumentAny::PerpetualContract(_)\n    )\n}","tryCatchPattern":"match exchange.add_instrument(instrument) {\n    Err(e) if e.to_string() == \"Cash account cannot trade futures or perpetuals\" => {\n        eprintln!(\"use a Margin account venue for derivatives\");\n    }\n    other => other?,\n}","preventionTips":["Set account_type Margin for any venue trading futures/perpetuals","Filter derivative instruments out of cash-account venue setups","Validate the instrument/account-type pairing in venue construction helpers"],"tags":["backtest","exchange","account-type","derivatives"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}