nautilus_backtest/
execution_client.rs
1#![allow(dead_code)]
18#![allow(unused_variables)]
19
20use std::{cell::RefCell, rc::Rc};
23
24use nautilus_common::{cache::Cache, clock::Clock};
25use nautilus_core::UnixNanos;
26use nautilus_execution::{
27 client::{ExecutionClient, base::BaseExecutionClient},
28 messages::{
29 BatchCancelOrders, CancelAllOrders, CancelOrder, ModifyOrder, QueryOrder, SubmitOrder,
30 SubmitOrderList, TradingCommand,
31 },
32};
33use nautilus_model::{
34 accounts::AccountAny,
35 enums::OmsType,
36 identifiers::{AccountId, ClientId, TraderId, Venue},
37 orders::Order,
38 types::{AccountBalance, MarginBalance},
39};
40
41use crate::exchange::SimulatedExchange;
42
43pub struct BacktestExecutionClient {
44 base: BaseExecutionClient,
45 exchange: Rc<RefCell<SimulatedExchange>>,
46 clock: Rc<RefCell<dyn Clock>>,
47 is_connected: bool,
48 routing: bool,
49 frozen_account: bool,
50}
51
52impl BacktestExecutionClient {
53 #[allow(clippy::too_many_arguments)]
54 pub fn new(
55 trader_id: TraderId,
56 account_id: AccountId,
57 exchange: Rc<RefCell<SimulatedExchange>>,
58 cache: Rc<RefCell<Cache>>,
59 clock: Rc<RefCell<dyn Clock>>,
60 routing: Option<bool>,
61 frozen_account: Option<bool>,
62 ) -> Self {
63 let routing = routing.unwrap_or(false);
64 let frozen_account = frozen_account.unwrap_or(false);
65 let exchange_id = exchange.borrow().id;
66 let base_client = BaseExecutionClient::new(
67 trader_id,
68 ClientId::from(exchange_id.as_str()),
69 Venue::from(exchange_id.as_str()),
70 exchange.borrow().oms_type,
71 account_id,
72 exchange.borrow().account_type,
73 exchange.borrow().base_currency,
74 clock.clone(),
75 cache,
76 );
77
78 if !frozen_account {
79 }
81
82 Self {
83 exchange,
84 clock,
85 base: base_client,
86 is_connected: false,
87 routing,
88 frozen_account,
89 }
90 }
91}
92
93impl ExecutionClient for BacktestExecutionClient {
94 fn is_connected(&self) -> bool {
95 self.is_connected
96 }
97
98 fn client_id(&self) -> ClientId {
99 self.base.client_id
100 }
101
102 fn account_id(&self) -> AccountId {
103 self.base.account_id
104 }
105
106 fn venue(&self) -> Venue {
107 self.base.venue
108 }
109
110 fn oms_type(&self) -> OmsType {
111 self.base.oms_type
112 }
113
114 fn get_account(&self) -> Option<AccountAny> {
115 self.base.get_account()
116 }
117
118 fn generate_account_state(
119 &self,
120 balances: Vec<AccountBalance>,
121 margins: Vec<MarginBalance>,
122 reported: bool,
123 ts_event: UnixNanos,
124 ) -> anyhow::Result<()> {
125 self.base
126 .generate_account_state(balances, margins, reported, ts_event)
127 }
128
129 fn start(&mut self) -> anyhow::Result<()> {
130 self.is_connected = true;
131 log::info!("Backtest execution client started");
132 Ok(())
133 }
134
135 fn stop(&mut self) -> anyhow::Result<()> {
136 self.is_connected = false;
137 log::info!("Backtest execution client stopped");
138 Ok(())
139 }
140
141 fn submit_order(&self, command: SubmitOrder) -> anyhow::Result<()> {
142 self.base.generate_order_submitted(
143 command.strategy_id,
144 command.instrument_id,
145 command.client_order_id,
146 self.clock.borrow().timestamp_ns(),
147 );
148
149 self.exchange
150 .borrow_mut()
151 .send(TradingCommand::SubmitOrder(command));
152 Ok(())
153 }
154
155 fn submit_order_list(&self, command: SubmitOrderList) -> anyhow::Result<()> {
156 for order in &command.order_list.orders {
157 self.base.generate_order_submitted(
158 command.strategy_id,
159 order.instrument_id(),
160 order.client_order_id(),
161 self.clock.borrow().timestamp_ns(),
162 );
163 }
164
165 self.exchange
166 .borrow_mut()
167 .send(TradingCommand::SubmitOrderList(command));
168 Ok(())
169 }
170
171 fn modify_order(&self, command: ModifyOrder) -> anyhow::Result<()> {
172 self.exchange
173 .borrow_mut()
174 .send(TradingCommand::ModifyOrder(command));
175 Ok(())
176 }
177
178 fn cancel_order(&self, command: CancelOrder) -> anyhow::Result<()> {
179 self.exchange
180 .borrow_mut()
181 .send(TradingCommand::CancelOrder(command));
182 Ok(())
183 }
184
185 fn cancel_all_orders(&self, command: CancelAllOrders) -> anyhow::Result<()> {
186 self.exchange
187 .borrow_mut()
188 .send(TradingCommand::CancelAllOrders(command));
189 Ok(())
190 }
191
192 fn batch_cancel_orders(&self, command: BatchCancelOrders) -> anyhow::Result<()> {
193 self.exchange
194 .borrow_mut()
195 .send(TradingCommand::BatchCancelOrders(command));
196 Ok(())
197 }
198
199 fn query_order(&self, command: QueryOrder) -> anyhow::Result<()> {
200 self.exchange
201 .borrow_mut()
202 .send(TradingCommand::QueryOrder(command));
203 Ok(())
204 }
205}