pub mod Status {
pub const PENDING: u8 = 0; pub const ACKED: u8 = 1; pub const PARTIAL: u8 = 2; pub const DEAD: u8 = 3; }
#[derive(Debug, Clone, Copy, Default)]
#[repr(C)]
pub struct OpenOrder {
pub order_id: u64,
pub px_1e9: u64,
pub qty_1e8: i64, pub filled_1e8: i64, pub side: i8, pub status: u8,
pub _pad: [u8; 6],
}
impl OpenOrder {
pub const EMPTY: Self = Self {
order_id: 0,
px_1e9: 0,
qty_1e8: 0,
filled_1e8: 0,
side: 0,
status: 0,
_pad: [0; 6],
};
#[inline(always)]
pub fn is_live(&self) -> bool {
self.status == Status::ACKED || self.status == Status::PARTIAL
}
#[inline(always)]
pub fn is_pending(&self) -> bool {
self.status == Status::PENDING
}
#[inline(always)]
pub fn remaining_1e8(&self) -> i64 {
self.qty_1e8.abs() - self.filled_1e8.abs()
}
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct SymbolMeta {
pub tick_size_1e9: u64,
pub lot_size_1e8: u64,
pub min_qty_1e8: u64,
pub min_notional_1e9: u64,
pub price_precision: u8,
pub qty_precision: u8,
pub _pad: [u8; 6],
}
impl Default for SymbolMeta {
fn default() -> Self {
Self {
tick_size_1e9: 0,
lot_size_1e8: 0,
min_qty_1e8: 0,
min_notional_1e9: 0,
price_precision: 0,
qty_precision: 0,
_pad: [0; 6],
}
}
}
impl SymbolMeta {
pub const EMPTY: Self = Self {
tick_size_1e9: 0,
lot_size_1e8: 0,
min_qty_1e8: 0,
min_notional_1e9: 0,
price_precision: 0,
qty_precision: 0,
_pad: [0; 6],
};
#[inline(always)]
pub fn round_px(&self, px_1e9: u64) -> u64 {
if self.tick_size_1e9 == 0 {
return px_1e9;
}
(px_1e9 / self.tick_size_1e9) * self.tick_size_1e9
}
#[inline(always)]
pub fn round_qty(&self, qty_1e8: i64) -> i64 {
if self.lot_size_1e8 == 0 {
return qty_1e8;
}
let lot = self.lot_size_1e8 as i64;
(qty_1e8 / lot) * lot
}
#[inline(always)]
pub fn check_notional(&self, qty_1e8: i64, px_1e9: u64) -> bool {
if self.min_notional_1e9 == 0 {
return true;
}
let notional = (qty_1e8.unsigned_abs() as u128 * px_1e9 as u128 / 100_000_000) as u64;
notional >= self.min_notional_1e9
}
#[inline(always)]
pub fn check_min_qty(&self, qty_1e8: i64) -> bool {
if self.min_qty_1e8 == 0 {
return true;
}
qty_1e8.unsigned_abs() >= self.min_qty_1e8
}
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct RiskSnapshot {
pub max_position_1e8: i64,
pub max_daily_loss_1e9: i64,
pub max_order_notional_1e9: u64,
pub max_order_rate: u32,
pub reduce_only: u8,
pub _pad: [u8; 3],
}
impl Default for RiskSnapshot {
fn default() -> Self {
Self {
max_position_1e8: 0,
max_daily_loss_1e9: 0,
max_order_notional_1e9: 0,
max_order_rate: 0,
reduce_only: 0,
_pad: [0; 3],
}
}
}
impl RiskSnapshot {
pub const EMPTY: Self = Self {
max_position_1e8: 0,
max_daily_loss_1e9: 0,
max_order_notional_1e9: 0,
max_order_rate: 0,
reduce_only: 0,
_pad: [0; 3],
};
#[inline(always)]
pub fn check_position(&self, current_position_1e8: i64, delta_1e8: i64) -> bool {
if self.max_position_1e8 == 0 {
return true;
}
let projected = current_position_1e8.saturating_add(delta_1e8);
projected.abs() <= self.max_position_1e8
}
}
pub const MAX_ORDERS: usize = 32;
#[derive(Clone, Copy)]
#[repr(C)]
pub struct AlgoState {
pub position_1e8: i64, pub avg_entry_1e9: u64, pub realized_pnl_1e9: i64, pub unrealized_pnl_1e9: i64, pub orders: [OpenOrder; MAX_ORDERS],
pub order_ct: u8,
pub _pad: [u8; 7],
pub session_pnl_1e9: i64, pub total_fill_count: u64, pub symbol: SymbolMeta, pub risk: RiskSnapshot, pub mesh_id: u64,
pub mesh_peer_count: u8,
pub _mesh_pad: [u8; 7],
pub mesh_peers: [u64; 16],
pub symbol_id: u16,
pub _sym_pad: [u8; 6],
pub symbol_name: [u8; 16],
}
impl Default for AlgoState {
fn default() -> Self {
Self {
position_1e8: 0,
avg_entry_1e9: 0,
realized_pnl_1e9: 0,
unrealized_pnl_1e9: 0,
orders: [OpenOrder::EMPTY; MAX_ORDERS],
order_ct: 0,
_pad: [0; 7],
session_pnl_1e9: 0,
total_fill_count: 0,
symbol: SymbolMeta::EMPTY,
risk: RiskSnapshot::EMPTY,
mesh_id: 0,
mesh_peer_count: 0,
_mesh_pad: [0; 7],
mesh_peers: [0; 16],
symbol_id: 0,
_sym_pad: [0; 6],
symbol_name: [0; 16],
}
}
}
impl AlgoState {
pub fn symbol_name(&self) -> &str {
let end = self.symbol_name.iter().position(|&b| b == 0).unwrap_or(16);
core::str::from_utf8(&self.symbol_name[..end]).unwrap_or("")
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct PnlSnapshot {
pub realized_1e9: i64,
pub unrealized_1e9: i64,
pub total_1e9: i64,
}
impl AlgoState {
#[inline(always)]
pub fn is_flat(&self) -> bool {
self.position_1e8 == 0
}
#[inline(always)]
pub fn is_long(&self) -> bool {
self.position_1e8 > 0
}
#[inline(always)]
pub fn is_short(&self) -> bool {
self.position_1e8 < 0
}
#[inline(always)]
pub fn has_orders(&self) -> bool {
self.order_ct > 0
}
#[inline(always)]
pub fn live_order_count(&self) -> usize {
let mut ct = 0;
for i in 0..self.order_ct as usize {
if self.orders[i].is_live() {
ct += 1;
}
}
ct
}
#[inline(always)]
pub fn find_order(&self, order_id: u64) -> Option<&OpenOrder> {
for i in 0..self.order_ct as usize {
if self.orders[i].order_id == order_id {
return Some(&self.orders[i]);
}
}
None
}
#[inline(always)]
pub fn open_buy_qty_1e8(&self) -> i64 {
let mut sum = 0i64;
for i in 0..self.order_ct as usize {
let o = &self.orders[i];
if o.is_live() && o.side > 0 {
sum += o.remaining_1e8();
}
}
sum
}
#[inline(always)]
pub fn open_sell_qty_1e8(&self) -> i64 {
let mut sum = 0i64;
for i in 0..self.order_ct as usize {
let o = &self.orders[i];
if o.is_live() && o.side < 0 {
sum += o.remaining_1e8();
}
}
sum
}
#[inline(always)]
pub fn total_pnl_1e9(&self) -> i64 {
self.realized_pnl_1e9 + self.unrealized_pnl_1e9
}
#[inline(always)]
pub fn get_pnl(&self) -> PnlSnapshot {
PnlSnapshot {
realized_1e9: self.realized_pnl_1e9,
unrealized_1e9: self.unrealized_pnl_1e9,
total_1e9: self.total_pnl_1e9(),
}
}
#[inline(always)]
pub fn realized_pnl_usd(&self) -> f64 {
self.realized_pnl_1e9 as f64 / 1e9
}
#[inline(always)]
pub fn unrealized_pnl_usd(&self) -> f64 {
self.unrealized_pnl_1e9 as f64 / 1e9
}
#[inline(always)]
pub fn total_pnl_usd(&self) -> f64 {
self.total_pnl_1e9() as f64 / 1e9
}
#[inline(always)]
pub fn session_pnl_usd(&self) -> f64 {
self.session_pnl_1e9 as f64 / 1e9
}
}