futu_cache/trd_cache/
order_upsert.rs1use super::{CachedOrder, TrdCache};
2use futu_domain_trade_account::{
3 BackendOrderIdentityFacts, OrderUpsertAction, OrderUpsertOrderFacts,
4 backend_order_identity_matches_like_cpp, plan_order_upsert_like_cpp,
5};
6
7impl TrdCache {
8 pub fn upsert_order(&self, acc_id: u64, order: CachedOrder) -> bool {
10 let mut entry = self.orders.entry(acc_id).or_default();
11 if let Some(existing) = entry
12 .iter_mut()
13 .find(|existing| Self::order_identity_matches(existing, &order))
14 {
15 match plan_order_upsert_like_cpp(
16 Some(Self::order_upsert_facts(existing)),
17 Self::order_upsert_facts(&order),
18 ) {
19 OrderUpsertAction::ReplaceExisting => {
20 *existing = order;
21 true
22 }
23 OrderUpsertAction::IgnoreStaleVersion
24 | OrderUpsertAction::IgnoreAuthoritativeExisting
25 | OrderUpsertAction::IgnoreUnchanged => false,
26 OrderUpsertAction::InsertNew => unreachable!("existing order was already matched"),
27 }
28 } else {
29 match plan_order_upsert_like_cpp(None, Self::order_upsert_facts(&order)) {
30 OrderUpsertAction::InsertNew => {
31 entry.push(order);
32 true
33 }
34 OrderUpsertAction::ReplaceExisting
35 | OrderUpsertAction::IgnoreStaleVersion
36 | OrderUpsertAction::IgnoreAuthoritativeExisting
37 | OrderUpsertAction::IgnoreUnchanged => {
38 unreachable!("missing order should plan an insert")
39 }
40 }
41 }
42 }
43
44 fn order_identity_matches(existing: &CachedOrder, incoming: &CachedOrder) -> bool {
45 backend_order_identity_matches_like_cpp(BackendOrderIdentityFacts {
46 existing_order_id: existing.order_id,
47 existing_backend_order_id: &existing.backend_order_id,
48 existing_order_id_ex: &existing.order_id_ex,
49 incoming_order_id: incoming.order_id,
50 incoming_backend_order_id: &incoming.backend_order_id,
51 incoming_order_id_ex: &incoming.order_id_ex,
52 })
53 }
54
55 fn order_upsert_facts(order: &CachedOrder) -> OrderUpsertOrderFacts<'_> {
56 OrderUpsertOrderFacts {
57 order_version: order.order_version,
58 order_status: order.order_status,
59 price: order.price,
60 qty: order.qty,
61 fill_qty: order.fill_qty,
62 aux_price: order.aux_price,
63 trail_type: order.trail_type,
64 trail_value: order.trail_value,
65 trail_spread: order.trail_spread,
66 is_stub: order.is_stub,
67 is_local_order: order.is_local_order,
68 is_pending_broker_confirm: order.is_pending_broker_confirm,
69 backend_order_id: &order.backend_order_id,
70 order_id_ex: &order.order_id_ex,
71 }
72 }
73}