Skip to main content

CachedOrder

Struct CachedOrder 

Source
pub struct CachedOrder {
Show 37 fields pub order_id: u64, pub order_id_ex: String, pub code: String, pub name: String, pub trd_side: i32, pub order_type: i32, pub order_status: i32, pub qty: f64, pub price: f64, pub fill_qty: f64, pub fill_avg_price: f64, pub create_time: String, pub update_time: String, pub last_err_msg: Option<String>, pub sec_market: Option<i32>, pub create_timestamp: Option<f64>, pub update_timestamp: Option<f64>, pub remark: Option<String>, pub time_in_force: Option<i32>, pub fill_outside_rth: Option<bool>, pub aux_price: Option<f64>, pub trail_type: Option<i32>, pub trail_value: Option<f64>, pub trail_spread: Option<f64>, pub currency: Option<i32>, pub trd_market: Option<i32>, pub backend_order_id: String, pub order_version: i32, pub exchange_code: i32, pub exchange: String, pub security_type: i32, pub session: Option<i32>, pub order_trade_time_type: Option<u32>, pub jp_acc_type: Option<i32>, pub is_stub: bool, pub stub_inserted_at_ms: u64, pub is_pending_broker_confirm: bool,
}
Expand description

缓存的订单 (对齐 C++ Ndt_Trd_Order 全字段)

Fields§

§order_id: u64§order_id_ex: String§code: String§name: String§trd_side: i32§order_type: i32§order_status: i32§qty: f64§price: f64§fill_qty: f64§fill_avg_price: f64§create_time: String§update_time: String§last_err_msg: Option<String>§sec_market: Option<i32>§create_timestamp: Option<f64>§update_timestamp: Option<f64>§remark: Option<String>§time_in_force: Option<i32>§fill_outside_rth: Option<bool>§aux_price: Option<f64>§trail_type: Option<i32>§trail_value: Option<f64>§trail_spread: Option<f64>§currency: Option<i32>§trd_market: Option<i32>§backend_order_id: String

v1.4.106 codex 0219 Finding 4 / 0226 F7: backend snapshot 字段集合.

PlaceOrder ack 后 backend 返 OrderNewRsp.order_id (= szOrderID, 服务端真实订单 id, alphanumeric 字符串). FTAPI Trd_PlaceOrder.S2C.order_id 是这个 string 的 hash (HashStrToU64 结果, 见 trade_query::hash_str_to_u64).

必填语义: ModifyOrder / CancelOrder backend req 的 order_id 字段 必须填 backend szOrderID, 不是 hash. 反模式 (v1.4.105 及以前): 没有 orderIDEx 时直接 order_id_ex.parse().unwrap_or(0) 把 hash 当 backend id 发 — backend 拒错或匹配失败.

修法 (v1.4.106 Finding 1+4): cache 存 backend_order_id (= szOrderID) 字段; trade-write handler 通过 find_order_for_trade_write lookup 拿到 ResolvedOrderContext { backend_order_id, version, exchange, exchange_code, security_type, ... } 后再发 backend req.

§order_version: i32

v1.4.106 codex 0219 Finding 4: backend Order.version (proto field 21).

ModifyOrder backend OrderReplaceReq.order_version 必填 — 让 backend 能拒接收已经被其他客户端改过版本的旧请求. C++ FillModifyOrderReq:736: req.set_order_version((u32_t)order.nVersion).

§exchange_code: i32

v1.4.106 codex 0219 Finding 4: backend Order.exchange_code (proto field 37).

期货所属交易所代码 (e.g. 1 = HKEX, 2 = NYSE 之类, 取值参考 NN_QotMarket). ModifyOrder / CancelOrder backend 必填 (期货必填, 股票为 0). C++ FillModifyOrderReq:773: req.set_exchange_code((u32_t)order.enMktID).

§exchange: String

v1.4.106 codex 0219 Finding 4: backend Order.exchange (proto field 49).

股票所属交易所字符串 (e.g. “SEHK”, “NYSE”, “NASDAQ”). ModifyOrder / CancelOrder backend 必填. C++ FillModifyOrderReq:774: req.set_exchange(order.szExchange).

§security_type: i32

v1.4.106 codex 0219 Finding 4: backend Order.security_type (proto field 29).

取值参考 backend odr_sys_cmn::SecurityType (1=COMMON, 2=OPTION, 4=FUTURES, 5=BOND). CancelOrder single 必填 (req.add_security_type(GetSecurityType(...)), C++ FillCancelOrderReq:817).

§session: Option<i32>

v1.4.98 T1-8 (mobile-source-audit): 美股盘前/盘中/盘后 session 标识. proto/Trd_Common.proto:455 字段 27. 同 time_in_force / fill_outside_rth 系列, 美股 RTH/Pre-Market/After-Hours order routing 显示用.

§order_trade_time_type: Option<u32>

Backend odr_sys_cmn.Order.order_trade_time_type / C++ order.enOrderTradeTimeType.

GetMaxTrdQtys real option IM side request (CMD5004) mirrors C++ NNProto_Trd_MaxQty::QueryOptionIM: when querying max qty for a modification order, the side request forwards the cached backend order’s trade-time type if it is not UNSET.

§jp_acc_type: Option<i32>

v1.4.98 T1-8 (mobile-source-audit): 日本子账户类型 (security_firm=7 FutuJP 时填充). proto/Trd_Common.proto:456 字段 28. 8 enum 值: GENERAL/TOKUTEI/NISA_GENERAL/NISA_TSUMITATE 等 (per docs/reference/rest-api.md D6).

§is_stub: bool

v1.4.90 S BUG-e4da-009: stub 标志。

PlaceOrder/CancelOrder handler 成功响应后立刻 upsert 一个 stub CachedOrder(v1.4.82 A2 / place_order.rs:427),让 /api/orders 0ms 可见。is_stub=true 标记此条尚未被 backend 权威列表 ack。

后续 backend query_orders 返回包含同 order_id 的 enriched 数据时, 经 merge_preserving_stubs 合并 → is_stub=false

历史坑:v1.4.73 A1 PlaceOrder 后 spawn refresh 直接 orders.insert 整覆盖,把刚 upsert 的 stub 抹掉(race 22ms 内即清零)。 跨 v1.4.73 → v1.4.89 7 版未真修。本字段是根因修法的一部分。

§stub_inserted_at_ms: u64

v1.4.90 S BUG-e4da-009: stub 插入时间(unix epoch ms)。

merge_preserving_stubs 用于 evict 老 stub:backend 如果连续多次 不返某 stub order_id 且 stub 已超过 STUB_TTL_MS (30s) → evict。 防止 stub 因 backend 拒单(never appear in list)永久滞留。

0 表示非 stub(与 is_stub=false 配套)。

§is_pending_broker_confirm: bool

v1.4.105 BUG-v1.4.104-001 (P0): broker 异步 confirm 标志.

PlaceOrder backend 同步 ack (CMD 4701 result=0) 仅说明 backend 收到请求, 代表 broker 真的接受订单. C++ OnOMEvent_Reply_PlaceOrder (APIServer_Trd_PlaceOrder.cpp:794) 是异步 event handler — broker 真 confirm 后才 fire set_orderid(nOrderIDHash). backend OrderNewRsp. need_op_confirm (proto field 6, default=true) 即表示 “真 broker confirm 还在路上, 等 OMEvent push (notice_type 4/5/8/100)”.

历史坑 (eli BUG-v1.4.104-001 实锤): v1.4.82-104 stub 上 cache 时直接 视为已确认, 没有 broker async confirm 等待 → 三次不同订单返同 order_id_ex 时客户端看 success → 误以为生效 → 加仓重下 → 风控 auto-cancel error 10003.

语义:

  • true: backend 已 ack 但 broker 未确认 — is_stub=true 时 stub 不进 /api/orders 响应 (filter), 等 push notice_type=4/5/8/100 confirm 后翻 false 才 expose. 30s 内未 confirm → cleanup task 删 stub + warn.
  • false: backend 权威 / broker 已 confirm — 正常 expose 给 client. query_orders 返的所有 order 都是 false (backend list 是 broker-confirmed 的权威列表).

is_stub 关系:

  • is_stub=true && is_pending_broker_confirm=true: 刚 PlaceOrder ack, 还没 push confirm. client 不可见 (Layer 4 filter).
  • is_stub=true && is_pending_broker_confirm=false: backend need_op_confirm= false 路径 (sim 账户 / 立即生效场景). client 可见.
  • is_stub=false: backend authoritative (query_orders 返 / push merge 后). is_pending_broker_confirm 必为 false. client 可见.

Trait Implementations§

Source§

impl Clone for CachedOrder

Source§

fn clone(&self) -> CachedOrder

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for CachedOrder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CachedOrder

Source§

fn default() -> CachedOrder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more