Skip to main content

df_hyperliquid_core/trade/orders/
limit.rs

1//! Limit orders: `Gtc`, `Ioc` or `Alo` at a price brought onto the grid, never against the
2//! trader. A limit is never `FrontendMarket`.
3
4use crate::trade::error::TradeError;
5use crate::trade::orders::entry::{OrderIntent, Price};
6use crate::trade::orders::{Side, Tif};
7use crate::trade::ticket::{Amount, Refusal, positive};
8use crate::utils::Dec;
9use crate::utils::rounding::Grid;
10
11impl OrderIntent {
12    #[must_use]
13    pub const fn limit(side: Side, amount: Amount, price: Dec, tif: Tif) -> OrderIntent {
14        OrderIntent::at(side, amount, Price::Limit { price, tif })
15    }
16}
17
18/// A limit order's price on the grid, what it is valued at (the same price) and its time in force.
19pub(crate) fn resting(grid: Grid, price: Dec, tif: Tif, side: Side) -> Result<(Dec, Dec, Tif), Refusal> {
20    if matches!(tif, Tif::FrontendMarket) {
21        return Err(Refusal::MarketTif);
22    }
23    let price = limit_on(grid, price, side, "a price")?;
24    Ok((price, price, tif))
25}
26
27/// A limit on the grid for `side`, never against the trader.
28pub(crate) fn limit_on(grid: Grid, price: Dec, side: Side, what: &'static str) -> Result<Dec, Refusal> {
29    let price = positive(price, what)?;
30    grid.price(price, side).ok_or(Refusal::Trade(TradeError::NoPrice(price)))
31}
32
33#[cfg(test)]
34#[path = "tests/limit.rs"]
35mod tests;