Skip to main content

ek_data/
order_request.rs

1//! 下单请求(`object.py:521-588` + 方法四件套)。
2
3use crate::constant::{Direction, Exchange, Offset, OrderType};
4use crate::order::OrderData;
5
6/// 发往网关的开仓/平仓请求。
7#[derive(Debug, Clone, PartialEq, Default)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct OrderRequest {
10    /// 合约代码
11    pub symbol: String,
12    /// 交易所
13    pub exchange: Exchange,
14    /// 方向(必填)
15    pub direction: Direction,
16    /// 委托类型(Python `type`;Rust 改名避关键字,serde 线上字段名还原为 `"type"`)
17    #[cfg_attr(feature = "serde", serde(rename = "type"))]
18    pub order_type: OrderType,
19    /// 委托量
20    pub volume: f64,
21    /// 委托价(市价单可 0)
22    pub price: f64,
23    /// 开平(缺省 NONE)
24    pub offset: Offset,
25    /// 策略/来源备注
26    pub reference: String,
27    /// 追单统计字段(原委托号)
28    pub old_order_id: String,
29}
30
31impl OrderRequest {
32    /// `en_symbol`(派生方法)。
33    pub fn en_symbol(&self) -> String {
34        crate::symbol::vt_symbol(&self.symbol, self.exchange)
35    }
36
37    /// 生成订单数据(`object.py:541`;补 id/gateway 两字段即成 OrderData;
38    /// reference 一并搬入,对齐原稿 554 行)。
39    pub fn create_order_data(&self, orderid: &str, gateway_name: &str) -> OrderData {
40        OrderData {
41            gateway_name: gateway_name.to_string(),
42            symbol: self.symbol.clone(),
43            exchange: self.exchange,
44            orderid: orderid.to_string(),
45            order_type: self.order_type,
46            direction: Some(self.direction),
47            offset: self.offset,
48            price: self.price,
49            volume: self.volume,
50            reference: self.reference.clone(),
51            ..OrderData::default()
52        }
53    }
54
55    /// 最小交易量校验(`object.py:559`;volume >= min_volume)。
56    pub fn is_min_volume_ok(&self, min_volume: f64) -> bool {
57        self.volume >= min_volume
58    }
59
60    /// 最大交易量校验(`object.py:567`;volume <= max_volume)。
61    pub fn is_max_volume_ok(&self, max_volume: f64) -> bool {
62        self.volume <= max_volume
63    }
64
65    /// 区间校验(`object.py:575`;闭区间 [min_volume, max_volume])。
66    pub fn is_volume_range_ok(&self, min_volume: f64, max_volume: f64) -> bool {
67        self.volume >= min_volume && self.volume <= max_volume
68    }
69
70    /// 倍数校验(`object.py:582`;volume 是 sub_beishu 的整数倍;
71    /// Python 除零会抛 ZeroDivisionError,Rust 版约定返回 false)。
72    pub fn is_volume_beishu_ok(&self, sub_beishu: f64) -> bool {
73        if sub_beishu == 0.0 {
74            return false;
75        }
76        let r = self.volume - (self.volume / sub_beishu).trunc() * sub_beishu;
77        r == 0.0
78    }
79}