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 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
143 let mut bitmex_config = config
144 .as_any()
145 .downcast_ref::<BitmexExecutionClientConfig>()
146 .ok_or_else(|| {
147 anyhow::anyhow!(
148 "Invalid config type for BitmexExecutionClientFactory. Expected BitmexExecutionClientConfig, was {config:?}",
149 )
150 })?
151 .clone();
152
153 let account_id = bitmex_config
154 .account_id
155 .unwrap_or_else(|| AccountId::from("BITMEX-001"));
156 bitmex_config.account_id = Some(account_id);
157
158 let core = ExecutionClientCore::new(
159 trader_id,
160 ClientId::from(name),
161 *BITMEX_VENUE,
162 OmsType::Netting,
163 account_id,
164 AccountType::Margin,
165 None, cache,
167 );
168
169 let client = BitmexExecutionClient::new(core, bitmex_config)?;
170 Ok(Box::new(client))
171 }
172
173 fn name(&self) -> &'static str {
174 BITMEX
175 }
176
177 fn config_type(&self) -> &'static str {
178 "BitmexExecutionClientConfig"
179 }
180}