architect_api/algo/
twap.rs1use super::*;
2use crate::{symbology::ExecutionVenue, Dir, HumanDuration};
3use anyhow::{bail, Result};
4use chrono::{DateTime, Utc};
5use derive::grpc;
6use rust_decimal::Decimal;
7use rust_decimal_macros::dec;
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
11pub struct TwapAlgo;
12
13impl Algo for TwapAlgo {
14 type Params = TwapParams;
15 type Status = TwapStatus;
16}
17
18pub type TwapAlgoOrder = AlgoOrder<TwapAlgo>;
19
20#[grpc(package = "json.architect")]
21#[grpc(service = "Algo", name = "create_twap_algo_order", response = "TwapAlgoOrder")]
22pub type CreateTwapAlgoOrderRequest = CreateAlgoOrderRequest<TwapAlgo>;
23
24#[grpc(package = "json.architect")]
25#[grpc(service = "Algo", name = "modify_twap_algo_order", response = "TwapAlgoOrder")]
26pub type ModifyTwapAlgoOrderRequest = ModifyAlgoOrderRequest<TwapAlgo>;
27
28#[grpc(package = "json.architect")]
29#[grpc(service = "Algo", name = "twap_algo_order", response = "TwapAlgoOrder")]
30pub type TwapAlgoOrderRequest = AlgoOrderRequest;
31
32#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
33pub struct TwapParams {
34 pub symbol: String,
35 pub execution_venue: ExecutionVenue,
36 pub dir: Dir,
37 pub quantity: Decimal,
38 pub interval: HumanDuration,
39 pub end_time: DateTime<Utc>,
40 pub reject_lockout: HumanDuration,
41 pub take_through_frac: Option<Decimal>,
42}
43
44impl Validate for TwapParams {
45 fn validate(&self) -> Result<()> {
46 if !self.quantity.is_sign_positive() {
47 bail!("quantity must be positive");
48 }
49 if self.interval.num_milliseconds() < 100 {
50 bail!("interval must be >= 100ms");
51 }
52 if self.reject_lockout.num_milliseconds() < 500
53 || self.reject_lockout.num_seconds() > 300
54 {
55 bail!("reject lockout must be between 0.5 seconds and 300 seconds");
56 }
57 if let Some(take_through_frac) = self.take_through_frac {
58 if take_through_frac.is_sign_negative() || take_through_frac > dec!(0.05) {
59 bail!("take_through_frac must be between 0 and 5%");
60 }
61 }
62 Ok(())
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
67pub struct TwapStatus {
68 pub realized_twap: Option<Decimal>,
69 pub quantity_filled: Decimal,
70}