Skip to main content

ek_data/
tick.rs

1//! 行情逐笔快照(`object.py:37-119`,字段逐值复刻 + 方法三层)。
2
3use crate::constant::Exchange;
4use crate::time::DtNs;
5
6/// Tick 数据:最后成交、盘口快照、日内统计。
7///
8/// 字段与 Python `TickData` 同名同义(snake_case);缺省值同 Python(0 / "")。
9#[derive(Debug, Clone, PartialEq, Default)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct TickData {
12    /// 上游网关名(`BaseData.gateway_name`,`object.py:31`)
13    pub gateway_name: String,
14    /// 合约代码
15    pub symbol: String,
16    /// 交易所
17    pub exchange: Exchange,
18    /// 时间戳(UTC 纪元纳秒;Python 为本地 naive datetime)
19    pub datetime: DtNs,
20
21    /// 交易日(缺省 None;Python 缺省空串)
22    pub trading_day: Option<i32>,
23    /// 行动日/自然日(缺省 None;Python 缺省空串)
24    pub action_day: Option<i32>,
25    /// 原始 HH:MM:SS 文本(上游原样)
26    pub update_time: String,
27    /// 毫秒段
28    pub update_millisec: i64,
29
30    /// 合约中文名
31    pub name: String,
32    /// 当日累计成交量
33    pub volume: f64,
34    /// 当日累计成交额
35    pub turnover: f64,
36    /// 持仓量/流通量
37    pub open_interest: f64,
38    /// 最新价
39    pub last_price: f64,
40    /// 本笔成交量
41    pub last_volume: f64,
42    /// 涨停价
43    pub limit_up: f64,
44    /// 跌停价
45    pub limit_down: f64,
46
47    /// 今开
48    pub open_price: f64,
49    /// 最高
50    pub high_price: f64,
51    /// 最低
52    pub low_price: f64,
53    /// 昨收
54    pub pre_close: f64,
55    /// 涨跌幅(%)
56    pub pct_change: f64,
57
58    /// 买一价
59    pub bid_price_1: f64,
60    /// 买二价
61    pub bid_price_2: f64,
62    /// 买三价
63    pub bid_price_3: f64,
64    /// 买四价
65    pub bid_price_4: f64,
66    /// 买五价
67    pub bid_price_5: f64,
68
69    /// 卖一价
70    pub ask_price_1: f64,
71    /// 卖二价
72    pub ask_price_2: f64,
73    /// 卖三价
74    pub ask_price_3: f64,
75    /// 卖四价
76    pub ask_price_4: f64,
77    /// 卖五价
78    pub ask_price_5: f64,
79
80    /// 买一量
81    pub bid_volume_1: f64,
82    /// 买二量
83    pub bid_volume_2: f64,
84    /// 买三量
85    pub bid_volume_3: f64,
86    /// 买四量
87    pub bid_volume_4: f64,
88    /// 买五量
89    pub bid_volume_5: f64,
90
91    /// 卖一量
92    pub ask_volume_1: f64,
93    /// 卖二量
94    pub ask_volume_2: f64,
95    /// 卖三量
96    pub ask_volume_3: f64,
97    /// 卖四量
98    pub ask_volume_4: f64,
99    /// 卖五量
100    pub ask_volume_5: f64,
101
102    /// 本地收包时间(UTC 纪元纳秒;Python 缺省 None)
103    pub localtime: Option<DtNs>,
104}
105
106impl TickData {
107    /// `en_symbol`(Python `__post_init__` 暂存字段的派生方法化)。
108    pub fn en_symbol(&self) -> String {
109        crate::symbol::vt_symbol(&self.symbol, self.exchange)
110    }
111
112    /// tick 是否触及涨停(`object.py:99`;diff 为容差,非负向给)。
113    ///
114    /// 注意原作怪癖(字节级保留):tick 缺省字段(0.0/0.0)时
115    /// `bid_price_1(0) + 0 >= limit_up(0)` 成立 → 返回 true;
116    /// 使用方须先落真实价格再作判,或自行先校验 limit_up>0。
117    pub fn reach_limit_up(&self, diff_price: f64) -> bool {
118        self.bid_price_1 + diff_price >= self.limit_up
119    }
120
121    /// tick 是否触及跌停(`object.py:105`)。
122    pub fn reach_limit_down(&self, diff_price: f64) -> bool {
123        self.ask_price_1 - diff_price <= self.limit_down
124    }
125
126    /// 触及涨停或跌停(`object.py:111`)。
127    pub fn reach_limit(&self, diff_price: f64) -> bool {
128        self.reach_limit_up(diff_price) || self.reach_limit_down(diff_price)
129    }
130}