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.clone());
67
68        Self::initialize_execute_handler(emulator.clone());
69        Self::initialize_on_event_handler(emulator.clone());
70        Self::initialize_submit_order_handler(emulator.clone());
71        Self::initialize_cancel_order_handler(emulator.clone());
72        Self::initialize_modify_order_handler(emulator.clone());
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 =
84            SubmitOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(&emulator)));
85        emulator.borrow_mut().set_submit_order_handler(handler);
86    }
87
88    fn initialize_cancel_order_handler(emulator: Rc<RefCell<OrderEmulator>>) {
89        let handler =
90            CancelOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(&emulator)));
91        emulator.borrow_mut().set_cancel_order_handler(handler);
92    }
93
94    fn initialize_modify_order_handler(emulator: Rc<RefCell<OrderEmulator>>) {
95        let handler =
96            ModifyOrderHandlerAny::OrderEmulator(WeakCell::from(Rc::downgrade(&emulator)));
97        emulator.borrow_mut().set_modify_order_handler(handler);
98    }
99
100    fn initialize_execute_handler(emulator: Rc<RefCell<OrderEmulator>>) {
101        let emulator_weak = WeakCell::from(Rc::downgrade(&emulator));
102        let handler = TypedIntoHandler::from(move |cmd| {
103            if let Some(emulator_rc) = emulator_weak.upgrade() {
104                emulator_rc.borrow_mut().execute(cmd);
105            }
106        });
107
108        let endpoint = MessagingSwitchboard::order_emulator_execute();
109        register_trading_command_endpoint(endpoint, handler);
110    }
111
112    fn initialize_on_event_handler(emulator: Rc<RefCell<OrderEmulator>>) {
113        let handler = TypedHandler::new(OrderEmulatorOnEventHandler::new(
114            Ustr::from(UUID4::new().as_str()),
115            WeakCell::from(Rc::downgrade(&emulator)),
116        ));
117
118        emulator.borrow_mut().set_on_event_handler(handler);
119    }
120
121    #[must_use]
122    pub fn get_emulator(&self) -> Ref<'_, OrderEmulator> {
123        self.emulator.borrow()
124    }
125
126    #[must_use]
127    pub fn get_emulator_mut(&self) -> RefMut<'_, OrderEmulator> {
128        self.emulator.borrow_mut()
129    }
130}