nautilus_bitmex/
factories.rs1use std::{any::Any, 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::{AccountId, ClientId, TraderId},
29};
30use nautilus_system::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
31
32use crate::{
33 common::consts::BITMEX_VENUE,
34 config::{BitmexDataClientConfig, BitmexExecClientConfig},
35 data::BitmexDataClient,
36 execution::BitmexExecutionClient,
37};
38
39impl ClientConfig for BitmexDataClientConfig {
40 fn as_any(&self) -> &dyn Any {
41 self
42 }
43}
44
45#[derive(Clone, Debug)]
50#[cfg_attr(
51 feature = "python",
52 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.bitmex", from_py_object)
53)]
54pub struct BitmexExecFactoryConfig {
55 pub trader_id: TraderId,
57 pub account_id: AccountId,
59 pub config: BitmexExecClientConfig,
61}
62
63impl BitmexExecFactoryConfig {
64 #[must_use]
69 pub fn new(trader_id: TraderId, config: BitmexExecClientConfig) -> Self {
70 Self {
71 trader_id,
72 account_id: AccountId::from("BITMEX-001"),
73 config,
74 }
75 }
76}
77
78impl ClientConfig for BitmexExecFactoryConfig {
79 fn as_any(&self) -> &dyn Any {
80 self
81 }
82}
83
84#[derive(Debug, Clone)]
86#[cfg_attr(
87 feature = "python",
88 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.bitmex", from_py_object)
89)]
90pub struct BitmexDataClientFactory;
91
92impl BitmexDataClientFactory {
93 #[must_use]
95 pub const fn new() -> Self {
96 Self
97 }
98}
99
100impl Default for BitmexDataClientFactory {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106impl DataClientFactory for BitmexDataClientFactory {
107 fn create(
108 &self,
109 name: &str,
110 config: &dyn ClientConfig,
111 _cache: Rc<RefCell<Cache>>,
112 _clock: Rc<RefCell<dyn Clock>>,
113 ) -> anyhow::Result<Box<dyn DataClient>> {
114 let bitmex_config = config
115 .as_any()
116 .downcast_ref::<BitmexDataClientConfig>()
117 .ok_or_else(|| {
118 anyhow::anyhow!(
119 "Invalid config type for BitmexDataClientFactory. Expected BitmexDataClientConfig, was {config:?}",
120 )
121 })?
122 .clone();
123
124 let client_id = ClientId::from(name);
125 let client = BitmexDataClient::new(client_id, bitmex_config)?;
126 Ok(Box::new(client))
127 }
128
129 fn name(&self) -> &'static str {
130 "BITMEX"
131 }
132
133 fn config_type(&self) -> &'static str {
134 "BitmexDataClientConfig"
135 }
136}
137
138#[derive(Debug, Clone)]
140#[cfg_attr(
141 feature = "python",
142 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.bitmex", from_py_object)
143)]
144pub struct BitmexExecutionClientFactory;
145
146impl BitmexExecutionClientFactory {
147 #[must_use]
149 pub const fn new() -> Self {
150 Self
151 }
152}
153
154impl Default for BitmexExecutionClientFactory {
155 fn default() -> Self {
156 Self::new()
157 }
158}
159
160impl ExecutionClientFactory for BitmexExecutionClientFactory {
161 fn create(
162 &self,
163 name: &str,
164 config: &dyn ClientConfig,
165 cache: Rc<RefCell<Cache>>,
166 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
167 let factory_config = config
168 .as_any()
169 .downcast_ref::<BitmexExecFactoryConfig>()
170 .ok_or_else(|| {
171 anyhow::anyhow!(
172 "Invalid config type for BitmexExecutionClientFactory. Expected BitmexExecFactoryConfig, was {config:?}",
173 )
174 })?
175 .clone();
176
177 let mut bitmex_config = factory_config.config;
178 bitmex_config.account_id = Some(factory_config.account_id);
179
180 let core = ExecutionClientCore::new(
181 factory_config.trader_id,
182 ClientId::from(name),
183 *BITMEX_VENUE,
184 OmsType::Netting,
185 factory_config.account_id,
186 AccountType::Margin,
187 None, cache,
189 );
190
191 let client = BitmexExecutionClient::new(core, bitmex_config)?;
192 Ok(Box::new(client))
193 }
194
195 fn name(&self) -> &'static str {
196 "BITMEX"
197 }
198
199 fn config_type(&self) -> &'static str {
200 "BitmexExecFactoryConfig"
201 }
202}