nautilus_testkit/testers/exec/
config.rs1use std::num::NonZeroUsize;
17
18use nautilus_core::Params;
19use nautilus_model::{
20 enums::{BookType, OrderType, TimeInForce, TrailingOffsetType, TriggerType},
21 identifiers::{ClientId, InstrumentId, StrategyId},
22 types::Quantity,
23};
24use nautilus_trading::strategy::StrategyConfig;
25use rust_decimal::Decimal;
26use serde::{Deserialize, Serialize};
27
28#[derive(Debug, Clone, Deserialize, Serialize, bon::Builder)]
30#[serde(default, deny_unknown_fields)]
31pub struct ExecTesterConfig {
32 #[builder(default)]
34 pub base: StrategyConfig,
35 #[builder(default = InstrumentId::from("BTCUSDT-PERP.BINANCE"))]
37 pub instrument_id: InstrumentId,
38 #[builder(default = Quantity::from("0.001"))]
40 pub order_qty: Quantity,
41 pub order_display_qty: Option<Quantity>,
43 pub order_expire_time_delta_mins: Option<u64>,
45 pub order_params: Option<Params>,
47 pub client_id: Option<ClientId>,
49 #[builder(default = false)]
51 pub subscribe_book: bool,
52 #[builder(default = true)]
54 pub subscribe_quotes: bool,
55 #[builder(default = true)]
57 pub subscribe_trades: bool,
58 #[builder(default = BookType::L2_MBP)]
60 pub book_type: BookType,
61 pub book_depth: Option<NonZeroUsize>,
63 #[builder(default = NonZeroUsize::new(1000).unwrap())]
65 pub book_interval_ms: NonZeroUsize,
66 #[builder(default = 10)]
68 pub book_levels_to_print: usize,
69 pub open_position_on_start_qty: Option<Decimal>,
71 #[builder(default = TimeInForce::Gtc)]
73 pub open_position_time_in_force: TimeInForce,
74 #[builder(default = true)]
76 pub enable_limit_buys: bool,
77 #[builder(default = true)]
79 pub enable_limit_sells: bool,
80 #[builder(default = false)]
82 pub enable_stop_buys: bool,
83 #[builder(default = false)]
85 pub enable_stop_sells: bool,
86 #[builder(default = 500)]
88 pub tob_offset_ticks: u64,
89 pub limit_time_in_force: Option<TimeInForce>,
91 #[builder(default = OrderType::StopMarket)]
93 pub stop_order_type: OrderType,
94 #[builder(default = 100)]
96 pub stop_offset_ticks: u64,
97 pub stop_limit_offset_ticks: Option<u64>,
99 #[builder(default = TriggerType::Default)]
101 pub stop_trigger_type: TriggerType,
102 pub stop_time_in_force: Option<TimeInForce>,
104 pub trailing_offset: Option<Decimal>,
106 #[builder(default = TrailingOffsetType::BasisPoints)]
108 pub trailing_offset_type: TrailingOffsetType,
109 #[builder(default = false)]
111 pub enable_brackets: bool,
112 #[builder(default = false)]
114 pub batch_submit_limit_pair: bool,
115 #[builder(default = OrderType::Limit)]
117 pub bracket_entry_order_type: OrderType,
118 #[builder(default = 500)]
120 pub bracket_offset_ticks: u64,
121 #[builder(default = false)]
123 pub modify_orders_to_maintain_tob_offset: bool,
124 #[builder(default = false)]
126 pub modify_stop_orders_to_maintain_offset: bool,
127 #[builder(default = false)]
129 pub cancel_replace_orders_to_maintain_tob_offset: bool,
130 #[builder(default = false)]
132 pub cancel_replace_stop_orders_to_maintain_offset: bool,
133 #[builder(default = false)]
135 pub use_post_only: bool,
136 #[builder(default = false)]
141 pub limit_aggressive: bool,
142 #[builder(default = false)]
144 pub use_quote_quantity: bool,
145 pub emulation_trigger: Option<TriggerType>,
147 #[builder(default = true)]
149 pub cancel_orders_on_stop: bool,
150 #[builder(default = true)]
152 pub close_positions_on_stop: bool,
153 pub close_positions_time_in_force: Option<TimeInForce>,
155 #[builder(default = true)]
157 pub reduce_only_on_stop: bool,
158 #[builder(default = false)]
160 pub use_individual_cancels_on_stop: bool,
161 #[builder(default = false)]
163 pub use_batch_cancel_on_stop: bool,
164 #[builder(default = false)]
166 pub dry_run: bool,
167 #[builder(default = true)]
169 pub log_data: bool,
170 #[builder(default = false)]
172 pub test_reject_post_only: bool,
173 #[builder(default = false)]
175 pub test_reject_reduce_only: bool,
176 #[builder(default = false)]
183 pub test_modify_rejected: bool,
184 #[builder(default = true)]
186 pub can_unsubscribe: bool,
187}
188
189impl ExecTesterConfig {
190 #[must_use]
196 pub fn new(
197 strategy_id: StrategyId,
198 instrument_id: InstrumentId,
199 client_id: ClientId,
200 order_qty: Quantity,
201 ) -> Self {
202 Self {
203 base: StrategyConfig {
204 strategy_id: Some(strategy_id),
205 order_id_tag: None,
206 ..Default::default()
207 },
208 instrument_id,
209 order_qty,
210 order_display_qty: None,
211 order_expire_time_delta_mins: None,
212 order_params: None,
213 client_id: Some(client_id),
214 subscribe_quotes: true,
215 subscribe_trades: true,
216 subscribe_book: false,
217 book_type: BookType::L2_MBP,
218 book_depth: None,
219 book_interval_ms: NonZeroUsize::new(1000).unwrap(),
220 book_levels_to_print: 10,
221 open_position_on_start_qty: None,
222 open_position_time_in_force: TimeInForce::Gtc,
223 enable_limit_buys: true,
224 enable_limit_sells: true,
225 enable_stop_buys: false,
226 enable_stop_sells: false,
227 tob_offset_ticks: 500,
228 limit_time_in_force: None,
229 stop_order_type: OrderType::StopMarket,
230 stop_offset_ticks: 100,
231 stop_limit_offset_ticks: None,
232 stop_trigger_type: TriggerType::Default,
233 stop_time_in_force: None,
234 trailing_offset: None,
235 trailing_offset_type: TrailingOffsetType::BasisPoints,
236 enable_brackets: false,
237 batch_submit_limit_pair: false,
238 bracket_entry_order_type: OrderType::Limit,
239 bracket_offset_ticks: 500,
240 modify_orders_to_maintain_tob_offset: false,
241 modify_stop_orders_to_maintain_offset: false,
242 cancel_replace_orders_to_maintain_tob_offset: false,
243 cancel_replace_stop_orders_to_maintain_offset: false,
244 use_post_only: false,
245 limit_aggressive: false,
246 use_quote_quantity: false,
247 emulation_trigger: None,
248 cancel_orders_on_stop: true,
249 close_positions_on_stop: true,
250 close_positions_time_in_force: None,
251 reduce_only_on_stop: true,
252 use_individual_cancels_on_stop: false,
253 use_batch_cancel_on_stop: false,
254 dry_run: false,
255 log_data: true,
256 test_reject_post_only: false,
257 test_reject_reduce_only: false,
258 test_modify_rejected: false,
259 can_unsubscribe: true,
260 }
261 }
262}
263
264impl Default for ExecTesterConfig {
265 fn default() -> Self {
266 Self::builder().build()
267 }
268}