nautilus_testkit/testers/data/config.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::num::NonZeroUsize;
17
18use nautilus_common::actor::DataActorConfig;
19use nautilus_core::Params;
20use nautilus_model::{
21 data::bar::BarType,
22 enums::BookType,
23 identifiers::{ClientId, InstrumentId},
24};
25use serde::{Deserialize, Serialize};
26
27/// Configuration for the data tester actor.
28#[derive(Debug, Clone, Deserialize, Serialize, bon::Builder)]
29#[serde(default, deny_unknown_fields)]
30pub struct DataTesterConfig {
31 /// Base data actor configuration.
32 #[builder(default)]
33 pub base: DataActorConfig,
34 /// Instrument IDs to subscribe to.
35 #[builder(default)]
36 pub instrument_ids: Vec<InstrumentId>,
37 /// Client ID to use for subscriptions.
38 pub client_id: Option<ClientId>,
39 /// Bar types to subscribe to.
40 pub bar_types: Option<Vec<BarType>>,
41 /// Whether to subscribe to order book deltas.
42 #[builder(default = false)]
43 pub subscribe_book_deltas: bool,
44 /// Whether to subscribe to order book depth snapshots.
45 #[builder(default = false)]
46 pub subscribe_book_depth: bool,
47 /// Whether to subscribe to order book at interval.
48 #[builder(default = false)]
49 pub subscribe_book_at_interval: bool,
50 /// Whether to subscribe to quotes.
51 #[builder(default = false)]
52 pub subscribe_quotes: bool,
53 /// Whether to subscribe to trades.
54 #[builder(default = false)]
55 pub subscribe_trades: bool,
56 /// Whether to subscribe to mark prices.
57 #[builder(default = false)]
58 pub subscribe_mark_prices: bool,
59 /// Whether to subscribe to index prices.
60 #[builder(default = false)]
61 pub subscribe_index_prices: bool,
62 /// Whether to subscribe to funding rates.
63 #[builder(default = false)]
64 pub subscribe_funding_rates: bool,
65 /// Whether to subscribe to bars.
66 #[builder(default = false)]
67 pub subscribe_bars: bool,
68 /// Whether to subscribe to instrument updates.
69 #[builder(default = false)]
70 pub subscribe_instrument: bool,
71 /// Whether to subscribe to instrument status.
72 #[builder(default = false)]
73 pub subscribe_instrument_status: bool,
74 /// Whether to subscribe to instrument close.
75 #[builder(default = false)]
76 pub subscribe_instrument_close: bool,
77 /// Whether to subscribe to option greeks.
78 #[builder(default = false)]
79 pub subscribe_option_greeks: bool,
80 /// Optional parameters passed to all subscribe calls.
81 pub subscribe_params: Option<Params>,
82 /// Optional parameters passed to all request calls.
83 pub request_params: Option<Params>,
84 /// Whether unsubscribe is supported on stop.
85 #[builder(default = true)]
86 pub can_unsubscribe: bool,
87 /// Whether to request instruments on start.
88 #[builder(default = false)]
89 pub request_instruments: bool,
90 // TODO: Support request_quotes when historical data requests are available
91 /// Whether to request historical quotes (not yet implemented).
92 #[builder(default = false)]
93 pub request_quotes: bool,
94 // TODO: Support request_trades when historical data requests are available
95 /// Whether to request historical trades (not yet implemented).
96 #[builder(default = false)]
97 pub request_trades: bool,
98 /// Whether to request historical bars.
99 #[builder(default = false)]
100 pub request_bars: bool,
101 /// Whether to request order book snapshots.
102 #[builder(default = false)]
103 pub request_book_snapshot: bool,
104 // TODO: Support request_book_deltas when Rust data engine has RequestBookDeltas
105 /// Whether to request historical order book deltas (not yet implemented).
106 #[builder(default = false)]
107 pub request_book_deltas: bool,
108 /// Whether to request historical funding rates.
109 #[builder(default = false)]
110 pub request_funding_rates: bool,
111 // TODO: Support requests_start_delta when we implement historical data requests
112 /// Book type for order book subscriptions.
113 #[builder(default = BookType::L2_MBP)]
114 pub book_type: BookType,
115 /// Order book depth for subscriptions.
116 pub book_depth: Option<NonZeroUsize>,
117 // TODO: Support book_group_size when order book grouping is implemented
118 /// Order book interval in milliseconds for at_interval subscriptions.
119 #[builder(default = NonZeroUsize::new(1000).unwrap())]
120 pub book_interval_ms: NonZeroUsize,
121 /// Number of order book levels to print when logging.
122 #[builder(default = 10)]
123 pub book_levels_to_print: usize,
124 /// Whether to manage local order book from deltas.
125 #[builder(default = true)]
126 pub manage_book: bool,
127 /// Whether to log received data.
128 #[builder(default = true)]
129 pub log_data: bool,
130 /// Stats logging interval in seconds (0 to disable).
131 #[builder(default = 5)]
132 pub stats_interval_secs: u64,
133}
134
135impl DataTesterConfig {
136 /// Creates a new [`DataTesterConfig`] instance with minimal settings.
137 ///
138 /// # Panics
139 ///
140 /// Panics if `NonZeroUsize::new(1000)` fails (which should never happen).
141 #[must_use]
142 pub fn new(client_id: ClientId, instrument_ids: Vec<InstrumentId>) -> Self {
143 Self {
144 base: DataActorConfig::default(),
145 instrument_ids,
146 client_id: Some(client_id),
147 bar_types: None,
148 subscribe_book_deltas: false,
149 subscribe_book_depth: false,
150 subscribe_book_at_interval: false,
151 subscribe_quotes: false,
152 subscribe_trades: false,
153 subscribe_mark_prices: false,
154 subscribe_index_prices: false,
155 subscribe_funding_rates: false,
156 subscribe_bars: false,
157
158 subscribe_instrument: false,
159 subscribe_instrument_status: false,
160 subscribe_instrument_close: false,
161 subscribe_option_greeks: false,
162 subscribe_params: None,
163 request_params: None,
164 can_unsubscribe: true,
165 request_instruments: false,
166 request_quotes: false,
167 request_trades: false,
168 request_bars: false,
169 request_book_snapshot: false,
170 request_book_deltas: false,
171 request_funding_rates: false,
172 book_type: BookType::L2_MBP,
173 book_depth: None,
174 book_interval_ms: NonZeroUsize::new(1000).unwrap(),
175 book_levels_to_print: 10,
176 manage_book: true,
177 log_data: true,
178 stats_interval_secs: 5,
179 }
180 }
181}
182
183impl Default for DataTesterConfig {
184 fn default() -> Self {
185 Self::builder().build()
186 }
187}