nautilus_deribit/
factories.rs1use std::{any::Any, cell::RefCell, rc::Rc};
19
20use nautilus_common::{cache::Cache, clock::Clock};
21use nautilus_data::client::DataClient;
22use nautilus_execution::client::{ExecutionClient, base::ExecutionClientCore};
23use nautilus_model::{
24 enums::{AccountType, OmsType},
25 identifiers::ClientId,
26};
27use nautilus_system::factories::{ClientConfig, DataClientFactory, ExecutionClientFactory};
28
29use crate::{
30 common::consts::DERIBIT_VENUE,
31 config::{DeribitDataClientConfig, DeribitExecClientConfig},
32 data::DeribitDataClient,
33 execution::DeribitExecutionClient,
34};
35
36impl ClientConfig for DeribitDataClientConfig {
37 fn as_any(&self) -> &dyn Any {
38 self
39 }
40}
41
42#[derive(Debug)]
44pub struct DeribitDataClientFactory;
45
46impl DeribitDataClientFactory {
47 #[must_use]
49 pub const fn new() -> Self {
50 Self
51 }
52}
53
54impl Default for DeribitDataClientFactory {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60impl DataClientFactory for DeribitDataClientFactory {
61 fn create(
62 &self,
63 name: &str,
64 config: &dyn ClientConfig,
65 _cache: Rc<RefCell<Cache>>,
66 _clock: Rc<RefCell<dyn Clock>>,
67 ) -> anyhow::Result<Box<dyn DataClient>> {
68 let deribit_config = config
69 .as_any()
70 .downcast_ref::<DeribitDataClientConfig>()
71 .ok_or_else(|| {
72 anyhow::anyhow!(
73 "Invalid config type for DeribitDataClientFactory. Expected DeribitDataClientConfig, was {config:?}",
74 )
75 })?
76 .clone();
77
78 let client_id = ClientId::from(name);
79 let client = DeribitDataClient::new(client_id, deribit_config)?;
80 Ok(Box::new(client))
81 }
82
83 fn name(&self) -> &'static str {
84 "DERIBIT"
85 }
86
87 fn config_type(&self) -> &'static str {
88 "DeribitDataClientConfig"
89 }
90}
91
92impl ClientConfig for DeribitExecClientConfig {
95 fn as_any(&self) -> &dyn Any {
96 self
97 }
98}
99
100#[derive(Debug)]
102pub struct DeribitExecutionClientFactory;
103
104impl DeribitExecutionClientFactory {
105 #[must_use]
107 pub const fn new() -> Self {
108 Self
109 }
110}
111
112impl Default for DeribitExecutionClientFactory {
113 fn default() -> Self {
114 Self::new()
115 }
116}
117
118impl ExecutionClientFactory for DeribitExecutionClientFactory {
119 fn create(
120 &self,
121 name: &str,
122 config: &dyn ClientConfig,
123 cache: Rc<RefCell<Cache>>,
124 clock: Rc<RefCell<dyn Clock>>,
125 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
126 let deribit_config = config
127 .as_any()
128 .downcast_ref::<DeribitExecClientConfig>()
129 .ok_or_else(|| {
130 anyhow::anyhow!(
131 "Invalid config type for DeribitExecutionClientFactory. Expected DeribitExecClientConfig, was {config:?}",
132 )
133 })?
134 .clone();
135
136 let oms_type = OmsType::Netting;
138 let account_type = AccountType::Margin;
139
140 let client_id = ClientId::from(name);
141 let core = ExecutionClientCore::new(
142 deribit_config.trader_id,
143 client_id,
144 *DERIBIT_VENUE,
145 oms_type,
146 deribit_config.account_id,
147 account_type,
148 None, clock,
150 cache,
151 );
152
153 let client = DeribitExecutionClient::new(core, deribit_config)?;
154 Ok(Box::new(client))
155 }
156
157 fn name(&self) -> &'static str {
158 "DERIBIT"
159 }
160
161 fn config_type(&self) -> &'static str {
162 "DeribitExecClientConfig"
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use std::{cell::RefCell, rc::Rc};
169
170 use nautilus_common::{
171 cache::Cache, clock::TestClock, live::runner::set_data_event_sender, messages::DataEvent,
172 };
173 use nautilus_system::factories::{ClientConfig, DataClientFactory};
174 use rstest::rstest;
175
176 use super::*;
177 use crate::http::models::DeribitInstrumentKind;
178
179 fn setup_test_env() {
180 let (sender, _receiver) = tokio::sync::mpsc::unbounded_channel::<DataEvent>();
182 set_data_event_sender(sender);
183 }
184
185 #[rstest]
186 fn test_deribit_data_client_factory_creation() {
187 let factory = DeribitDataClientFactory::new();
188 assert_eq!(factory.name(), "DERIBIT");
189 assert_eq!(factory.config_type(), "DeribitDataClientConfig");
190 }
191
192 #[rstest]
193 fn test_deribit_data_client_factory_default() {
194 let factory = DeribitDataClientFactory::new();
195 assert_eq!(factory.name(), "DERIBIT");
196 }
197
198 #[rstest]
199 fn test_deribit_data_client_config_implements_client_config() {
200 let config = DeribitDataClientConfig {
201 instrument_kinds: vec![DeribitInstrumentKind::Future],
202 ..Default::default()
203 };
204
205 let boxed_config: Box<dyn ClientConfig> = Box::new(config);
206 let downcasted = boxed_config
207 .as_any()
208 .downcast_ref::<DeribitDataClientConfig>();
209
210 assert!(downcasted.is_some());
211 }
212
213 #[rstest]
214 fn test_deribit_data_client_factory_creates_client() {
215 setup_test_env();
216
217 let factory = DeribitDataClientFactory::new();
218 let config = DeribitDataClientConfig {
219 instrument_kinds: vec![DeribitInstrumentKind::Future],
220 use_testnet: true,
221 ..Default::default()
222 };
223
224 let cache = Rc::new(RefCell::new(Cache::default()));
225 let clock = Rc::new(RefCell::new(TestClock::new()));
226
227 let result = factory.create("DERIBIT-TEST", &config, cache, clock);
228 assert!(result.is_ok());
229
230 let client = result.unwrap();
231 assert_eq!(client.client_id(), ClientId::from("DERIBIT-TEST"));
232 }
233}