df_hyperliquid_core/trade/orders/
close.rs1use crate::trade::builder::BuilderSetting;
4use crate::trade::error::TradeError;
5use crate::trade::orders::{Cloid, Order, PlaceOrder, Side};
6use crate::trade::ticket::{Market, Refusal, at_least, positive, routed};
7use crate::utils::Dec;
8use crate::utils::rounding::MINIMUM_ORDER_VALUE;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct Close {
13 pub position: Dec,
16 pub size: Option<Dec>,
17 pub reference: Dec,
18 pub slippage: Dec,
19 pub cloid: Option<Cloid>,
20}
21
22impl Close {
23 #[must_use]
25 pub const fn new(position: Dec, reference: Dec, slippage: Dec) -> Close {
26 Close { position, size: None, reference, slippage, cloid: None }
27 }
28
29 #[must_use]
30 pub const fn with_cloid(mut self, cloid: Cloid) -> Close {
31 self.cloid = Some(cloid);
32 self
33 }
34}
35
36pub fn close(market: &Market, intent: &Close, builder: Option<&BuilderSetting>) -> Result<PlaceOrder, Refusal> {
40 if market.is_spot() {
41 return Err(Refusal::Spot("a position"));
42 }
43 if intent.position.is_zero() {
44 return Err(Refusal::NoPosition);
45 }
46 let side = match intent.position.is_positive() {
47 true => Side::Sell,
48 false => Side::Buy,
49 };
50 let held = intent.position.abs();
51 let wanted = match intent.size {
52 None => held,
53 Some(size) if positive(size, "a size")? > held => {
54 return Err(Refusal::CloseTooLarge { size, position: held });
55 }
56 Some(size) => size,
57 };
58 let size = market.grid().size(wanted).ok_or(Refusal::Trade(TradeError::NoSize(wanted)))?;
59 let reference = positive(intent.reference, "a reference price")?;
60 let bound = market.grid().market_bound(reference, intent.slippage, side)?;
61 if size != held {
62 at_least(size, reference, MINIMUM_ORDER_VALUE)?;
63 }
64 let order = Order::market(market.asset(), side, bound, size).reduce_only();
65 let order = match intent.cloid {
66 Some(cloid) => order.with_cloid(cloid),
67 None => order,
68 };
69 routed(PlaceOrder::one(order), builder)
70}
71
72#[cfg(test)]
73#[path = "tests/close.rs"]
74mod tests;