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}