Skip to main content

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}