1use crate::{
2 folio::{AccountBalances, AccountPositions, AccountStatistics},
3 orderflow::{Cancel, Order},
4 symbology::{ExecutionInfo, ExecutionVenue, TradableProduct},
5 AccountId, AccountIdOrName, UserId,
6};
7use derive::grpc;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use std::collections::BTreeMap;
11use uuid::Uuid;
12
13pub mod cpty_id;
14
15pub use cpty_id::CptyId;
16
17#[grpc(package = "json.architect")]
18#[grpc(service = "Cpty", name = "cpty", response = "CptyResponse", server_streaming)]
19#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
20#[serde(tag = "t", rename_all = "snake_case")]
21pub enum CptyRequest {
23 #[schemars(title = "Login|CptyLoginRequest")]
24 Login(CptyLoginRequest),
25 #[schemars(title = "Logout|CptyLogoutRequest")]
26 Logout(CptyLogoutRequest),
27 #[schemars(title = "PlaceOrder|Order")]
28 PlaceOrder(Order),
29 #[schemars(title = "PlaceBatchOrder|BatchOrder")]
30 PlaceBatchOrder { orders: Vec<Order> },
31 #[schemars(title = "CancelOrder")]
32 CancelOrder { cancel: Cancel, original_order: Option<Order> },
33 #[schemars(title = "CancelAllOrders")]
34 CancelAllOrders {
35 cancel_id: Uuid,
36 trader: Option<UserId>,
37 account: Option<AccountId>,
38 },
39 #[schemars(title = "BatchCancelOrders")]
40 BatchCancelOrders { cancels: Vec<Cancel>, original_orders: Vec<Option<Order>> },
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
44pub struct CptyLoginRequest {
45 pub trader: UserId,
46 pub account: AccountId,
47}
48
49#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
50pub struct CptyLogoutRequest {}
51
52#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
53#[serde(tag = "t", rename_all = "snake_case")]
54pub enum CptyResponse {
56 #[serde(rename = "xs")]
57 #[schemars(title = "Symbology")]
58 Symbology {
59 execution_info:
60 BTreeMap<TradableProduct, BTreeMap<ExecutionVenue, ExecutionInfo>>,
61 },
62 #[serde(rename = "ro")]
63 #[schemars(title = "ReconcileOrder|Order")]
64 ReconcileOrder(Order),
65 #[serde(rename = "oo")]
66 #[schemars(title = "ReconcileOpenOrders")]
67 ReconcileOpenOrders {
68 orders: Vec<Order>,
69 snapshot_for_account: Option<AccountIdOrName>,
70 },
71 #[serde(rename = "as")]
72 #[schemars(title = "UpdateAccountSummary")]
73 UpdateAccountSummary {
74 account: AccountIdOrName,
75 timestamp: i64,
76 timestamp_ns: u32,
77 #[serde(default)]
78 balances: Option<AccountBalances>,
79 #[serde(default)]
80 positions: Option<AccountPositions>,
81 #[serde(default)]
82 statistics: Option<AccountStatistics>,
83 is_snapshot: bool,
84 },
85}
86
87#[grpc(package = "json.architect")]
88#[grpc(service = "Cpty", name = "cpty_status", response = "CptyStatus")]
89#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
90pub struct CptyStatusRequest {
91 pub kind: String,
92 pub instance: Option<String>,
93}
94
95#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
96pub struct CptyStatus {
97 pub kind: String,
98 pub instance: Option<String>,
99 pub connected: bool,
100 pub logged_in: Option<bool>,
102 pub stale: bool,
103 pub connections: BTreeMap<String, ConnectionStatus>,
104}
105
106impl CptyStatus {
107 pub fn new(id: CptyId) -> Self {
108 Self {
109 kind: id.kind.to_string(),
110 instance: id.instance.map(|s| s.to_string()),
111 connected: true,
112 logged_in: None,
113 stale: false,
114 connections: BTreeMap::new(),
115 }
116 }
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
120pub struct ConnectionStatus {
121 pub connected: bool,
122 pub logged_in: Option<bool>,
124 pub last_heartbeat: i64,
126 pub last_heartbeat_stale_threshold: i64,
128}
129
130#[grpc(package = "json.architect")]
131#[grpc(service = "Cpty", name = "cptys", response = "CptysResponse")]
132#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
133pub struct CptysRequest {}
134
135#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
136pub struct CptysResponse {
137 pub cptys: Vec<CptyStatus>,
138}