nautilus_architect_ax/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//! Configuration structures for the AX Exchange adapter.
17
18use nautilus_model::identifiers::AccountId;
19
20/// Configuration for the AX Exchange live data client.
21#[derive(Clone, Debug)]
22pub struct AxDataClientConfig {
23 /// Optional API key for authenticated REST/WebSocket requests.
24 pub api_key: Option<String>,
25 /// Optional API secret for authenticated REST/WebSocket requests.
26 pub api_secret: Option<String>,
27 /// Use sandbox environment (default: false).
28 pub is_sandbox: bool,
29 /// Optional override for the REST base URL.
30 pub base_url_http: Option<String>,
31 /// Optional override for the public WebSocket URL.
32 pub base_url_ws_public: Option<String>,
33 /// Optional override for the private WebSocket URL.
34 pub base_url_ws_private: Option<String>,
35 /// Optional HTTP proxy URL.
36 pub http_proxy_url: Option<String>,
37 /// Optional WebSocket proxy URL.
38 pub ws_proxy_url: Option<String>,
39 /// Optional REST timeout in seconds.
40 pub http_timeout_secs: Option<u64>,
41 /// Optional maximum retry attempts for REST requests.
42 pub max_retries: Option<u32>,
43 /// Optional initial retry backoff in milliseconds.
44 pub retry_delay_initial_ms: Option<u64>,
45 /// Optional maximum retry backoff in milliseconds.
46 pub retry_delay_max_ms: Option<u64>,
47 /// Optional heartbeat interval (seconds) for WebSocket clients.
48 pub heartbeat_interval_secs: Option<u64>,
49 /// Optional receive window in milliseconds for signed requests.
50 pub recv_window_ms: Option<u64>,
51 /// Optional interval (minutes) for instrument refresh from REST.
52 pub update_instruments_interval_mins: Option<u64>,
53}
54
55impl Default for AxDataClientConfig {
56 fn default() -> Self {
57 Self {
58 api_key: None,
59 api_secret: None,
60 is_sandbox: false,
61 base_url_http: None,
62 base_url_ws_public: None,
63 base_url_ws_private: None,
64 http_proxy_url: None,
65 ws_proxy_url: None,
66 http_timeout_secs: Some(60),
67 max_retries: Some(3),
68 retry_delay_initial_ms: Some(1_000),
69 retry_delay_max_ms: Some(10_000),
70 heartbeat_interval_secs: Some(20),
71 recv_window_ms: Some(5_000),
72 update_instruments_interval_mins: Some(60),
73 }
74 }
75}
76
77impl AxDataClientConfig {
78 /// Creates a configuration with default values.
79 #[must_use]
80 pub fn new() -> Self {
81 Self::default()
82 }
83
84 /// Returns `true` if both API key and secret are available.
85 #[must_use]
86 pub fn has_api_credentials(&self) -> bool {
87 self.api_key.is_some() && self.api_secret.is_some()
88 }
89
90 /// Returns the REST base URL, considering overrides and environment.
91 #[must_use]
92 pub fn http_base_url(&self) -> String {
93 self.base_url_http.clone().unwrap_or_else(|| {
94 if self.is_sandbox {
95 "https://gateway.sandbox.architect.exchange/api".to_string()
96 } else {
97 "https://gateway.architect.exchange/api".to_string()
98 }
99 })
100 }
101
102 /// Returns the public WebSocket URL, considering overrides and environment.
103 #[must_use]
104 pub fn ws_public_url(&self) -> String {
105 self.base_url_ws_public.clone().unwrap_or_else(|| {
106 if self.is_sandbox {
107 "wss://gateway.sandbox.architect.exchange/ws/public".to_string()
108 } else {
109 "wss://gateway.architect.exchange/ws/public".to_string()
110 }
111 })
112 }
113
114 /// Returns the private WebSocket URL, considering overrides and environment.
115 #[must_use]
116 pub fn ws_private_url(&self) -> String {
117 self.base_url_ws_private.clone().unwrap_or_else(|| {
118 if self.is_sandbox {
119 "wss://gateway.sandbox.architect.exchange/ws/private".to_string()
120 } else {
121 "wss://gateway.architect.exchange/ws/private".to_string()
122 }
123 })
124 }
125
126 /// Returns `true` when private WebSocket connection is required.
127 #[must_use]
128 pub fn requires_private_ws(&self) -> bool {
129 self.has_api_credentials()
130 }
131}
132
133/// Configuration for the AX Exchange live execution client.
134#[derive(Clone, Debug)]
135pub struct AxExecClientConfig {
136 /// API key for authenticated requests.
137 pub api_key: Option<String>,
138 /// API secret for authenticated requests.
139 pub api_secret: Option<String>,
140 /// Use sandbox environment (default: false).
141 pub is_sandbox: bool,
142 /// Optional override for the REST base URL.
143 pub base_url_http: Option<String>,
144 /// Optional override for the private WebSocket URL.
145 pub base_url_ws_private: Option<String>,
146 /// Optional HTTP proxy URL.
147 pub http_proxy_url: Option<String>,
148 /// Optional WebSocket proxy URL.
149 pub ws_proxy_url: Option<String>,
150 /// Optional REST timeout in seconds.
151 pub http_timeout_secs: Option<u64>,
152 /// Optional maximum retry attempts for REST requests.
153 pub max_retries: Option<u32>,
154 /// Optional initial retry backoff in milliseconds.
155 pub retry_delay_initial_ms: Option<u64>,
156 /// Optional maximum retry backoff in milliseconds.
157 pub retry_delay_max_ms: Option<u64>,
158 /// Optional heartbeat interval (seconds) for WebSocket clients.
159 pub heartbeat_interval_secs: Option<u64>,
160 /// Optional receive window in milliseconds for signed requests.
161 pub recv_window_ms: Option<u64>,
162 /// Optional account identifier to associate with the execution client.
163 pub account_id: Option<AccountId>,
164}
165
166impl Default for AxExecClientConfig {
167 fn default() -> Self {
168 Self {
169 api_key: None,
170 api_secret: None,
171 is_sandbox: false,
172 base_url_http: None,
173 base_url_ws_private: None,
174 http_proxy_url: None,
175 ws_proxy_url: None,
176 http_timeout_secs: Some(60),
177 max_retries: Some(3),
178 retry_delay_initial_ms: Some(1_000),
179 retry_delay_max_ms: Some(10_000),
180 heartbeat_interval_secs: Some(5),
181 recv_window_ms: Some(5_000),
182 account_id: None,
183 }
184 }
185}
186
187impl AxExecClientConfig {
188 /// Creates a configuration with default values.
189 #[must_use]
190 pub fn new() -> Self {
191 Self::default()
192 }
193
194 /// Returns `true` if both API key and secret are available.
195 #[must_use]
196 pub fn has_api_credentials(&self) -> bool {
197 self.api_key.is_some() && self.api_secret.is_some()
198 }
199
200 /// Returns the REST base URL, considering overrides and environment.
201 #[must_use]
202 pub fn http_base_url(&self) -> String {
203 self.base_url_http.clone().unwrap_or_else(|| {
204 if self.is_sandbox {
205 "https://gateway.sandbox.architect.exchange/api".to_string()
206 } else {
207 "https://gateway.architect.exchange/api".to_string()
208 }
209 })
210 }
211
212 /// Returns the private WebSocket URL, considering overrides and environment.
213 #[must_use]
214 pub fn ws_private_url(&self) -> String {
215 self.base_url_ws_private.clone().unwrap_or_else(|| {
216 if self.is_sandbox {
217 "wss://gateway.sandbox.architect.exchange/ws/private".to_string()
218 } else {
219 "wss://gateway.architect.exchange/ws/private".to_string()
220 }
221 })
222 }
223}