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 factories::{ClientConfig, DataClientFactory, ExecutionClientFactory},
25};
26use nautilus_live::ExecutionClientCore;
27use nautilus_model::{
28 enums::{AccountType, OmsType},
29 identifiers::{AccountId, ClientId, TraderId},
30};
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)]
54#[cfg_attr(
55 feature = "python",
56 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.bitmex")
57)]
58pub struct BitmexExecFactoryConfig {
59 pub trader_id: TraderId,
61 pub account_id: AccountId,
63 pub config: BitmexExecClientConfig,
65}
66
67impl BitmexExecFactoryConfig {
68 #[must_use]
73 pub fn new(trader_id: TraderId, config: BitmexExecClientConfig) -> Self {
74 Self {
75 trader_id,
76 account_id: AccountId::from("BITMEX-001"),
77 config,
78 }
79 }
80}
81
82impl ClientConfig for BitmexExecFactoryConfig {
83 fn as_any(&self) -> &dyn Any {
84 self
85 }
86}
87
88#[derive(Debug, Clone)]
90#[cfg_attr(
91 feature = "python",
92 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.bitmex", from_py_object)
93)]
94#[cfg_attr(
95 feature = "python",
96 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.bitmex")
97)]
98pub struct BitmexDataClientFactory;
99
100impl BitmexDataClientFactory {
101 #[must_use]
103 pub const fn new() -> Self {
104 Self
105 }
106}
107
108impl Default for BitmexDataClientFactory {
109 fn default() -> Self {
110 Self::new()
111 }
112}
113
114impl DataClientFactory for BitmexDataClientFactory {
115 fn create(
116 &self,
117 name: &str,
118 config: &dyn ClientConfig,
119 _cache: Rc<RefCell<Cache>>,
120 _clock: Rc<RefCell<dyn Clock>>,
121 ) -> anyhow::Result<Box<dyn DataClient>> {
122 let bitmex_config = config
123 .as_any()
124 .downcast_ref::<BitmexDataClientConfig>()
125 .ok_or_else(|| {
126 anyhow::anyhow!(
127 "Invalid config type for BitmexDataClientFactory. Expected BitmexDataClientConfig, was {config:?}",
128 )
129 })?
130 .clone();
131
132 let client_id = ClientId::from(name);
133 let client = BitmexDataClient::new(client_id, bitmex_config)?;
134 Ok(Box::new(client))
135 }
136
137 fn name(&self) -> &'static str {
138 "BITMEX"
139 }
140
141 fn config_type(&self) -> &'static str {
142 "BitmexDataClientConfig"
143 }
144}
145
146#[derive(Debug, Clone)]
148#[cfg_attr(
149 feature = "python",
150 pyo3::pyclass(module = "nautilus_trader.core.nautilus_pyo3.bitmex", from_py_object)
151)]
152#[cfg_attr(
153 feature = "python",
154 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.bitmex")
155)]
156pub struct BitmexExecutionClientFactory;
157
158impl BitmexExecutionClientFactory {
159 #[must_use]
161 pub const fn new() -> Self {
162 Self
163 }
164}
165
166impl Default for BitmexExecutionClientFactory {
167 fn default() -> Self {
168 Self::new()
169 }
170}
171
172impl ExecutionClientFactory for BitmexExecutionClientFactory {
173 fn create(
174 &self,
175 name: &str,
176 config: &dyn ClientConfig,
177 cache: Rc<RefCell<Cache>>,
178 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
179 let factory_config = config
180 .as_any()
181 .downcast_ref::<BitmexExecFactoryConfig>()
182 .ok_or_else(|| {
183 anyhow::anyhow!(
184 "Invalid config type for BitmexExecutionClientFactory. Expected BitmexExecFactoryConfig, was {config:?}",
185 )
186 })?
187 .clone();
188
189 let mut bitmex_config = factory_config.config;
190 bitmex_config.account_id = Some(factory_config.account_id);
191
192 let core = ExecutionClientCore::new(
193 factory_config.trader_id,
194 ClientId::from(name),
195 *BITMEX_VENUE,
196 OmsType::Netting,
197 factory_config.account_id,
198 AccountType::Margin,
199 None, cache,
201 );
202
203 let client = BitmexExecutionClient::new(core, bitmex_config)?;
204 Ok(Box::new(client))
205 }
206
207 fn name(&self) -> &'static str {
208 "BITMEX"
209 }
210
211 fn config_type(&self) -> &'static str {
212 "BitmexExecFactoryConfig"
213 }
214}