ek-data 0.2.5

Trading data contracts for the enkeep ek ecosystem: venue enums, zero-dep epoch-nanosecond time, decimal-exact price rounding, vt-symbol convention, bus event dictionary, tick/bar/order/trade/position/account/contract objects and request objects (Python enkeep_trade trader/object.py + constant.py, faithfully ported).
Documentation
//! 合约对象(`object.py:340-368`)。
//!
//! 对冲组合家族(HedgeContractData / ContractData2 / ProductInfo /
//! HedgeSetting)属组合批次,整族 defer(DESIGN.md defer 清单)。

use crate::constant::{Asset, Exchange, InstrumentType};

/// 合约基础数据。
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ContractData {
    /// 上游网关名
    pub gateway_name: String,
    /// 合约代码
    pub symbol: String,
    /// 交易所
    pub exchange: Exchange,
    /// 合约中文名
    pub name: String,
    /// 资产大类
    pub asset: Asset,
    /// 合约形态(缺省 None)
    pub instrument_type: Option<InstrumentType>,
    /// 合约乘数(Python 缺省 1)
    pub size: f64,
    /// 最小价格变动(Python 缺省 0.01)
    pub price_tick: f64,

    /// 品种代码(期货层级)
    pub product_id: Option<String>,

    /// 限价单最大上量
    pub max_limit_order_volume: Option<f64>,
    /// 限价单最小上量
    pub min_limit_order_volume: Option<f64>,
    /// 市价单最大上量
    pub max_market_order_volume: Option<f64>,
    /// 市价单最小上量
    pub min_market_order_volume: Option<f64>,

    /// 交割年
    pub delivery_year: Option<i32>,
    /// 交割月
    pub delivery_month: Option<i32>,

    // —— 扩展字段(object.py:360-368)——
    /// IPO 日(股票)
    pub open_date: Option<String>,
    /// 前收盘价
    pub pre_close: Option<f64>,
    /// 当日涨停价
    pub up_stop_price: Option<f64>,
    /// 当日跌停价
    pub down_stop_price: Option<f64>,
    /// 流通股本
    pub float_volume: Option<f64>,
    /// 总股本
    pub total_volume: Option<f64>,
    /// 合约停牌状态(上游原值)
    pub instrument_status: Option<i64>,
    /// 是否可交易
    pub is_trading: Option<bool>,
}

impl Default for ContractData {
    /// Python 字段缺省:asset 缺省面 EQUITY、size=1、price_tick=0.01
    /// (`object.py:347-348`;其余 Option 字段一律 None)。
    fn default() -> Self {
        Self {
            asset: Asset::EQUITY,
            size: 1.0,
            price_tick: 0.01,
            ..Self::EMPTY
        }
    }
}

impl ContractData {
    /// `en_symbol`(派生方法;分配一次)。
    pub fn en_symbol(&self) -> String {
        let mut buf = String::with_capacity(self.exchange.as_str().len() + 1 + self.symbol.len());
        self.en_symbol_into(&mut buf);
        buf
    }

    /// 零分配版本:追加到复用缓冲。
    pub fn en_symbol_into(&self, buf: &mut String) {
        crate::symbol::write_vt_symbol(buf, &self.symbol, self.exchange);
    }
}

/// 缺省骨架常量(供 [`Default`] 的 `..Self::EMPTY` 复合;不对外承诺)。
impl ContractData {
    const EMPTY: Self = Self {
        gateway_name: String::new(),
        symbol: String::new(),
        exchange: crate::constant::Exchange::LOCAL,
        name: String::new(),
        asset: Asset::EQUITY,
        instrument_type: None,
        size: 0.0,
        price_tick: 0.0,
        product_id: None,
        max_limit_order_volume: None,
        min_limit_order_volume: None,
        max_market_order_volume: None,
        min_market_order_volume: None,
        delivery_year: None,
        delivery_month: None,
        open_date: None,
        pre_close: None,
        up_stop_price: None,
        down_stop_price: None,
        float_volume: None,
        total_volume: None,
        instrument_status: None,
        is_trading: None,
    };
}