architect_api/algo/
mod.rs

1use crate::{OrderId, TraderIdOrEmail, UserId};
2use anyhow::Result;
3use chrono::{DateTime, Utc};
4use derive::grpc;
5use derive_more::{Display, FromStr};
6use schemars::{JsonSchema, JsonSchema_repr};
7use serde::{de::DeserializeOwned, Deserialize, Serialize};
8use serde_json::value::RawValue;
9use serde_repr::{Deserialize_repr, Serialize_repr};
10use strum::FromRepr;
11
12pub mod builder;
13pub mod common_params;
14pub mod release_at_time;
15pub mod twap;
16
17pub trait Algo {
18    const NAME: &'static str;
19
20    type Params: std::fmt::Debug
21        + Clone
22        + Validate
23        + DisplaySymbols
24        + Serialize
25        + DeserializeOwned
26        + JsonSchema
27        + Send
28        + 'static;
29
30    type Status: std::fmt::Debug
31        + Clone
32        + Default
33        + Serialize
34        + DeserializeOwned
35        + JsonSchema;
36}
37
38pub trait DisplaySymbols {
39    fn display_symbols(&self) -> Option<Vec<String>> {
40        None
41    }
42}
43
44impl DisplaySymbols for () {}
45
46#[grpc(package = "json.architect")]
47#[grpc(service = "Algo", name = "create_algo_order", response = "AlgoOrder")]
48#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
49pub struct CreateAlgoOrderRequest {
50    pub algo: String,
51    pub id: Option<OrderId>,
52    pub parent_id: Option<OrderId>,
53    pub trader: Option<TraderIdOrEmail>,
54    pub params: Box<RawValue>,
55}
56
57impl CreateAlgoOrderRequest {
58    pub fn builder(algo: impl AsRef<str>) -> builder::CreateAlgoOrderRequestBuilder {
59        builder::CreateAlgoOrderRequestBuilder::new(algo)
60    }
61}
62
63#[grpc(package = "json.architect")]
64#[grpc(service = "Algo", name = "modify_algo_order", response = "AlgoOrder")]
65#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
66pub struct ModifyAlgoOrderRequest {
67    pub algo_order_id: OrderId,
68    pub params: Box<RawValue>,
69}
70
71#[grpc(package = "json.architect")]
72#[grpc(service = "Algo", name = "start_algo", response = "StartAlgoResponse")]
73#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
74pub struct StartAlgoRequest {
75    pub algo_order_id: OrderId,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
79pub struct StartAlgoResponse {}
80
81#[grpc(package = "json.architect")]
82#[grpc(service = "Algo", name = "pause_algo", response = "PauseAlgoResponse")]
83#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
84pub struct PauseAlgoRequest {
85    pub algo_order_id: OrderId,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
89pub struct PauseAlgoResponse {}
90
91#[grpc(package = "json.architect")]
92#[grpc(service = "Algo", name = "stop_algo", response = "StopAlgoResponse")]
93#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
94pub struct StopAlgoRequest {
95    pub algo_order_id: OrderId,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
99pub struct StopAlgoResponse {}
100
101/// Get generic algo run status
102#[grpc(package = "json.architect")]
103#[grpc(service = "Algo", name = "algo_order", response = "AlgoOrder")]
104#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
105pub struct AlgoOrderRequest {
106    pub algo_order_id: OrderId,
107}
108
109/// Find all algo orders matching the given criteria.
110///
111/// If limit is not specified, it will default to 100.
112#[grpc(package = "json.architect")]
113#[grpc(service = "Algo", name = "algo_orders", response = "AlgoOrdersResponse")]
114#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
115pub struct AlgoOrdersRequest {
116    pub algo: Option<String>,
117    pub parent_order_id: Option<OrderId>,
118    pub trader: Option<TraderIdOrEmail>,
119    pub display_symbol: Option<String>,
120    pub status: Option<Vec<AlgoOrderStatus>>,
121    pub from_inclusive: Option<DateTime<Utc>>,
122    pub to_exclusive: Option<DateTime<Utc>>,
123    pub limit: Option<u32>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
127pub struct AlgoOrdersResponse {
128    pub algo_orders: Vec<AlgoOrder>,
129}
130
131impl Algo for () {
132    const NAME: &'static str = "UNKNOWN";
133
134    type Params = ();
135    type Status = ();
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
139pub struct AlgoOrder {
140    pub algo: String,
141    pub id: OrderId,
142    pub parent_id: Option<OrderId>,
143    pub create_time: DateTime<Utc>,
144    /// If the algo order is stopped, the time at which it was stopped.
145    pub finish_time: Option<DateTime<Utc>>,
146    /// If the algo order is stopped, whether the stop was successful.
147    pub finish_success: Option<bool>,
148    pub status: AlgoOrderStatus,
149    pub status_details: Box<RawValue>,
150    /// If algo order status is rejected, contains the reject reason;
151    /// for algo orders that finished unsuccessfully, contains the error reason.
152    pub reject_or_error_reason: Option<String>,
153    pub display_symbols: Option<Vec<String>>,
154    pub trader: UserId,
155    pub params: Box<RawValue>,
156    /// Progress of the algo, 0.0 to 1.0, if computable
157    pub working_progress: Option<f64>,
158    pub num_sent_orders: u32,
159    pub num_open_orders: u32,
160    pub num_rejects: u32,
161    pub num_errors: u32,
162}
163
164#[derive(
165    Debug,
166    Display,
167    FromStr,
168    FromRepr,
169    Clone,
170    Copy,
171    PartialEq,
172    Eq,
173    Serialize_repr,
174    Deserialize_repr,
175    JsonSchema_repr,
176)]
177#[serde(rename_all = "snake_case")]
178#[repr(u8)]
179pub enum AlgoOrderStatus {
180    // Pending = 0,
181    Working = 1,
182    Rejected = 2,
183    Paused = 63,
184    // Pausing = 64,
185    // Stopping = 128,
186    Stopped = 127, // same as paused but final
187}
188
189impl AlgoOrderStatus {
190    pub fn is_alive(&self) -> bool {
191        matches!(self, AlgoOrderStatus::Working | AlgoOrderStatus::Paused)
192    }
193}
194
195// CR-someday alee: use something more akin to the validator crate
196pub trait Validate {
197    fn validate(&self) -> Result<()> {
198        Ok(())
199    }
200}
201
202impl Validate for () {}
203
204#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
205pub struct AlgoLog {}