ccdata_api/schemas/data_api/futures.rs
1use std::fmt::Display;
2use serde::{Serialize, Deserialize};
3use crate::schemas::data_api::InstrumentStatus;
4
5
6#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
7/// The exchange to obtain data from.
8pub enum FuturesMarket {
9 BINANCE,
10 BIT,
11 BITFINEX,
12 BITGET,
13 BITMEX,
14 BTCEX,
15 BULLISH,
16 BYBIT,
17 COINBASE,
18 COINBASEINTERNATIONAL,
19 CROSSTOWER,
20 CRYPTODOTCOM,
21 DERIBIT,
22 DYDXV4,
23 FTX,
24 GATEIO,
25 HUOBIPRO,
26 HYPERLIQUID,
27 #[default]
28 KRAKEN,
29 KUCOIN,
30 MOCK,
31 OKEX,
32}
33
34impl Display for FuturesMarket {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self {
37 Self::BINANCE => write!(f, "binance"),
38 Self::BIT => write!(f, "bit"),
39 Self::BITFINEX => write!(f, "bitfinex"),
40 Self::BITGET => write!(f, "bitget"),
41 Self::BITMEX => write!(f, "bitmex"),
42 Self::BTCEX => write!(f, "btcex"),
43 Self::BULLISH => write!(f, "bullish"),
44 Self::BYBIT => write!(f, "bybit"),
45 Self::COINBASE => write!(f, "coinbase"),
46 Self::COINBASEINTERNATIONAL => write!(f, "coinbaseinternational"),
47 Self::CROSSTOWER => write!(f, "crosstower"),
48 Self::CRYPTODOTCOM => write!(f, "cryptodotcom"),
49 Self::DERIBIT => write!(f, "deribit"),
50 Self::DYDXV4 => write!(f, "dydxv4"),
51 Self::FTX => write!(f, "ftx"),
52 Self::GATEIO => write!(f, "gateio"),
53 Self::HUOBIPRO => write!(f, "huobipro"),
54 Self::HYPERLIQUID => write!(f, "hyperliquid"),
55 Self::KRAKEN => write!(f, "kraken"),
56 Self::KUCOIN => write!(f, "kucoin"),
57 Self::MOCK => write!(f, "mock"),
58 Self::OKEX => write!(f, "okex"),
59 }
60 }
61}
62
63
64#[derive(Clone, Debug, Serialize, Deserialize)]
65pub struct FuturesInstrumentMapping {
66 #[serde(rename = "MAPPED_INSTRUMENT")]
67 pub mapped_instrument: String,
68 #[serde(rename = "INDEX_UNDERLYING")]
69 pub index_underlying: String,
70 #[serde(rename = "INDEX_UNDERLYING_ID")]
71 pub index_underlying_id: i32,
72 #[serde(rename = "QUOTE_CURRENCY")]
73 pub quote_currency: String,
74 #[serde(rename = "QUOTE_CURRENCY_ID")]
75 pub quote_currency_id: i32,
76 #[serde(rename = "SETTLEMENT_CURRENCY")]
77 pub settlement_currency: String,
78 #[serde(rename = "SETTLEMENT_CURRENCY_ID")]
79 pub settlement_currency_id: i32,
80 #[serde(rename = "CONTRACT_CURRENCY")]
81 pub contract_currency: String,
82 #[serde(rename = "CONTRACT_CURRENCY_ID")]
83 pub contract_currency_id: i32,
84 #[serde(rename = "DENOMINATION_TYPE")]
85 pub denomination_type: String,
86 #[serde(rename = "TRANSFORM_FUNCTION")]
87 pub transform_function: String,
88 #[serde(rename = "CREATED_ON")]
89 pub created_on: i64,
90}
91
92
93// Futures: Historical OHLCV+
94
95
96/// Futures: Historical OHLCV+
97#[derive(Clone, Debug, Serialize, Deserialize)]
98pub struct FuturesOHLCV {
99 #[serde(rename = "UNIT")]
100 /// The level of granularity (e.g. MINUTE / HOUR / DAY).
101 pub unit: String,
102 #[serde(rename = "TIMESTAMP")]
103 /// The timestamp, in seconds, of the histo period. This refers to the first timestamp of the unit under consideration,
104 /// not the last (e.g. for daily data the timestamp will refer to 00:00 GMT/UTC).
105 pub timestamp: i64,
106 #[serde(rename = "TYPE")]
107 /// Type of the message.
108 pub type_: String,
109 #[serde(rename = "MARKET")]
110 /// The market / exchange under consideration (e.g. bitmex, deribit, ftx, etc).
111 pub market: String,
112 #[serde(rename = "INSTRUMENT")]
113 /// The unmapped instrument ID.
114 pub instrument: String,
115 #[serde(rename = "MAPPED_INSTRUMENT")]
116 /// The mapped instrument ID, derived from our mapping rules.
117 pub mapped_instrument: String,
118 #[serde(rename = "INDEX_UNDERLYING")]
119 /// The mapped index underlying asset.
120 pub index_underlying: String,
121 #[serde(rename = "QUOTE_CURRENCY")]
122 /// The mapped to asset quote / counter symbol / coin (e.g. USD). Only available on instruments that have mapping.
123 pub quote_currency: String,
124 #[serde(rename = "SETTLEMENT_CURRENCY")]
125 /// The currency that the contract is settled in (e.g. USD). Only available on instruments that have mapping.
126 pub settlement_currency: String,
127 #[serde(rename = "CONTRACT_CURRENCY")]
128 /// The currency that the contract size is denominated in (e.g. USD). Only available on instruments that have mapping.
129 pub contract_currency: String,
130 #[serde(rename = "DENOMINATION_TYPE")]
131 /// VANILLA = (SETTLEMENT_CURRENCY = QUOTE_CURRENCY), INVERSE = (SETTLEMENT_CURRENCY = INDEX_UNDERLYING),
132 /// QUANTO (SETTLEMENT_CURRENCY != INDEX_UNDERLYING or QUOTE_CURRENCY).
133 pub denomination_type: String,
134 #[serde(rename = "INDEX_UNDERLYING_ID")]
135 /// Represents the internal CoinDesk ID for the index underlying asset (e.g., 1). This ID is unique and immutable,
136 /// ensuring consistent identification. Applicable only to instruments with a mapping.
137 pub index_underlying_id: i32,
138 #[serde(rename = "QUOTE_CURRENCY_ID")]
139 /// Represents the internal CoinDesk ID for the asset quote / counter symbol / coin (e.g. 5). This ID is unique and immutable,
140 /// ensuring consistent identification. Applicable only to instruments with a mapping.
141 pub quote_currency_id: i32,
142 #[serde(rename = "SETTLEMENT_CURRENCY_ID")]
143 /// Represents the internal CoinDesk ID for the currency that the contract is settled in (e.g. 5). This ID is unique and immutable,
144 /// ensuring consistent identification. Applicable only to instruments with a mapping.
145 pub settlement_currency_id: i32,
146 #[serde(rename = "CONTRACT_CURRENCY_ID")]
147 /// Represents the internal CoinDesk ID for the currency that the contract size is denominated in (e.g. 5). This ID is unique and immutable,
148 /// ensuring consistent identification. Applicable only to instruments with a mapping.
149 pub contract_currency_id: i32,
150 #[serde(rename = "TRANSFORM_FUNCTION")]
151 /// The transform function. This is the function we apply when we do mapping to change values into easier human readable ones
152 /// and to make sure the mapped direction BASE - QUOTE is constant accross all instruments.
153 pub transform_function: String,
154 #[serde(rename = "OPEN")]
155 /// The open price for the historical period, based on the closest trade before the period start.
156 pub open: f64,
157 #[serde(rename = "HIGH")]
158 /// The highest trade price of the historical period. If there were no trades in the period, the open price will be taken as the highest.
159 pub high: f64,
160 #[serde(rename = "LOW")]
161 /// The lowest trade price of the historical period. If there were no trades in the period, the open price will be taken as the lowest.
162 pub low: f64,
163 #[serde(rename = "CLOSE")]
164 /// The price of the last trade of the historical period. If there were no trades in the period, the open price will be taken as the close.
165 pub close: f64,
166 #[serde(rename = "FIRST_TRADE_TIMESTAMP")]
167 /// The timestamp, in seconds, of the first trade of the time period. Only available when there is at least one trade in the time period.
168 pub first_trade_timestamp: i64,
169 #[serde(rename = "LAST_TRADE_TIMESTAMP")]
170 /// The timestamp, in seconds, of the last trade of the time period. Only available when there is at least one trade in the time period).
171 pub last_trade_timestamp: i64,
172 #[serde(rename = "FIRST_TRADE_PRICE")]
173 /// The price of the first trade of the time period. Only available when there is at least one trade in the time period.
174 pub first_trade_price: f64,
175 #[serde(rename = "HIGH_TRADE_PRICE")]
176 /// The highest trade price of the time period. Only available when there is at least one trade in the time period.
177 pub high_trade_price: f64,
178 #[serde(rename = "HIGH_TRADE_TIMESTAMP")]
179 /// The timestamp, in seconds, of the highest trade in this time period. Only available when there is at least one trade in the time period.
180 pub high_trade_timestamp: i64,
181 #[serde(rename = "LOW_TRADE_PRICE")]
182 /// The lowest trade price of the time period. Only available when there is at least one trade in the time period.
183 pub low_trade_price: f64,
184 #[serde(rename = "LOW_TRADE_TIMESTAMP")]
185 /// The timestamp, in seconds, of the lowest trade of the time period. Only available when there is at least one trade in the time period.
186 pub low_trade_timestamp: i64,
187 #[serde(rename = "LAST_TRADE_PRICE")]
188 /// The price of the last trade of the period. Only available when there is at least one trade in the time period.
189 pub last_trade_price: f64,
190 #[serde(rename = "TOTAL_TRADES")]
191 /// The total number of trades that occurred in the time period. If there were no trades in the time period, 0 will be given.
192 pub total_trades: i64,
193 #[serde(rename = "TOTAL_TRADES_BUY")]
194 /// The total number of BUY trades that occurred in the in time period.
195 pub total_trades_buy: i64,
196 #[serde(rename = "TOTAL_TRADES_SELL")]
197 /// The total number of SELL trades that occurred in the time period.
198 pub total_trades_sell: i64,
199 #[serde(rename = "TOTAL_TRADES_UNKNOWN")]
200 /// The total number of UNKNOWN trades that occurred in the time period.
201 pub total_trades_unknown: i64,
202 #[serde(rename = "NUMBER_OF_CONTRACTS")]
203 /// The sum of all the trade number of contracts for the time period. If there were no trades in the time period, 0 will be given.
204 pub number_of_contracts: i64,
205 #[serde(rename = "VOLUME")]
206 /// The sum of all the trade volumes in the from asset (base symbol / coin) for the time period. If there were no trades in the time period, 0 will be given.
207 pub volume: f64,
208 #[serde(rename = "QUOTE_VOLUME")]
209 /// The sum of all the trade volumes in the To asset (quote/counter symbol/coin) for the time period. If there were no trades in the time period, 0 will be given.
210 pub quote_volume: f64,
211 #[serde(rename = "VOLUME_BUY")]
212 /// The sum of all the BUY trade volumes in the from asset (base symbol / coin) for the time period.
213 pub volume_buy: f64,
214 #[serde(rename = "QUOTE_VOLUME_BUY")]
215 /// The sum of all the BUY trade volumes in the To asset (quote/counter symbol/coin) for the time period.
216 pub quote_volume_buy: f64,
217 #[serde(rename = "VOLUME_SELL")]
218 /// The sum of all the SELL trade volumes in the from asset (base symbol / coin) for the time period.
219 pub volume_sell: f64,
220 #[serde(rename = "QUOTE_VOLUME_SELL")]
221 /// The sum of all the SELL trade volumes in the To asset (quote/counter symbol/coin) for the time period.
222 pub quote_volume_sell: f64,
223 #[serde(rename = "VOLUME_UNKNOWN")]
224 /// The sum of all the UNKNOWN trade volumes in the from asset (base symbol / coin) for the time period.
225 pub volume_unknown: f64,
226 #[serde(rename = "QUOTE_VOLUME_UNKNOWN")]
227 /// The sum of all the UNKNOWN trade volumes in the To asset (quote/counter symbol/coin) for the time period.
228 pub quote_volume_unknown: f64,
229}
230
231
232// Futures: Instrument Metadata
233
234
235#[derive(Clone, Debug, Serialize, Deserialize)]
236pub struct FuturesInstrumentMetadata {
237 #[serde(rename = "METADATA_VERSION")]
238 /// The version of metadata, used for version conversions/migrates.
239 pub metadata_version: i32,
240 #[serde(rename = "INSTRUMENT_STATUS")]
241 /// The status of the instrument, we only poll / stream / connect to the ACTIVE ones,
242 /// for the RETIRED / IGNORED / EXPIRED / READY_FOR_DECOMMISSIONING means we no longer query/stream data.
243 pub instrument_status: String,
244 #[serde(rename = "FIRST_SEEN_ON_POLLING_TS")]
245 /// This is the first time instrument was seen on instrumentListSourceType POLLING.
246 pub first_seen_on_polling_ts: i64,
247 #[serde(rename = "LAST_SEEN_ON_POLLING_TS")]
248 /// This is the last time instrument was seen on instrumentListSourceType POLLING.
249 pub last_seen_on_polling_ts: i64,
250 #[serde(rename = "INSTRUMENT")]
251 /// The instrument ID as it is on the exchange with small modifications - we do not allow the following characters inside isntrument ids: ,/&?
252 pub instrument: String,
253 #[serde(rename = "INSTRUMENT_MAPPING")]
254 /// The current mapping information for this instrument.
255 pub instrument_mapping: FuturesInstrumentMapping,
256 #[serde(rename = "INSTRUMENT_EXTERNAL_DATA")]
257 /// The full data we get from the polling endpoint for this specific instrument.
258 /// his is a JSON stringified object with different properties per exchange.
259 pub instrument_external_data: String,
260 #[serde(rename = "INSTRUMENT_AVAILABLE_ON_INSTRUMENTS_ENDPOINT")]
261 /// This flags the exchange instrument is currently available on instruments endpoint.
262 pub instrument_available_on_instruments_endpoint: bool,
263 #[serde(rename = "INDEX_ID")]
264 /// The id of the index the contract is based on.
265 pub index_id: String,
266 #[serde(rename = "INDEX_UNDERLYING")]
267 /// The underlying instrument of the index.
268 pub index_underlying: String,
269 #[serde(rename = "QUOTE_CURRENCY")]
270 /// The instrument that the contract is priced in.
271 pub quote_currency: String,
272 #[serde(rename = "SETTLEMENT_CURRENCY")]
273 /// The currency used to calculate contract PnL. The settlement currency can be different from the index underlying or quote currencies.
274 pub settlement_currency: String,
275 #[serde(rename = "DENOMINATION_TYPE")]
276 /// VANILLA = (SETTLEMENT_CURRENCY = QUOTE_CURRENCY), INVERSE = (SETTLEMENT_CURRENCY = INDEX_UNDERLYING),
277 /// QUANTO (SETTLEMENT_CURRENCY != INDEX_UNDERLYING or QUOTE_CURRENCY)
278 pub denomination_type: String,
279 #[serde(rename = "CONTRACT_CURRENCY")]
280 /// The denomination of the CONTRACT_SIZE.
281 pub contract_currency: String,
282 #[serde(rename = "CONTRACT_SIZE")]
283 /// The contract size - how much of the contract currency does one contract contain.
284 pub contract_size: f64,
285 #[serde(rename = "TICK_SIZE")]
286 /// The minimum amount the price can move, denominated in QUOTE_CURRENCY.
287 pub tick_size: f64,
288 #[serde(rename = "DELIVERY_METHOD")]
289 /// The settlement delivery method on the derivative product.
290 pub delivery_method: String,
291 #[serde(rename = "CONTRACT_TERM")]
292 /// The term / duration the contract represents e.g. 3xMONTH.
293 pub contract_term: String,
294 #[serde(rename = "CONTRACT_CREATION_TS")]
295 /// The contract creation timestamp we get for the specific derivative instrument.
296 pub contract_creation_ts: i64,
297 #[serde(rename = "CONTRACT_EXPIRATION_TS")]
298 /// The contract expiration timestamp we get for the specific derivative instrument. Not needed for PERPETUAL contract types.
299 pub contract_expiration_ts: Option<i64>,
300 #[serde(rename = "FIRST_OB_L2_MINUTE_SNAPSHOT_TS")]
301 /// Timestamp of the initial Level 2 minute snapshot.
302 pub first_ob_l2_minute_snapshot_t2s: i64,
303 #[serde(rename = "LAST_OB_L2_MINUTE_SNAPSHOT_TS")]
304 /// Timestamp of the latest Level 2 minute snapshot.
305 pub last_ob_l2_minute_snapshot_ts: i64,
306}
307
308
309// Futures: Markets
310
311
312/// Futures: Markets
313#[derive(Clone, Debug, Serialize, Deserialize)]
314pub struct FuturesMarkets {
315 #[serde(rename = "TYPE")]
316 /// Type of the message.
317 pub type_: String,
318 #[serde(rename = "EXCHANGE_STATUS")]
319 /// The status of the echange. We only poll / stream / connect to the ACTIVE ones, for the RETIRED ones we no longer query for data.
320 pub exchange_status: String,
321 #[serde(rename = "MAPPED_INSTRUMENTS_TOTAL")]
322 /// The total number of instruments that have been verified by our mapping team and have been properly assigned with a base, quote, mapping function,
323 /// and other necessary fields. This is done to ensure that pairs like XXBTZUSD are accurately mapped to BTC-USD and that the pair refers
324 // to the correct assets rather than using the same asset id to represent different assets.
325 pub mapped_instrument_total: i64,
326 #[serde(rename = "UNMAPPED_INSTRUMENTS_TOTAL")]
327 /// The number of instruments that have not yet been verified by our mapping team.
328 pub unmapped_instruments_total: i64,
329 #[serde(rename = "INSTRUMENT_STATUS")]
330 /// An object with the total number of instrument for each of the available instrument statuses.
331 pub instrument_status: InstrumentStatus,
332 #[serde(rename = "TOTAL_TRADES_FUTURES")]
333 /// The total number of futures trades that this exchange has processed.
334 pub total_trades_futures: i64,
335 #[serde(rename = "TOTAL_FUNDING_RATE_UPDATES")]
336 /// The total number of futures funding rate updates that this exchange has processed.
337 pub total_funding_rate_updates: i64,
338 #[serde(rename = "TOTAL_OPEN_INTEREST_UPDATES")]
339 /// The total number of futures open interest updates that this exchange has processed.
340 pub total_open_interest_updates: i64,
341 #[serde(rename = "HAS_ORDERBOOK_L2_MINUTE_SNAPSHOTS_ENABLED")]
342 /// Boolean field denoting if we have historical minute orderbook snapshots endabled for this exchange.
343 pub has_orderbook_l2_minute_snapshots_enabled: bool,
344}