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