use serde::{Deserialize, Serialize};
use crate::Client;
use crate::Error;
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct OrderRequest {
pub account_id: String,
pub symbol: String,
pub quantity: String,
pub order_type: String,
pub trade_action: String,
pub time_in_force: TimeInForce,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit_price: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub stop_price: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct TimeInForce {
#[serde(rename = "Duration")]
pub duration: String,
}
impl TimeInForce {
pub fn day() -> Self {
Self {
duration: "DAY".to_string(),
}
}
pub fn gtc() -> Self {
Self {
duration: "GTC".to_string(),
}
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct OrderGroupRequest {
#[serde(rename = "Type")]
pub group_type: String,
pub orders: Vec<OrderRequest>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct OrderResponse {
pub orders: Option<Vec<OrderConfirmation>>,
pub errors: Option<Vec<OrderError>>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct OrderConfirmation {
pub order_id: Option<String>,
pub message: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct OrderError {
pub error: Option<String>,
pub message: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct ActivationTrigger {
pub key: String,
pub name: String,
#[serde(default)]
pub description: Option<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct ActivationTriggersResponse {
activation_triggers: Vec<ActivationTrigger>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Route {
pub id: String,
pub name: String,
#[serde(default)]
pub asset_types: Vec<String>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct RoutesResponse {
routes: Vec<Route>,
}
impl Client {
pub async fn place_order(&mut self, order: &OrderRequest) -> Result<OrderResponse, Error> {
let resp = self.post("/v3/orderexecution/orders", order).await?;
Ok(resp.json().await?)
}
pub async fn confirm_order(&mut self, order: &OrderRequest) -> Result<OrderResponse, Error> {
let resp = self.post("/v3/orderexecution/orderconfirm", order).await?;
Ok(resp.json().await?)
}
pub async fn cancel_order(&mut self, order_id: &str) -> Result<OrderResponse, Error> {
let resp = self
.delete(&format!("/v3/orderexecution/orders/{order_id}"))
.await?;
Ok(resp.json().await?)
}
pub async fn replace_order(
&mut self,
order_id: &str,
order: &OrderRequest,
) -> Result<OrderResponse, Error> {
let resp = self
.put(&format!("/v3/orderexecution/orders/{order_id}"), order)
.await?;
Ok(resp.json().await?)
}
pub async fn place_order_group(
&mut self,
group: &OrderGroupRequest,
) -> Result<OrderResponse, Error> {
let resp = self.post("/v3/orderexecution/ordergroups", group).await?;
Ok(resp.json().await?)
}
pub async fn confirm_order_group(
&mut self,
group: &OrderGroupRequest,
) -> Result<OrderResponse, Error> {
let resp = self
.post("/v3/orderexecution/ordergroupconfirm", group)
.await?;
Ok(resp.json().await?)
}
pub async fn get_activation_triggers(&mut self) -> Result<Vec<ActivationTrigger>, Error> {
let resp = self.get("/v3/orderexecution/activationtriggers").await?;
let data: ActivationTriggersResponse = resp.json().await?;
Ok(data.activation_triggers)
}
pub async fn get_routes(&mut self) -> Result<Vec<Route>, Error> {
let resp = self.get("/v3/orderexecution/routes").await?;
let data: RoutesResponse = resp.json().await?;
Ok(data.routes)
}
}