nautilus_tardis/http/models.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
16use jiff::Timestamp;
17use serde::{Deserialize, Serialize};
18use serde_json::Value;
19use ustr::Ustr;
20
21use crate::common::{
22 enums::{TardisExchange, TardisInstrumentType, TardisOptionType},
23 parse::{deserialize_f64_or_string, deserialize_opt_f64_or_string, deserialize_uppercase},
24};
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27#[serde(rename_all = "camelCase")]
28/// The metadata of a particular instrument.
29/// See <https://docs.tardis.dev/api/instruments-metadata-api>.
30pub struct TardisInstrumentInfo {
31 /// The instrument symbol.
32 #[serde(deserialize_with = "deserialize_uppercase")]
33 pub id: Ustr,
34 /// The instrument exchange.
35 pub exchange: TardisExchange,
36 /// The instrument base currency (normalized, e.g., BTC for BitMEX, not XBT).
37 pub base_currency: Ustr,
38 /// The instrument quote currency (normalized, e.g., BTC for BitMEX, not XBT).
39 pub quote_currency: Ustr,
40 /// The instrument type e.g., spot, perpetual, future, option.
41 #[serde(rename = "type")]
42 pub instrument_type: TardisInstrumentType,
43 /// If the instrument is actively listed.
44 pub active: bool,
45 /// The listing date in ISO format.
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub listing: Option<Timestamp>,
48 /// The available from date in ISO format.
49 pub available_since: Timestamp,
50 /// The available to date in ISO format.
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub available_to: Option<Timestamp>,
53 /// The contract expiry date in ISO format (applicable to futures and options).
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub expiry: Option<Timestamp>,
56 /// The instrument price increment.
57 #[serde(deserialize_with = "deserialize_f64_or_string")]
58 pub price_increment: f64,
59 /// The instrument size increment.
60 #[serde(deserialize_with = "deserialize_f64_or_string")]
61 pub amount_increment: f64,
62 /// The minimum tradeable size for the instrument.
63 #[serde(deserialize_with = "deserialize_f64_or_string")]
64 pub min_trade_amount: f64,
65 /// The instrument maker fee: consider it as illustrative only, as it depends in practice on account traded volume levels, different categories, VIP levels, owning exchange currency etc.
66 #[serde(deserialize_with = "deserialize_f64_or_string")]
67 pub maker_fee: f64,
68 /// The instrument taker fee: consider it as illustrative only, as it depends in practice on account traded volume levels, different categories, VIP levels, owning exchange currency etc.
69 #[serde(deserialize_with = "deserialize_f64_or_string")]
70 pub taker_fee: f64,
71 /// If the instrument is inverse (only for derivatives such as futures and perpetual swaps).
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub inverse: Option<bool>,
74 /// The instrument contract multiplier (only for derivatives).
75 #[serde(skip_serializing_if = "Option::is_none")]
76 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
77 pub contract_multiplier: Option<f64>,
78 /// If the instrument is quanto (only for quanto instruments).
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub quanto: Option<bool>,
81 /// The instrument settlement currency (only for Quanto instruments where settlement currency is different both base and quote currency).
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub settlement_currency: Option<Ustr>,
84 /// The instrument strike price (only for options).
85 #[serde(skip_serializing_if = "Option::is_none")]
86 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
87 pub strike_price: Option<f64>,
88 /// The option type (only for options).
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub option_type: Option<TardisOptionType>,
91 /// The changes for the instrument (best-effort basis from Tardis).
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub changes: Option<Vec<TardisInstrumentChanges>>,
94 /// Additional fields from the Tardis API not explicitly modeled above.
95 #[serde(flatten)]
96 pub extra: serde_json::Map<String, Value>,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(rename_all = "camelCase")]
101/// The changes info returned by the exchanges API.
102pub struct TardisInstrumentChanges {
103 /// Date in ISO format.
104 pub until: Timestamp,
105 /// The minimum price increment (tick size).
106 #[serde(skip_serializing_if = "Option::is_none")]
107 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
108 pub price_increment: Option<f64>,
109 /// The minimum size increment.
110 #[serde(skip_serializing_if = "Option::is_none")]
111 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
112 pub amount_increment: Option<f64>,
113 /// The instrument contract multiplier (only for derivatives).
114 #[serde(skip_serializing_if = "Option::is_none")]
115 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
116 pub contract_multiplier: Option<f64>,
117 /// The maker fee rate.
118 #[serde(skip_serializing_if = "Option::is_none")]
119 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
120 pub maker_fee: Option<f64>,
121 /// The taker fee rate.
122 #[serde(skip_serializing_if = "Option::is_none")]
123 #[serde(default, deserialize_with = "deserialize_opt_f64_or_string")]
124 pub taker_fee: Option<f64>,
125 /// Additional fields from the Tardis API not explicitly modeled above.
126 #[serde(flatten)]
127 pub extra: serde_json::Map<String, Value>,
128}