rusty_feeder/exchange/bithumb/data/
trade.rs

1/*
2 * Bithumb trade data structures and processing
3 * Optimized for minimal allocations and low latency
4 */
5
6use rust_decimal::Decimal;
7use rusty_model::enums::OrderSide;
8use serde::{Deserialize, Serialize};
9use smartstring::alias::String;
10
11/// Raw trade message from Bithumb WebSocket
12#[derive(Debug, Clone, Deserialize, Serialize)]
13#[repr(align(64))] // Cache line alignment for better performance
14pub struct TradeMessage {
15    /// Message type
16    #[serde(rename = "type")]
17    pub message_type: String,
18
19    /// Market code (e.g., "KRW-BTC")
20    pub code: String,
21
22    /// Trade price
23    pub trade_price: Decimal,
24
25    /// Trade volume
26    pub trade_volume: Decimal,
27
28    /// Ask/Bid indicator
29    pub ask_bid: String,
30
31    /// Previous day's closing price
32    pub prev_closing_price: Decimal,
33
34    /// Change direction (RISE, EVEN, FALL)
35    pub change: String,
36
37    /// Change amount (absolute value)
38    pub change_price: Decimal,
39
40    /// Trade date (KST) in yyyy-MM-dd format
41    pub trade_date: String,
42
43    /// Trade time (KST) in HH:mm:ss format
44    pub trade_time: String,
45
46    /// Trade timestamp in milliseconds
47    pub trade_timestamp: u64,
48
49    /// Sequential ID (unique for each trade)
50    pub sequential_id: u64,
51
52    /// Message timestamp in milliseconds
53    pub timestamp: u64,
54
55    /// Stream type (SNAPSHOT or REALTIME)
56    pub stream_type: String,
57}
58
59/// Processed trade transaction with additional information
60#[derive(Debug, Clone)]
61#[repr(align(64))] // Cache line alignment for better performance
62pub struct Transaction {
63    /// Market code (e.g., "KRW-BTC")
64    pub code: String,
65
66    /// Sequential ID (unique ID for the trade)
67    pub sequential_id: u64,
68
69    /// Trade price
70    pub price: Decimal,
71
72    /// Trade volume
73    pub volume: Decimal,
74
75    /// Trade side (Buy/Sell)
76    pub side: OrderSide,
77
78    /// Trade timestamp in nanoseconds
79    pub trade_timestamp_ns: u64,
80
81    /// Message timestamp in nanoseconds
82    pub timestamp_ns: u64,
83
84    /// Local timestamp when processed (nanoseconds)
85    pub local_time_ns: u64,
86}
87
88impl Transaction {
89    /// Create a new transaction from a trade message
90    #[inline(always)]
91    #[must_use]
92    pub fn from_trade_message(msg: &TradeMessage, local_time_ns: u64) -> Self {
93        let side = match msg.ask_bid.as_str() {
94            "BID" => OrderSide::Buy,
95            _ => OrderSide::Sell,
96        };
97
98        // Convert millisecond timestamps to nanoseconds for HFT precision
99        let trade_timestamp_ns = msg.trade_timestamp * 1_000_000;
100        let timestamp_ns = msg.timestamp * 1_000_000;
101
102        Self {
103            code: msg.code.clone(),
104            sequential_id: msg.sequential_id,
105            price: msg.trade_price,
106            volume: msg.trade_volume,
107            side,
108            trade_timestamp_ns,
109            timestamp_ns,
110            local_time_ns,
111        }
112    }
113}