Skip to main content

nautilus_backtest/modules/
mod.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3//  https://nautechsystems.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Simulation module trait for extending backtesting with custom venue behaviors.
17
18pub mod fx_rollover;
19
20use ahash::AHashMap;
21pub use fx_rollover::FXRolloverInterestModule;
22use nautilus_common::cache::Cache;
23use nautilus_core::UnixNanos;
24use nautilus_execution::matching_engine::engine::OrderMatchingEngine;
25use nautilus_model::{
26    data::Data,
27    identifiers::{InstrumentId, Venue},
28    instruments::InstrumentAny,
29    types::{Currency, Money},
30};
31
32/// Read-only view of exchange state passed to simulation modules during processing.
33#[derive(Debug)]
34pub struct ExchangeContext<'a> {
35    /// The venue identifier.
36    pub venue: Venue,
37    /// The optional base currency for single-currency accounts.
38    pub base_currency: Option<Currency>,
39    /// All instruments registered on the exchange.
40    pub instruments: &'a AHashMap<InstrumentId, InstrumentAny>,
41    /// All matching engines, providing order book access.
42    pub matching_engines: &'a AHashMap<InstrumentId, OrderMatchingEngine>,
43    /// Read-only cache access for querying positions and other state.
44    pub cache: &'a Cache,
45}
46
47#[derive(Debug, Clone)]
48pub enum SimulationModuleAny {
49    FXRolloverInterest(FXRolloverInterestModule),
50}
51
52impl SimulationModule for SimulationModuleAny {
53    fn pre_process(&self, data: &Data) {
54        match self {
55            Self::FXRolloverInterest(module) => module.pre_process(data),
56        }
57    }
58
59    fn process(&self, ts_now: UnixNanos, ctx: &ExchangeContext) -> Vec<Money> {
60        match self {
61            Self::FXRolloverInterest(module) => module.process(ts_now, ctx),
62        }
63    }
64
65    fn log_diagnostics(&self) {
66        match self {
67            Self::FXRolloverInterest(module) => module.log_diagnostics(),
68        }
69    }
70
71    fn reset(&self) {
72        match self {
73            Self::FXRolloverInterest(module) => module.reset(),
74        }
75    }
76}
77
78impl From<SimulationModuleAny> for Box<dyn SimulationModule> {
79    fn from(value: SimulationModuleAny) -> Self {
80        match value {
81            SimulationModuleAny::FXRolloverInterest(module) => Box::new(module),
82        }
83    }
84}
85
86/// Trait for custom simulation modules that extend backtesting functionality.
87///
88/// Implementations can add specialized behavior such as rollover interest,
89/// market makers, price impact models, or other venue-specific simulation
90/// logic that runs alongside the core backtesting engine.
91///
92/// Modules use interior mutability (`Cell`/`RefCell`) for state since they
93/// are stored inside `SimulatedExchange` and invoked through shared references.
94pub trait SimulationModule {
95    /// Pre-processes market data before matching engine processing.
96    fn pre_process(&self, data: &Data);
97
98    /// Processes simulation logic at the given timestamp.
99    ///
100    /// Returns account balance adjustments to be applied by the exchange.
101    fn process(&self, ts_now: UnixNanos, ctx: &ExchangeContext) -> Vec<Money>;
102
103    /// Logs diagnostic information about the module's state.
104    fn log_diagnostics(&self);
105
106    /// Resets the module to its initial state.
107    fn reset(&self);
108}