rusty_feeder/exchange/upbit/
types.rs

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