nautilus_architect_ax/http/
query.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//! Request parameter structures for the Ax REST API.
17//!
18//! Each struct corresponds to an Ax REST endpoint and is annotated
19//! using `serde` so that it can be serialized directly into the query string
20//! or request body expected by the exchange.
21//!
22//! Parameter structs are built using the builder pattern and then passed to
23//! `AxRawHttpClient` methods where they are automatically serialized.
24
25use serde::{Deserialize, Serialize};
26
27use crate::common::enums::AxCandleWidth;
28
29/// Parameters for the GET /ticker endpoint.
30///
31/// # References
32/// - <https://docs.sandbox.x.architect.co/api-reference/marketdata/get-ticker>
33#[derive(Clone, Debug, Deserialize, Serialize)]
34pub struct GetTickerParams {
35    /// Instrument symbol, e.g. "GBPUSD-PERP", "EURUSD-PERP".
36    pub symbol: String,
37}
38
39impl GetTickerParams {
40    /// Creates a new [`GetTickerParams`] with the given symbol.
41    #[must_use]
42    pub fn new(symbol: impl Into<String>) -> Self {
43        Self {
44            symbol: symbol.into(),
45        }
46    }
47}
48
49/// Parameters for the GET /instrument endpoint.
50///
51/// # References
52/// - <https://docs.sandbox.x.architect.co/api-reference/symbols-instruments/get-instrument>
53#[derive(Clone, Debug, Deserialize, Serialize)]
54pub struct GetInstrumentParams {
55    /// Instrument symbol, e.g. "GBPUSD-PERP", "EURUSD-PERP".
56    pub symbol: String,
57}
58
59impl GetInstrumentParams {
60    /// Creates a new [`GetInstrumentParams`] with the given symbol.
61    #[must_use]
62    pub fn new(symbol: impl Into<String>) -> Self {
63        Self {
64            symbol: symbol.into(),
65        }
66    }
67}
68
69/// Parameters for the GET /candles endpoint.
70///
71/// # References
72/// - <https://docs.sandbox.x.architect.co/api-reference/marketdata/get-candles>
73#[derive(Clone, Debug, Deserialize, Serialize)]
74pub struct GetCandlesParams {
75    /// Instrument symbol.
76    pub symbol: String,
77    /// Start timestamp in nanoseconds.
78    pub start_timestamp_ns: i64,
79    /// End timestamp in nanoseconds.
80    pub end_timestamp_ns: i64,
81    /// Candle width/interval.
82    pub candle_width: AxCandleWidth,
83}
84
85impl GetCandlesParams {
86    /// Creates a new [`GetCandlesParams`].
87    #[must_use]
88    pub fn new(
89        symbol: impl Into<String>,
90        start_timestamp_ns: i64,
91        end_timestamp_ns: i64,
92        candle_width: AxCandleWidth,
93    ) -> Self {
94        Self {
95            symbol: symbol.into(),
96            start_timestamp_ns,
97            end_timestamp_ns,
98            candle_width,
99        }
100    }
101}
102
103/// Parameters for the GET /candles/current and GET /candles/last endpoints.
104///
105/// # References
106/// - <https://docs.sandbox.x.architect.co/api-reference/marketdata/get-current-candle>
107/// - <https://docs.sandbox.x.architect.co/api-reference/marketdata/get-last-candle>
108#[derive(Clone, Debug, Deserialize, Serialize)]
109pub struct GetCandleParams {
110    /// Instrument symbol.
111    pub symbol: String,
112    /// Candle width/interval.
113    pub candle_width: AxCandleWidth,
114}
115
116impl GetCandleParams {
117    /// Creates a new [`GetCandleParams`].
118    #[must_use]
119    pub fn new(symbol: impl Into<String>, candle_width: AxCandleWidth) -> Self {
120        Self {
121            symbol: symbol.into(),
122            candle_width,
123        }
124    }
125}
126
127/// Parameters for the GET /funding-rates endpoint.
128///
129/// # References
130/// - <https://docs.sandbox.x.architect.co/api-reference/marketdata/get-funding-rates>
131#[derive(Clone, Debug, Deserialize, Serialize)]
132pub struct GetFundingRatesParams {
133    /// Instrument symbol.
134    pub symbol: String,
135    /// Start timestamp in nanoseconds.
136    pub start_timestamp_ns: i64,
137    /// End timestamp in nanoseconds.
138    pub end_timestamp_ns: i64,
139}
140
141impl GetFundingRatesParams {
142    /// Creates a new [`GetFundingRatesParams`].
143    #[must_use]
144    pub fn new(symbol: impl Into<String>, start_timestamp_ns: i64, end_timestamp_ns: i64) -> Self {
145        Self {
146            symbol: symbol.into(),
147            start_timestamp_ns,
148            end_timestamp_ns,
149        }
150    }
151}
152
153/// Parameters for the GET /transactions endpoint.
154///
155/// # References
156/// - <https://docs.sandbox.x.architect.co/api-reference/portfolio-management/get-transactions>
157#[derive(Clone, Debug, Deserialize, Serialize)]
158pub struct GetTransactionsParams {
159    /// Transaction types to filter by.
160    pub transaction_types: Vec<String>,
161}
162
163impl GetTransactionsParams {
164    /// Creates a new [`GetTransactionsParams`].
165    #[must_use]
166    pub fn new(transaction_types: Vec<String>) -> Self {
167        Self { transaction_types }
168    }
169}
170
171#[cfg(test)]
172mod tests {
173    use rstest::rstest;
174
175    use super::*;
176
177    #[rstest]
178    fn test_get_ticker_params_serialization() {
179        let params = GetTickerParams::new("GBPUSD-PERP");
180        let qs = serde_urlencoded::to_string(&params).unwrap();
181        assert_eq!(qs, "symbol=GBPUSD-PERP");
182    }
183
184    #[rstest]
185    fn test_get_instrument_params_serialization() {
186        let params = GetInstrumentParams::new("EURUSD-PERP");
187        let qs = serde_urlencoded::to_string(&params).unwrap();
188        assert_eq!(qs, "symbol=EURUSD-PERP");
189    }
190
191    #[rstest]
192    fn test_get_candles_params_serialization() {
193        let params = GetCandlesParams::new(
194            "GBPUSD-PERP",
195            1000000000,
196            2000000000,
197            AxCandleWidth::Minutes1,
198        );
199        let qs = serde_urlencoded::to_string(&params).unwrap();
200        assert!(qs.contains("symbol=GBPUSD-PERP"));
201        assert!(qs.contains("start_timestamp_ns=1000000000"));
202        assert!(qs.contains("end_timestamp_ns=2000000000"));
203        assert!(qs.contains("candle_width=1m"));
204    }
205
206    #[rstest]
207    fn test_get_candle_params_serialization() {
208        let params = GetCandleParams::new("GBPUSD-PERP", AxCandleWidth::Hours1);
209        let qs = serde_urlencoded::to_string(&params).unwrap();
210        assert!(qs.contains("symbol=GBPUSD-PERP"));
211        assert!(qs.contains("candle_width=1h"));
212    }
213
214    #[rstest]
215    fn test_get_funding_rates_params_serialization() {
216        let params = GetFundingRatesParams::new("GBPUSD-PERP", 1000000000, 2000000000);
217        let qs = serde_urlencoded::to_string(&params).unwrap();
218        assert!(qs.contains("symbol=GBPUSD-PERP"));
219        assert!(qs.contains("start_timestamp_ns=1000000000"));
220        assert!(qs.contains("end_timestamp_ns=2000000000"));
221    }
222}