Skip to main content

ek_data/
position.rs

1//! 持仓对象(`object.py:235-264`;含迅投 XtPosition 扩展字段)。
2
3use crate::constant::{Direction, Exchange};
4
5/// 逐向持仓数据。
6#[derive(Debug, Clone, PartialEq, Default)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub struct PositionData {
9    /// 上游网关名
10    pub gateway_name: String,
11    /// 合约代码
12    pub symbol: String,
13    /// 交易所
14    pub exchange: Exchange,
15    /// 方向(Python 必填;Rust `Default` 为 [`Direction::NET`],见 constant.rs 说明)
16    pub direction: Direction,
17
18    /// 持仓量
19    pub volume: f64,
20    /// 冻结量
21    pub frozen: f64,
22    /// 持仓均价(网关侧口径)
23    pub price: f64,
24    /// 持仓盈亏
25    pub pnl: f64,
26    /// 隔夜仓量(Yesterday)
27    pub yd_volume: f64,
28
29    // —— 迅投 XtPosition 扩展(object.py:250-257)——
30    /// 证券名称
31    pub name: String,
32    /// 可用数量
33    pub can_use_volume: f64,
34    /// 市值
35    pub market_value: f64,
36    /// 在途股份
37    pub on_road_volume: f64,
38    /// 成本价
39    pub avg_price: f64,
40    /// 最新价
41    pub last_price: f64,
42    /// 盈亏比例
43    pub profit_rate: f64,
44}
45
46impl PositionData {
47    /// `en_symbol`(派生方法;分配一次)。
48    pub fn en_symbol(&self) -> String {
49        let mut buf = String::with_capacity(self.exchange.as_str().len() + 1 + self.symbol.len());
50        self.en_symbol_into(&mut buf);
51        buf
52    }
53
54    /// 零分配版本:追加到复用缓冲。
55    pub fn en_symbol_into(&self, buf: &mut String) {
56        crate::symbol::write_vt_symbol(buf, &self.symbol, self.exchange);
57    }
58
59    /// `en_positionid` =
60    /// `"{gateway_name}.{en_symbol}.{direction 线值}"`(`object.py:262-264`)。
61    ///
62    /// 注意:Python 版第三段用中文线值(`"多"`),Rust 版依线值决定 3 用英文
63    /// (`"LONG"`/`"SHORT"`/`"NET"`;DESIGN.md 决定 3)。
64    pub fn en_positionid(&self) -> String {
65        format!(
66            "{}.{}.{}",
67            self.gateway_name,
68            self.en_symbol(),
69            self.direction.as_str()
70        )
71    }
72}