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;
26
27#[derive(Debug, Clone, bon::Builder)]
29pub struct ExecTesterConfig {
30 #[builder(default)]
32 pub base: StrategyConfig,
33 #[builder(default = InstrumentId::from("BTCUSDT-PERP.BINANCE"))]
35 pub instrument_id: InstrumentId,
36 #[builder(default = Quantity::from("0.001"))]
38 pub order_qty: Quantity,
39 pub order_display_qty: Option<Quantity>,
41 pub order_expire_time_delta_mins: Option<u64>,
43 pub order_params: Option<Params>,
45 pub client_id: Option<ClientId>,
47 #[builder(default = false)]
49 pub subscribe_book: bool,
50 #[builder(default = true)]
52 pub subscribe_quotes: bool,
53 #[builder(default = true)]
55 pub subscribe_trades: bool,
56 #[builder(default = BookType::L2_MBP)]
58 pub book_type: BookType,
59 pub book_depth: Option<NonZeroUsize>,
61 #[builder(default = NonZeroUsize::new(1000).unwrap())]
63 pub book_interval_ms: NonZeroUsize,
64 #[builder(default = 10)]
66 pub book_levels_to_print: usize,
67 pub open_position_on_start_qty: Option<Decimal>,
69 #[builder(default = TimeInForce::Gtc)]
71 pub open_position_time_in_force: TimeInForce,
72 #[builder(default = true)]
74 pub enable_limit_buys: bool,
75 #[builder(default = true)]
77 pub enable_limit_sells: bool,
78 #[builder(default = false)]
80 pub enable_stop_buys: bool,
81 #[builder(default = false)]
83 pub enable_stop_sells: bool,
84 #[builder(default = 500)]
86 pub tob_offset_ticks: u64,
87 pub limit_time_in_force: Option<TimeInForce>,
89 #[builder(default = OrderType::StopMarket)]
91 pub stop_order_type: OrderType,
92 #[builder(default = 100)]
94 pub stop_offset_ticks: u64,
95 pub stop_limit_offset_ticks: Option<u64>,
97 #[builder(default = TriggerType::Default)]
99 pub stop_trigger_type: TriggerType,
100 pub stop_time_in_force: Option<TimeInForce>,
102 pub trailing_offset: Option<Decimal>,
104 #[builder(default = TrailingOffsetType::BasisPoints)]
106 pub trailing_offset_type: TrailingOffsetType,
107 #[builder(default = false)]
109 pub enable_brackets: bool,
110 #[builder(default = false)]
112 pub batch_submit_limit_pair: bool,
113 #[builder(default = OrderType::Limit)]
115 pub bracket_entry_order_type: OrderType,
116 #[builder(default = 500)]
118 pub bracket_offset_ticks: u64,
119 #[builder(default = false)]
121 pub modify_orders_to_maintain_tob_offset: bool,
122 #[builder(default = false)]
124 pub modify_stop_orders_to_maintain_offset: bool,
125 #[builder(default = false)]
127 pub cancel_replace_orders_to_maintain_tob_offset: bool,
128 #[builder(default = false)]
130 pub cancel_replace_stop_orders_to_maintain_offset: bool,
131 #[builder(default = false)]
133 pub use_post_only: bool,
134 #[builder(default = false)]
136 pub use_quote_quantity: bool,
137 pub emulation_trigger: Option<TriggerType>,
139 #[builder(default = true)]
141 pub cancel_orders_on_stop: bool,
142 #[builder(default = true)]
144 pub close_positions_on_stop: bool,
145 pub close_positions_time_in_force: Option<TimeInForce>,
147 #[builder(default = true)]
149 pub reduce_only_on_stop: bool,
150 #[builder(default = false)]
152 pub use_individual_cancels_on_stop: bool,
153 #[builder(default = false)]
155 pub use_batch_cancel_on_stop: bool,
156 #[builder(default = false)]
158 pub dry_run: bool,
159 #[builder(default = true)]
161 pub log_data: bool,
162 #[builder(default = false)]
164 pub test_reject_post_only: bool,
165 #[builder(default = false)]
167 pub test_reject_reduce_only: bool,
168 #[builder(default = true)]
170 pub can_unsubscribe: bool,
171}
172
173impl ExecTesterConfig {
174 #[must_use]
180 pub fn new(
181 strategy_id: StrategyId,
182 instrument_id: InstrumentId,
183 client_id: ClientId,
184 order_qty: Quantity,
185 ) -> Self {
186 Self {
187 base: StrategyConfig {
188 strategy_id: Some(strategy_id),
189 order_id_tag: None,
190 ..Default::default()
191 },
192 instrument_id,
193 order_qty,
194 order_display_qty: None,
195 order_expire_time_delta_mins: None,
196 order_params: None,
197 client_id: Some(client_id),
198 subscribe_quotes: true,
199 subscribe_trades: true,
200 subscribe_book: false,
201 book_type: BookType::L2_MBP,
202 book_depth: None,
203 book_interval_ms: NonZeroUsize::new(1000).unwrap(),
204 book_levels_to_print: 10,
205 open_position_on_start_qty: None,
206 open_position_time_in_force: TimeInForce::Gtc,
207 enable_limit_buys: true,
208 enable_limit_sells: true,
209 enable_stop_buys: false,
210 enable_stop_sells: false,
211 tob_offset_ticks: 500,
212 limit_time_in_force: None,
213 stop_order_type: OrderType::StopMarket,
214 stop_offset_ticks: 100,
215 stop_limit_offset_ticks: None,
216 stop_trigger_type: TriggerType::Default,
217 stop_time_in_force: None,
218 trailing_offset: None,
219 trailing_offset_type: TrailingOffsetType::BasisPoints,
220 enable_brackets: false,
221 batch_submit_limit_pair: false,
222 bracket_entry_order_type: OrderType::Limit,
223 bracket_offset_ticks: 500,
224 modify_orders_to_maintain_tob_offset: false,
225 modify_stop_orders_to_maintain_offset: false,
226 cancel_replace_orders_to_maintain_tob_offset: false,
227 cancel_replace_stop_orders_to_maintain_offset: false,
228 use_post_only: false,
229 use_quote_quantity: false,
230 emulation_trigger: None,
231 cancel_orders_on_stop: true,
232 close_positions_on_stop: true,
233 close_positions_time_in_force: None,
234 reduce_only_on_stop: true,
235 use_individual_cancels_on_stop: false,
236 use_batch_cancel_on_stop: false,
237 dry_run: false,
238 log_data: true,
239 test_reject_post_only: false,
240 test_reject_reduce_only: false,
241 can_unsubscribe: true,
242 }
243 }
244}
245
246impl Default for ExecTesterConfig {
247 fn default() -> Self {
248 Self::builder().build()
249 }
250}