df_papertrade_core/trade/writes/
open.rs1use df_hyperliquid_core::client::Http;
5use df_hyperliquid_core::utils::Address;
6
7use crate::account::Account;
8use crate::account::store::Store;
9use crate::client::{Accepted, Client, Error};
10use crate::trade::{Intent, OpenPosition, deadline, math};
11use crate::utils::Lane;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub struct Open {
16 pub instrument_id: u32,
17 pub is_long: bool,
18 pub margin: u128,
20 pub leverage: u32,
22 pub use_debt: bool,
24}
25
26impl<H: Http + Clone> Client<H> {
27 pub async fn open(
31 &self,
32 store: &impl Store,
33 owner: Address,
34 account: &Account,
35 open: Open,
36 mark: Option<u128>,
37 ) -> Result<Accepted, Error> {
38 let state = self.trading_state().await?;
39 let instrument = state
40 .instrument(open.instrument_id)
41 .ok_or_else(|| Error::Invalid(format!("no market {}", open.instrument_id)))?;
42 let (available, room) = if open.use_debt {
43 let room = math::debt_room(account.consumable_debt, account.queued, account.funds.available_queued);
44 (account.funds.available_queued, Some(room))
45 } else {
46 (account.funds.available_balance, None)
47 };
48 math::check_open(&state, instrument, open.is_long, open.margin, open.leverage, mark, available, room)?;
49 let key = self.session_key(store, owner, Some(account)).await?;
50 let nonce = self.take_nonce(store, owner, Lane::Exchange).await?;
51 let intent = OpenPosition::new(
52 owner,
53 open.instrument_id,
54 open.is_long,
55 open.margin,
56 open.leverage,
57 open.use_debt,
58 nonce,
59 deadline(self.now_ms()),
60 )?;
61 let signed =
62 key.sign(Intent::OpenPosition(intent), self.now_ms()).map_err(|e| Error::Signature(e.to_string()))?;
63 self.submit(&signed).await
64 }
65}