rusty_feeder/exchange/bithumb/
types.rs

1/*
2 * Bithumb exchange-specific types and constants
3 */
4
5use crate::provider::prelude::*;
6use rust_decimal::Decimal;
7use serde::{Deserialize, Serialize};
8use smartstring::alias::String;
9
10/// Bithumb Public WebSocket URL (ws-api endpoint)
11pub const BITHUMB_WS_URL: &str = "wss://ws-api.bithumb.com/websocket/v1";
12
13/// Bithumb Public WebSocket URL (pubwss endpoint for public data)
14pub const BITHUMB_PUBLIC_WS_URL: &str = "wss://pubwss.bithumb.com/pub/ws";
15
16/// Bithumb REST API base URL
17pub const BITHUMB_API_URL: &str = "https://api.bithumb.com";
18
19/// Bithumb Private WebSocket URL
20pub const BITHUMB_PRIVATE_WS_URL: &str = "wss://ws-api.bithumb.com/websocket/v1/private";
21
22/// Bithumb API rate limits
23pub const BITHUMB_RATE_LIMITS: &[RateLimit] = &[
24    RateLimit {
25        limit_type: "REQUEST_WEIGHT",
26        interval: "MINUTE",
27        interval_num: 1,
28        limit: 900, // Bithumb allows 900 requests per minute for most endpoints
29    },
30    RateLimit {
31        limit_type: "ORDERS",
32        interval: "MINUTE",
33        interval_num: 1,
34        limit: 200, // Order rate limits
35    },
36    RateLimit {
37        limit_type: "RAW_REQUESTS",
38        interval: "SECOND",
39        interval_num: 1,
40        limit: 30, // Maximum general requests per second
41    },
42];
43
44/// Message types for Bithumb WebSocket API
45#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
46#[serde(rename_all = "lowercase")]
47pub enum BithumbMessageType {
48    /// Trade execution
49    #[serde(rename = "trade")]
50    Trade,
51
52    /// Orderbook data
53    #[serde(rename = "orderbook")]
54    Orderbook,
55
56    /// Ticker update
57    #[serde(rename = "ticker")]
58    Ticker,
59
60    /// Status message
61    #[serde(rename = "status")]
62    Status,
63}
64
65/// Stream types for Bithumb WebSocket messages
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
67#[serde(rename_all = "UPPERCASE")]
68pub enum StreamType {
69    /// Snapshot data
70    #[serde(rename = "SNAPSHOT")]
71    Snapshot,
72
73    /// Real-time update
74    #[serde(rename = "REALTIME")]
75    Realtime,
76}
77
78/// Change direction for price
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
80#[serde(rename_all = "UPPERCASE")]
81pub enum ChangeDirection {
82    /// Price went up
83    #[serde(rename = "RISE")]
84    Rise,
85
86    /// Price stayed the same
87    #[serde(rename = "EVEN")]
88    Even,
89
90    /// Price went down
91    #[serde(rename = "FALL")]
92    Fall,
93}
94
95/// Trade side (Ask/Bid)
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
97#[serde(rename_all = "UPPERCASE")]
98pub enum TradeSide {
99    /// Sell order
100    #[serde(rename = "ASK")]
101    Ask,
102
103    /// Buy order
104    #[serde(rename = "BID")]
105    Bid,
106}
107
108/// Status message from WebSocket
109#[derive(Debug, Clone, Deserialize, Serialize)]
110pub struct StatusMessage {
111    /// Status of the WebSocket connection
112    pub status: String,
113}
114
115/// Ticket part of WebSocket request
116#[derive(Debug, Clone, Serialize)]
117pub struct TicketRequest {
118    /// Client-generated ticket ID
119    pub ticket: String,
120}
121
122/// WebSocket subscription request for Bithumb
123#[derive(Debug, Clone, Serialize)]
124pub struct SubscriptionRequest {
125    /// Type of data to subscribe to
126    #[serde(rename = "type")]
127    pub data_type: String,
128
129    /// Market codes to subscribe to
130    pub codes: Vec<String>,
131
132    /// Price level aggregation (for orderbook)
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub level: Option<f64>,
135
136    /// Whether to only get snapshot data
137    #[serde(skip_serializing_if = "Option::is_none", rename = "isOnlySnapshot")]
138    pub is_only_snapshot: Option<bool>,
139
140    /// Whether to only get realtime data
141    #[serde(skip_serializing_if = "Option::is_none", rename = "isOnlyRealtime")]
142    pub is_only_realtime: Option<bool>,
143}
144
145/// WebSocket subscription format
146#[derive(Debug, Clone, Serialize)]
147pub struct FormatRequest {
148    /// Format of responses (DEFAULT or SIMPLE)
149    pub format: String,
150}
151
152/// WebSocket response format for trade data
153#[derive(Debug, Clone, Deserialize, Serialize)]
154#[repr(align(64))] // Cache line alignment for better performance
155pub struct TradeResponse {
156    /// Message type
157    #[serde(rename = "type")]
158    pub message_type: String,
159
160    /// Market code (e.g., "KRW-BTC")
161    pub code: String,
162
163    /// Trade price
164    pub trade_price: Decimal,
165
166    /// Trade volume
167    pub trade_volume: Decimal,
168
169    /// Ask/Bid indicator
170    pub ask_bid: String,
171
172    /// Previous day's closing price
173    pub prev_closing_price: Decimal,
174
175    /// Change direction (RISE, EVEN, FALL)
176    pub change: String,
177
178    /// Change amount (absolute value)
179    pub change_price: Decimal,
180
181    /// Trade date (KST) in yyyy-MM-dd format
182    pub trade_date: String,
183
184    /// Trade time (KST) in HH:mm:ss format
185    pub trade_time: String,
186
187    /// Trade timestamp in milliseconds
188    pub trade_timestamp: u64,
189
190    /// Sequential ID (unique for each trade)
191    pub sequential_id: u64,
192
193    /// Message timestamp in milliseconds
194    pub timestamp: u64,
195
196    /// Stream type (SNAPSHOT or REALTIME)
197    pub stream_type: String,
198}
199
200/// Individual price level in the orderbook
201#[derive(Debug, Clone, Deserialize, Serialize)]
202pub struct OrderbookUnit {
203    /// Ask price
204    pub ask_price: Decimal,
205
206    /// Bid price
207    pub bid_price: Decimal,
208
209    /// Ask size/volume
210    pub ask_size: Decimal,
211
212    /// Bid size/volume
213    pub bid_size: Decimal,
214}
215
216/// WebSocket response format for orderbook data
217#[derive(Debug, Clone, Deserialize, Serialize)]
218#[repr(align(64))] // Cache line alignment for better performance
219pub struct OrderbookResponse {
220    /// Message type
221    #[serde(rename = "type")]
222    pub message_type: String,
223
224    /// Market code (e.g., "KRW-BTC")
225    pub code: String,
226
227    /// Total ask volume
228    pub total_ask_size: Decimal,
229
230    /// Total bid volume
231    pub total_bid_size: Decimal,
232
233    /// Orderbook units (price levels)
234    pub orderbook_units: Vec<OrderbookUnit>,
235
236    /// Price level aggregation
237    pub level: f64,
238
239    /// Message timestamp in milliseconds
240    pub timestamp: u64,
241
242    /// Stream type (SNAPSHOT or REALTIME)
243    pub stream_type: String,
244}