Skip to content

Commit 2869923

Browse files
committed
implement add_venue for backtest engine
1 parent 9c04443 commit 2869923

File tree

1 file changed

+89
-30
lines changed

1 file changed

+89
-30
lines changed

crates/backtest/src/engine.rs

Lines changed: 89 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,28 @@
1919

2020
//! The core `BacktestEngine` for backtesting on historical data.
2121
22-
use std::collections::{HashMap, HashSet, VecDeque};
22+
use std::{
23+
cell::RefCell,
24+
collections::{HashMap, HashSet, VecDeque},
25+
rc::Rc,
26+
};
2327

2428
use nautilus_core::{UUID4, UnixNanos};
2529
use nautilus_execution::models::{fee::FeeModelAny, fill::FillModel, latency::LatencyModel};
2630
use nautilus_model::{
2731
data::Data,
2832
enums::{AccountType, BookType, OmsType},
29-
identifiers::{ClientId, InstrumentId, Venue},
33+
identifiers::{AccountId, ClientId, InstrumentId, Venue},
3034
instruments::InstrumentAny,
3135
types::{Currency, Money},
3236
};
3337
use nautilus_system::kernel::NautilusKernel;
38+
use rust_decimal::Decimal;
3439
use ustr::Ustr;
3540

3641
use crate::{
3742
accumulator::TimeEventAccumulator, config::BacktestEngineConfig, exchange::SimulatedExchange,
38-
modules::SimulationModule,
43+
execution_client::BacktestExecutionClient, modules::SimulationModule,
3944
};
4045

4146
pub struct BacktestEngine {
@@ -45,7 +50,7 @@ pub struct BacktestEngine {
4550
accumulator: TimeEventAccumulator,
4651
run_config_id: Option<UUID4>,
4752
run_id: Option<UUID4>,
48-
venues: HashMap<Venue, SimulatedExchange>,
53+
venues: HashMap<Venue, Rc<RefCell<SimulatedExchange>>>,
4954
has_data: HashSet<InstrumentId>,
5055
has_book_data: HashSet<InstrumentId>,
5156
data: VecDeque<Data>,
@@ -83,33 +88,87 @@ impl BacktestEngine {
8388

8489
#[allow(clippy::too_many_arguments)]
8590
pub fn add_venue(
86-
&self,
87-
_venue: Venue,
88-
_oms_type: OmsType,
89-
_account_type: AccountType,
90-
_book_type: BookType,
91-
_starting_balances: Vec<Money>,
92-
_base_currency: Option<Currency>,
93-
_default_leverage: Option<f64>,
94-
_leverages: Option<HashMap<Currency, f64>>,
95-
_modules: Vec<Box<dyn SimulationModule>>,
96-
_fill_model: Option<FillModel>,
97-
_fee_model: Option<FeeModelAny>,
98-
_latency_model: Option<LatencyModel>,
99-
_routing: Option<bool>,
100-
_frozen_account: Option<bool>,
101-
_reject_stop_orders: Option<bool>,
102-
_support_gtd_orders: Option<bool>,
103-
_support_contingent_orders: Option<bool>,
104-
_use_position_ids: Option<bool>,
105-
_use_random_ids: Option<bool>,
106-
_use_reduce_only: Option<bool>,
107-
_use_message_queue: Option<bool>,
108-
_bar_execution: Option<bool>,
109-
_bar_adaptive_high_low_ordering: Option<bool>,
110-
_trade_execution: Option<bool>,
91+
&mut self,
92+
venue: Venue,
93+
oms_type: OmsType,
94+
account_type: AccountType,
95+
book_type: BookType,
96+
starting_balances: Vec<Money>,
97+
base_currency: Option<Currency>,
98+
default_leverage: Option<Decimal>,
99+
leverages: HashMap<InstrumentId, Decimal>,
100+
modules: Vec<Box<dyn SimulationModule>>,
101+
fill_model: FillModel,
102+
fee_model: FeeModelAny,
103+
latency_model: Option<LatencyModel>,
104+
routing: Option<bool>,
105+
frozen_account: Option<bool>,
106+
reject_stop_orders: Option<bool>,
107+
support_gtd_orders: Option<bool>,
108+
support_contingent_orders: Option<bool>,
109+
use_position_ids: Option<bool>,
110+
use_random_ids: Option<bool>,
111+
use_reduce_only: Option<bool>,
112+
use_message_queue: Option<bool>,
113+
bar_execution: Option<bool>,
114+
bar_adaptive_high_low_ordering: Option<bool>,
115+
trade_execution: Option<bool>,
111116
) {
112-
todo!("implement add_venue")
117+
let default_leverage: Decimal = default_leverage.unwrap_or_else(|| {
118+
if account_type == AccountType::Margin {
119+
Decimal::from(10)
120+
} else {
121+
Decimal::from(0)
122+
}
123+
});
124+
125+
let exchange = SimulatedExchange::new(
126+
venue,
127+
oms_type,
128+
account_type,
129+
starting_balances,
130+
base_currency,
131+
default_leverage,
132+
leverages,
133+
modules,
134+
self.kernel.cache.clone(),
135+
self.kernel.clock.clone(),
136+
fill_model,
137+
fee_model,
138+
book_type,
139+
latency_model,
140+
frozen_account,
141+
bar_execution,
142+
reject_stop_orders,
143+
support_gtd_orders,
144+
support_contingent_orders,
145+
use_position_ids,
146+
use_random_ids,
147+
use_reduce_only,
148+
use_message_queue,
149+
)
150+
.unwrap();
151+
let exchange = Rc::new(RefCell::new(exchange));
152+
self.venues.insert(venue, exchange.clone());
153+
154+
let account_id = AccountId::from(format!("{}-001", venue).as_str());
155+
let exec_client = BacktestExecutionClient::new(
156+
self.kernel.config.trader_id,
157+
account_id,
158+
exchange.clone(),
159+
self.kernel.cache.clone(),
160+
self.kernel.clock.clone(),
161+
routing,
162+
frozen_account,
163+
);
164+
let exec_client = Rc::new(exec_client);
165+
166+
exchange.borrow_mut().register_client(exec_client.clone());
167+
self.kernel
168+
.exec_engine
169+
.register_client(exec_client)
170+
.unwrap();
171+
log::info!("Adding exchange {} to engine", venue);
113172
}
114173

115174
pub fn change_fill_model(&mut self, venue: Venue, fill_model: FillModel) {

0 commit comments

Comments
 (0)