Skip to main content

nautilus_execution/order_emulator/
adapter.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
16use std::{
17    cell::{Ref, RefCell, RefMut},
18    rc::Rc,
19};
20
21use nautilus_common::{
22    cache::Cache,
23    clock::Clock,
24    msgbus::{
25        MessagingSwitchboard, TypedHandler, TypedIntoHandler, register_trading_command_endpoint,
26    },
27};
28use nautilus_core::{UUID4, WeakCell};
29use nautilus_model::identifiers::TraderId;
30use ustr::Ustr;
31
32use crate::{
33    order_emulator::{emulator::OrderEmulator, handlers::OrderEmulatorOnEventHandler},
34    order_manager::handlers::{
35        CancelOrderHandlerAny, ModifyOrderHandlerAny, SubmitOrderHandlerAny,
36    },
37};
38
39#[derive(Debug)]
40pub struct OrderEmulatorAdapter {
41    emulator: Rc<RefCell<OrderEmulator>>,
42}
43
44impl OrderEmulatorAdapter {
45    /// Creates a new [`OrderEmulatorAdapter`] instance.
46    ///
47    /// # Panics
48    ///
49    /// Panics if registration with the actor system fails.
50    pub fn new(
51        trader_id: TraderId,
52        clock: Rc<RefCell<dyn Clock>>,
53        cache: Rc<RefCell<Cache>>,
54    ) -> Self {
55        let emulator = Rc::new(RefCell::new(OrderEmulator::new(
56            clock.clone(),
57            cache.clone(),
58        )));
59
60        emulator
61            .borrow_mut()
62            .register(trader_id, clock, cache)
63            .expect("Failed to register OrderEmulator");
64
65        // Set self-reference for subscription handlers
66        Self::initialize_self_ref(&emulator);
67
68        Self::initialize_execute_handler(&emulator);
69        Self::initialize_on_event_handler(&emulator);
70        Self::initialize_submit_order_handler(&emulator);
71        Self::initialize_cancel_order_handler(&emulator);
72        Self::initialize_modify_order_handler(&emulator);
73
74        Self { emulator }
75    }
76
77    fn initialize_self_ref(emulator: &Rc<RefCell<OrderEmulator>>) {
78        let self_ref = WeakCell::from(Rc::downgrade(emulator));
79        emulator.borrow_mut().set_self_ref(self_ref);
80    }
81
82    fn initialize_submit_order_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
83        let handler = SubmitOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(emulator)));
84        emulator.borrow_mut().set_submit_order_handler(handler);
85    }
86
87    fn initialize_cancel_order_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
88        let handler = CancelOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(emulator)));
89        emulator.borrow_mut().set_cancel_order_handler(handler);
90    }
91
92    fn initialize_modify_order_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
93        let handler = ModifyOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(emulator)));
94        emulator.borrow_mut().set_modify_order_handler(handler);
95    }
96
97    fn initialize_execute_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
98        let emulator_weak = WeakCell::from(Rc::downgrade(emulator));
99        let handler = TypedIntoHandler::from(move |cmd| {
100            if let Some(emulator_rc) = emulator_weak.upgrade() {
101                emulator_rc.borrow_mut().execute(cmd);
102            }
103        });
104
105        let endpoint = MessagingSwitchboard::order_emulator_execute();
106        register_trading_command_endpoint(endpoint, handler);
107    }
108
109    fn initialize_on_event_handler(emulator: &Rc<RefCell<OrderEmulator>>) {
110        let handler = TypedHandler::new(OrderEmulatorOnEventHandler::new(
111            Ustr::from(UUID4::new().as_str()),
112            WeakCell::from(Rc::downgrade(emulator)),
113        ));
114
115        emulator.borrow_mut().set_on_event_handler(handler);
116    }
117
118    #[must_use]
119    pub fn get_emulator(&self) -> Ref<'_, OrderEmulator> {
120        self.emulator.borrow()
121    }
122
123    #[must_use]
124    pub fn get_emulator_mut(&self) -> RefMut<'_, OrderEmulator> {
125        self.emulator.borrow_mut()
126    }
127}