Skip to main content

nautilus_sandbox/python/
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
16//! Python bindings for sandbox configuration.
17
18use nautilus_model::{
19    enums::{AccountType, BookType, OmsType},
20    identifiers::{AccountId, TraderId, Venue},
21    types::{Currency, Money},
22};
23use pyo3::prelude::*;
24use rust_decimal::Decimal;
25
26use crate::config::SandboxExecutionClientConfig;
27
28#[pymethods]
29#[pyo3_stub_gen::derive::gen_stub_pymethods]
30impl SandboxExecutionClientConfig {
31    /// Configuration for `SandboxExecutionClient` instances.
32    #[new]
33    #[pyo3(signature = (venue, starting_balances, trader_id=None, account_id=None, base_currency=None, oms_type=None, account_type=None, default_leverage=None, book_type=None, frozen_account=false, bar_execution=true, trade_execution=true, reject_stop_orders=true, support_gtd_orders=true, support_contingent_orders=true, use_position_ids=true, use_random_ids=false, use_reduce_only=true))]
34    #[expect(clippy::too_many_arguments)]
35    fn py_new(
36        venue: Venue,
37        starting_balances: Vec<Money>,
38        trader_id: Option<TraderId>,
39        account_id: Option<AccountId>,
40        base_currency: Option<Currency>,
41        oms_type: Option<OmsType>,
42        account_type: Option<AccountType>,
43        default_leverage: Option<Decimal>,
44        book_type: Option<BookType>,
45        frozen_account: bool,
46        bar_execution: bool,
47        trade_execution: bool,
48        reject_stop_orders: bool,
49        support_gtd_orders: bool,
50        support_contingent_orders: bool,
51        use_position_ids: bool,
52        use_random_ids: bool,
53        use_reduce_only: bool,
54    ) -> Self {
55        // Generate default IDs from venue if not provided
56        let trader_id =
57            trader_id.unwrap_or_else(|| TraderId::from(format!("{venue}-001").as_str()));
58        let account_id =
59            account_id.unwrap_or_else(|| AccountId::from(format!("{venue}-SANDBOX-001").as_str()));
60
61        Self {
62            trader_id,
63            account_id,
64            venue,
65            starting_balances,
66            base_currency,
67            oms_type: oms_type.unwrap_or(OmsType::Netting),
68            account_type: account_type.unwrap_or(AccountType::Margin),
69            default_leverage: default_leverage.unwrap_or(Decimal::ONE),
70            leverages: ahash::AHashMap::new(),
71            book_type: book_type.unwrap_or(BookType::L1_MBP),
72            frozen_account,
73            bar_execution,
74            trade_execution,
75            reject_stop_orders,
76            support_gtd_orders,
77            support_contingent_orders,
78            use_position_ids,
79            use_random_ids,
80            use_reduce_only,
81        }
82    }
83
84    #[getter]
85    fn trader_id(&self) -> TraderId {
86        self.trader_id
87    }
88
89    #[getter]
90    fn account_id(&self) -> AccountId {
91        self.account_id
92    }
93
94    #[getter]
95    fn venue(&self) -> Venue {
96        self.venue
97    }
98
99    #[getter]
100    fn starting_balances(&self) -> Vec<Money> {
101        self.starting_balances.clone()
102    }
103
104    #[getter]
105    fn base_currency(&self) -> Option<Currency> {
106        self.base_currency
107    }
108
109    #[getter]
110    fn oms_type(&self) -> OmsType {
111        self.oms_type
112    }
113
114    #[getter]
115    fn account_type(&self) -> AccountType {
116        self.account_type
117    }
118
119    #[getter]
120    fn default_leverage(&self) -> Decimal {
121        self.default_leverage
122    }
123
124    #[getter]
125    fn book_type(&self) -> BookType {
126        self.book_type
127    }
128
129    #[getter]
130    fn frozen_account(&self) -> bool {
131        self.frozen_account
132    }
133
134    #[getter]
135    fn bar_execution(&self) -> bool {
136        self.bar_execution
137    }
138
139    #[getter]
140    fn trade_execution(&self) -> bool {
141        self.trade_execution
142    }
143
144    #[getter]
145    fn reject_stop_orders(&self) -> bool {
146        self.reject_stop_orders
147    }
148
149    #[getter]
150    fn support_gtd_orders(&self) -> bool {
151        self.support_gtd_orders
152    }
153
154    #[getter]
155    fn support_contingent_orders(&self) -> bool {
156        self.support_contingent_orders
157    }
158
159    #[getter]
160    fn use_position_ids(&self) -> bool {
161        self.use_position_ids
162    }
163
164    #[getter]
165    fn use_random_ids(&self) -> bool {
166        self.use_random_ids
167    }
168
169    #[getter]
170    fn use_reduce_only(&self) -> bool {
171        self.use_reduce_only
172    }
173}