nautilus_binance/
factories.rs1use std::{cell::RefCell, rc::Rc};
19
20use nautilus_common::{
21 cache::Cache,
22 clients::{DataClient, ExecutionClient},
23 clock::Clock,
24};
25use nautilus_live::ExecutionClientCore;
26use nautilus_model::{
27 enums::{AccountType, OmsType},
28 identifiers::ClientId,
29};
30use nautilus_system::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
31
32use crate::{
33 common::consts::{BINANCE, BINANCE_VENUE},
34 config::{BinanceDataClientConfig, BinanceExecClientConfig},
35 data::BinanceSpotDataClient,
36 execution::BinanceSpotExecutionClient,
37};
38
39#[derive(Debug)]
41pub struct BinanceDataClientFactory;
42
43impl BinanceDataClientFactory {
44 #[must_use]
46 pub const fn new() -> Self {
47 Self
48 }
49}
50
51impl Default for BinanceDataClientFactory {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl DataClientFactory for BinanceDataClientFactory {
58 fn create(
59 &self,
60 name: &str,
61 config: &dyn ClientConfig,
62 _cache: Rc<RefCell<Cache>>,
63 _clock: Rc<RefCell<dyn Clock>>,
64 ) -> anyhow::Result<Box<dyn DataClient>> {
65 let binance_config = config
66 .as_any()
67 .downcast_ref::<BinanceDataClientConfig>()
68 .ok_or_else(|| {
69 anyhow::anyhow!(
70 "Invalid config type for BinanceDataClientFactory. Expected BinanceDataClientConfig, was {config:?}",
71 )
72 })?
73 .clone();
74
75 let client_id = ClientId::from(name);
76 let client = BinanceSpotDataClient::new(client_id, binance_config)?;
77 Ok(Box::new(client))
78 }
79
80 fn name(&self) -> &'static str {
81 BINANCE
82 }
83
84 fn config_type(&self) -> &'static str {
85 stringify!(BinanceDataClientConfig)
86 }
87}
88
89#[derive(Debug)]
91pub struct BinanceExecutionClientFactory;
92
93impl BinanceExecutionClientFactory {
94 #[must_use]
96 pub const fn new() -> Self {
97 Self
98 }
99}
100
101impl Default for BinanceExecutionClientFactory {
102 fn default() -> Self {
103 Self::new()
104 }
105}
106
107impl ExecutionClientFactory for BinanceExecutionClientFactory {
108 fn create(
109 &self,
110 name: &str,
111 config: &dyn ClientConfig,
112 cache: Rc<RefCell<Cache>>,
113 clock: Rc<RefCell<dyn Clock>>,
114 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
115 let binance_config = config
116 .as_any()
117 .downcast_ref::<BinanceExecClientConfig>()
118 .ok_or_else(|| {
119 anyhow::anyhow!(
120 "Invalid config type for BinanceExecutionClientFactory. Expected BinanceExecClientConfig, was {config:?}",
121 )
122 })?
123 .clone();
124
125 let account_type = AccountType::Cash;
127 let oms_type = OmsType::Hedging;
128
129 let core = ExecutionClientCore::new(
130 binance_config.trader_id,
131 ClientId::from(name),
132 *BINANCE_VENUE,
133 oms_type,
134 binance_config.account_id,
135 account_type,
136 None, clock,
138 cache,
139 );
140
141 let client = BinanceSpotExecutionClient::new(core, binance_config)?;
142
143 Ok(Box::new(client))
144 }
145
146 fn name(&self) -> &'static str {
147 BINANCE
148 }
149
150 fn config_type(&self) -> &'static str {
151 stringify!(BinanceExecClientConfig)
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use nautilus_system::factories::DataClientFactory;
158 use rstest::rstest;
159
160 use super::*;
161
162 #[rstest]
163 fn test_binance_data_client_factory_creation() {
164 let factory = BinanceDataClientFactory::new();
165 assert_eq!(factory.name(), "BINANCE");
166 assert_eq!(factory.config_type(), "BinanceDataClientConfig");
167 }
168
169 #[rstest]
170 fn test_binance_data_client_factory_default() {
171 let factory = BinanceDataClientFactory;
172 assert_eq!(factory.name(), "BINANCE");
173 }
174}