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 {
98 fn as_any(&self) -> &dyn Any {
99 self
100 }
101}
102
103#[derive(Debug)]
105pub struct DeribitExecutionClientFactory;
106
107impl DeribitExecutionClientFactory {
108 #[must_use]
110 pub const fn new() -> Self {
111 Self
112 }
113}
114
115impl Default for DeribitExecutionClientFactory {
116 fn default() -> Self {
117 Self::new()
118 }
119}
120
121impl ExecutionClientFactory for DeribitExecutionClientFactory {
122 fn create(
123 &self,
124 name: &str,
125 config: &dyn ClientConfig,
126 cache: Rc<RefCell<Cache>>,
127 clock: Rc<RefCell<dyn Clock>>,
128 ) -> anyhow::Result<Box<dyn ExecutionClient>> {
129 let deribit_config = config
130 .as_any()
131 .downcast_ref::<DeribitExecClientConfig>()
132 .ok_or_else(|| {
133 anyhow::anyhow!(
134 "Invalid config type for DeribitExecutionClientFactory. Expected DeribitExecClientConfig, was {config:?}",
135 )
136 })?
137 .clone();
138
139 let oms_type = OmsType::Netting;
141 let account_type = AccountType::Margin;
142
143 let client_id = ClientId::from(name);
144 let core = ExecutionClientCore::new(
145 deribit_config.trader_id,
146 client_id,
147 *DERIBIT_VENUE,
148 oms_type,
149 deribit_config.account_id,
150 account_type,
151 None, clock,
153 cache,
154 );
155
156 let client = DeribitExecutionClient::new(core, deribit_config)?;
157 Ok(Box::new(client))
158 }
159
160 fn name(&self) -> &'static str {
161 "DERIBIT"
162 }
163
164 fn config_type(&self) -> &'static str {
165 "DeribitExecClientConfig"
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use std::{cell::RefCell, rc::Rc};
172
173 use nautilus_common::{
174 cache::Cache, clock::TestClock, live::runner::set_data_event_sender, messages::DataEvent,
175 };
176 use nautilus_system::factories::{ClientConfig, DataClientFactory};
177 use rstest::rstest;
178
179 use super::*;
180 use crate::http::models::DeribitInstrumentKind;
181
182 fn setup_test_env() {
183 let (sender, _receiver) = tokio::sync::mpsc::unbounded_channel::<DataEvent>();
185 set_data_event_sender(sender);
186 }
187
188 #[rstest]
189 fn test_deribit_data_client_factory_creation() {
190 let factory = DeribitDataClientFactory::new();
191 assert_eq!(factory.name(), "DERIBIT");
192 assert_eq!(factory.config_type(), "DeribitDataClientConfig");
193 }
194
195 #[rstest]
196 fn test_deribit_data_client_factory_default() {
197 let factory = DeribitDataClientFactory::new();
198 assert_eq!(factory.name(), "DERIBIT");
199 }
200
201 #[rstest]
202 fn test_deribit_data_client_config_implements_client_config() {
203 let config = DeribitDataClientConfig {
204 instrument_kinds: vec![DeribitInstrumentKind::Future],
205 ..Default::default()
206 };
207
208 let boxed_config: Box<dyn ClientConfig> = Box::new(config);
209 let downcasted = boxed_config
210 .as_any()
211 .downcast_ref::<DeribitDataClientConfig>();
212
213 assert!(downcasted.is_some());
214 }
215
216 #[rstest]
217 fn test_deribit_data_client_factory_creates_client() {
218 setup_test_env();
219
220 let factory = DeribitDataClientFactory::new();
221 let config = DeribitDataClientConfig {
222 instrument_kinds: vec![DeribitInstrumentKind::Future],
223 use_testnet: true,
224 ..Default::default()
225 };
226
227 let cache = Rc::new(RefCell::new(Cache::default()));
228 let clock = Rc::new(RefCell::new(TestClock::new()));
229
230 let result = factory.create("DERIBIT-TEST", &config, cache, clock);
231 assert!(result.is_ok());
232
233 let client = result.unwrap();
234 assert_eq!(client.client_id(), ClientId::from("DERIBIT-TEST"));
235 }
236}