use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use super::common::{ClientOrderId, OrderId, Price, Quantity, Side, Symbol, Timestamp};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum OrderType {
Market,
Limit,
Conditional,
Tpsl,
#[serde(other)]
Unknown,
}
impl OrderType {
pub const fn as_str(self) -> &'static str {
match self {
Self::Market => "market",
Self::Limit => "limit",
Self::Conditional => "conditional",
Self::Tpsl => "tpsl",
Self::Unknown => "unknown",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum OrderStatus {
PendingNew,
New,
PartiallyFilled,
Filled,
Cancelled,
Rejected,
Replaced,
#[serde(other)]
Unknown,
}
impl OrderStatus {
pub const fn as_str(self) -> &'static str {
match self {
Self::PendingNew => "pending_new",
Self::New => "new",
Self::PartiallyFilled => "partially_filled",
Self::Filled => "filled",
Self::Cancelled => "cancelled",
Self::Rejected => "rejected",
Self::Replaced => "replaced",
Self::Unknown => "unknown",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TimeInForce {
Gtc,
Ioc,
Fok,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExecutionInstruction {
AllowTaker,
PostOnly,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TriggerType {
Market,
Limit,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TriggerDirection {
Ge,
Le,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderTrigger {
#[serde(with = "rust_decimal::serde::str")]
pub trigger_price: Decimal,
#[serde(rename = "type")]
pub trigger_type: TriggerType,
pub trigger_direction: TriggerDirection,
#[serde(
with = "rust_decimal::serde::str_option",
default,
skip_serializing_if = "Option::is_none"
)]
pub limit_price: Option<Decimal>,
pub time_in_force: TimeInForce,
#[serde(default)]
pub execution_instructions: Vec<ExecutionInstruction>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Order {
pub id: OrderId,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub previous_order_id: Option<OrderId>,
pub client_order_id: ClientOrderId,
pub symbol: Symbol,
pub side: Side,
#[serde(rename = "type")]
pub order_type: OrderType,
#[serde(with = "rust_decimal::serde::str")]
pub quantity: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub filled_quantity: Decimal,
#[serde(with = "rust_decimal::serde::str")]
pub leaves_quantity: Decimal,
#[serde(
with = "rust_decimal::serde::str_option",
default,
skip_serializing_if = "Option::is_none"
)]
pub amount: Option<Decimal>,
#[serde(
with = "rust_decimal::serde::str_option",
default,
skip_serializing_if = "Option::is_none"
)]
pub filled_amount: Option<Decimal>,
#[serde(
with = "rust_decimal::serde::str_option",
default,
skip_serializing_if = "Option::is_none"
)]
pub price: Option<Decimal>,
#[serde(
with = "rust_decimal::serde::str_option",
default,
skip_serializing_if = "Option::is_none"
)]
pub average_fill_price: Option<Decimal>,
pub status: OrderStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reject_reason: Option<String>,
pub time_in_force: TimeInForce,
#[serde(default)]
pub execution_instructions: Vec<ExecutionInstruction>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub conditional: Option<OrderTrigger>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub take_profit: Option<OrderTrigger>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub stop_loss: Option<OrderTrigger>,
#[serde(
with = "rust_decimal::serde::str_option",
default,
skip_serializing_if = "Option::is_none"
)]
pub total_fee: Option<Decimal>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fee_currency: Option<String>,
pub created_date: Timestamp,
pub updated_date: Timestamp,
}
pub type OrderDetails = Order;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderAck {
pub venue_order_id: OrderId,
pub client_order_id: ClientOrderId,
pub state: OrderStatus,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LimitOrderConfiguration {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_size: Option<Quantity>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub quote_size: Option<Quantity>,
pub price: Price,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub execution_instructions: Option<Vec<ExecutionInstruction>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MarketOrderConfiguration {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_size: Option<Quantity>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub quote_size: Option<Quantity>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderConfiguration {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<LimitOrderConfiguration>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub market: Option<MarketOrderConfiguration>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OrderPlacementRequest {
pub client_order_id: ClientOrderId,
pub symbol: Symbol,
pub side: Side,
pub order_configuration: OrderConfiguration,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct OrderReplacementRequest {
pub client_order_id: ClientOrderId,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_size: Option<Quantity>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub quote_size: Option<Quantity>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub price: Option<Price>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub execution_instructions: Option<Vec<ExecutionInstruction>>,
}