nautilus_bitmex/
factories.rs1use std::{any::Any, cell::RefCell, rc::Rc};
19
20use nautilus_common::{
21 cache::CacheView,
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, BITMEX_VENUE},
34 config::{BitmexDataClientConfig, BitmexExecutionClientConfig},
35 data::BitmexDataClient,
36 execution::BitmexExecutionClient,
37};
38
39impl ClientConfig for BitmexDataClientConfig {
40 fn as_any(&self) -> &dyn Any {
41 self
42 }
43}
44
45impl ClientConfig for BitmexExecutionClientConfig {
46 fn as_any(&self) -> &dyn Any {
47 self
48 }
49}
50
51#[derive(Debug, Clone)]
53#[cfg_attr(
54 feature = "python",
55 pyo3::pyclass(module = "nautilus_trader.adapters.bitmex", from_py_object)
56)]
57#[cfg_attr(
58 feature = "python",
59 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.adapters.bitmex")
60)]
61pub struct BitmexDataClientFactory;
62
63impl BitmexDataClientFactory {
64 #[must_use]
66 pub const fn new() -> Self {
67 Self
68 }
69}
70
71impl Default for BitmexDataClientFactory {
72 fn default() -> Self {
73 Self::new()
74 }
75}
76
77impl DataClientFactory for BitmexDataClientFactory {
78 fn create(
79 &self,
80 name: &str,
81 config: &dyn ClientConfig,
82 _cache: CacheView,
83 _clock: Rc<RefCell<dyn Clock>>,
84 ) -> anyhow::Result<Box<dyn DataClient>> {
85 let bitmex_config = config
86 .as_any()
87 .downcast_ref::<BitmexDataClientConfig>()
88 .ok_or_else(|| {
89 anyhow::anyhow!(
90 "Invalid config type for BitmexDataClientFactory. Expected BitmexDataClientConfig, was {config:?}",
91 )
92 })?
93 .clone();
94
95 let client_id = ClientId::from(name);
96 let client = BitmexDataClient::new(client_id, bitmex_config)?;
97 Ok(Box::new(client))
98 }
99
100 fn name(&self) -> &'static str {
101 BITMEX
102 }
103
104 fn config_type(&self) -> &'static str {
105 "BitmexDataClientConfig"
106 }
107}
108
109#[derive(Debug, Clone)]
111#[cfg_attr(
112 feature = "python",
113 pyo3::pyclass(module = "nautilus_trader.adapters.bitmex", from_py_object)
114)]
115#[cfg_attr(
116 feature = "python",
117 pyo3_stub_gen::derive::gen_stub_pyclass(module = "nautilus_trader.adapters.bitmex")
118)]
119pub struct BitmexExecutionClientFactory;
120
121impl BitmexExecutionClientFactory {
122 #[must_use]
124 pub const fn new() -> Self {
125 Self
126 }
127}
128
129impl Default for BitmexExecutionClientFactory {
130 fn default() -> Self {
131 Self::new()
132 }
133}
134
135impl ExecutionClientFactory for BitmexExecutionClientFactory {
136 fn create(
137 &self,
138 trader_id: TraderId,
139 name: &str,
140 config: &dyn ClientConfig,
141 cache: CacheView,
142 _clock: Rc<RefCell<dyn Clock>>,
143 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
144 let mut bitmex_config = config
145 .as_any()
146 .downcast_ref::<BitmexExecutionClientConfig>()
147 .ok_or_else(|| {
148 anyhow::anyhow!(
149 "Invalid config type for BitmexExecutionClientFactory. Expected BitmexExecutionClientConfig, was {config:?}",
150 )
151 })?
152 .clone();
153
154 let account_id = bitmex_config
155 .account_id
156 .unwrap_or_else(|| AccountId::from("BITMEX-001"));
157 bitmex_config.account_id = Some(account_id);
158
159 let core = ExecutionClientCore::new(
160 trader_id,
161 ClientId::from(name),
162 *BITMEX_VENUE,
163 OmsType::Netting,
164 account_id,
165 AccountType::Margin,
166 None, cache,
168 );
169
170 let client = BitmexExecutionClient::new(core, bitmex_config)?;
171 Ok(Box::new(client))
172 }
173
174 fn name(&self) -> &'static str {
175 BITMEX
176 }
177
178 fn config_type(&self) -> &'static str {
179 "BitmexExecutionClientConfig"
180 }
181}