use crate::{
book::common::events::CancelCause,
book::protocol::{
command::{Persistence, Side},
reject::RejectReason,
},
types::*,
};
use std::collections::VecDeque;
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
strum::Display,
strum::AsRefStr,
)]
pub enum BookMarketState {
Open,
TurnInPlayEnabled,
Suspended,
Halted,
Closed,
Voided,
Settled,
}
impl BookMarketState {
pub fn is_matchable(self) -> bool {
matches!(self, Self::Open | Self::TurnInPlayEnabled)
}
pub fn is_terminal(self) -> bool {
matches!(self, Self::Closed | Self::Voided | Self::Settled)
}
pub fn is_halted(self) -> bool {
matches!(self, Self::Halted)
}
}
pub fn ensure_can_accept_new_orders(state: BookMarketState) -> Result<(), RejectReason> {
if state.is_matchable() {
Ok(())
} else {
Err(RejectReason::MarketNotOpen)
}
}
pub fn ensure_state_change(
current: BookMarketState,
to: BookMarketState,
) -> Result<(), crate::book::protocol::reject::RejectReason> {
if current == to {
return Err(crate::book::protocol::reject::RejectReason::NoChange);
}
Ok(())
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub struct CloseProcessState {
pub batch_max_events: u16,
pub cursor_after: Option<OrderId>,
pub total_live_orders: u64,
pub cancelled_total: u64,
pub chunks_done: u32,
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub struct CancelProcessState {
pub batch_max_events: u16,
pub cursor_after: Option<OrderId>,
pub started_at_ms: i64,
pub from_created_at_inclusive_ms: Option<i64>,
pub to_created_at_inclusive_ms: Option<i64>,
pub account_filter: Option<AccountId>,
pub runner_filter: Option<RunnerId>,
pub reason: String,
pub final_event_metadata_json: Option<String>,
pub cancelled_total: u64,
pub chunks_done: u32,
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub struct OrderBatchProcessState {
pub batch_max_events: u16,
pub cursor_after: Option<OrderId>,
pub cancel_cause: CancelCause,
pub cause_detail: Option<String>,
pub processed_total: u64,
pub chunks_done: u32,
}
#[derive(
Debug,
Clone,
PartialEq,
Eq,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub enum BatchProcessState {
Close(CloseProcessState),
Cancel(CancelProcessState),
Lapse(OrderBatchProcessState),
Void(OrderBatchProcessState),
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
strum::Display,
strum::AsRefStr,
)]
pub enum BookOrderState {
ExecutableUnmatched,
ExecutablePartiallyMatched,
ExecutionComplete,
Cancelled,
Lapsed,
Voided,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
Hash,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub enum RunnerResult {
Winner,
Loser,
Removed,
RemovedVacant,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub struct SignedMoney(pub i64);
impl SignedMoney {
pub fn zero() -> Self {
Self(0)
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BookOrderInfo {
pub order_id: OrderId,
pub account_id: AccountId,
pub correlation_id: Option<CorrelationId>,
pub side: Side,
pub state: BookOrderState,
pub created_at: DateTime,
pub last_updated_at: DateTime,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BookOrder {
pub info: BookOrderInfo,
pub runner_id: RunnerId,
pub price: OddsX10000,
pub stake: Money,
pub matched: Money,
pub persistence: Persistence,
}
impl BookOrder {
pub fn remaining(&self) -> Money {
Money(self.stake.0.saturating_sub(self.matched.0).max(0))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct PriceSize {
pub price: OddsX10000,
pub size: Money,
}
#[derive(Debug, Clone, Default)]
pub struct RunnerPrices {
pub runner_id: RunnerId,
pub available_to_back: Vec<PriceSize>,
pub available_to_lay: Vec<PriceSize>,
}
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
serde::Serialize,
serde::Deserialize,
rkyv::Archive,
rkyv::Serialize,
rkyv::Deserialize,
)]
pub struct BinaryPriceSize {
pub price_ticks: u16,
pub size_shares: u64,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct BinaryDepth {
pub max_price_ticks: u16,
pub bids: Vec<BinaryPriceSize>,
pub asks: Vec<BinaryPriceSize>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PriceLevel {
pub fifo: VecDeque<OrderId>,
pub total_remaining: Money,
}
impl PriceLevel {
pub fn new() -> Self {
Self {
fifo: VecDeque::new(),
total_remaining: Money::zero(),
}
}
}
impl Default for PriceLevel {
fn default() -> Self {
Self::new()
}
}