diff --git a/pulse-sdk/src/general.rs b/pulse-sdk/src/general.rs index fd70443..565523e 100644 --- a/pulse-sdk/src/general.rs +++ b/pulse-sdk/src/general.rs @@ -66,6 +66,7 @@ pub struct EngineStatus { pub perps_equity: Decimal, pub strategy_mode: Mode, pub strategy_state: ItemState, + pub positions: Vec, } impl std::fmt::Display for MarketTrend { diff --git a/pulse-sdk/src/terminal.rs b/pulse-sdk/src/terminal.rs index db231be..a046ace 100644 --- a/pulse-sdk/src/terminal.rs +++ b/pulse-sdk/src/terminal.rs @@ -11,9 +11,6 @@ pub enum TerminalServerMessage { // WatchList WatchListUpdated(Vec), - // Positions - PositionsUpdated(Vec), - // Configuration ConfigUpdated(EngineConfig), diff --git a/src/engine/engine/mod.rs b/src/engine/engine/mod.rs index c062433..141682d 100644 --- a/src/engine/engine/mod.rs +++ b/src/engine/engine/mod.rs @@ -69,6 +69,7 @@ impl Engine { perps_equity: 0.into(), strategy_mode: Mode::Auto, strategy_state: ItemState::Stopped, + positions: Vec::new(), })), watch_list: Arc::new(Mutex::new(WatchList { name_to_index: HashMap::new(), diff --git a/src/engine/engine/terminal.rs b/src/engine/engine/terminal.rs index 20d700e..20ab85b 100644 --- a/src/engine/engine/terminal.rs +++ b/src/engine/engine/terminal.rs @@ -227,24 +227,23 @@ impl TerminalServer { if let Some(acc) = engine.accounts.lock().await.get_active() { match client.clearinghouse_state(acc.address, None).await { Ok(state) => { - engine.status.lock().await.perps_equity = - state.margin_summary.account_value; + let mut status = engine.status.lock().await; + + status.perps_equity = state.margin_summary.account_value; + status.positions = state + .asset_positions + .into_iter() + .map(|position| Position { + symbol: position.position.coin, + size: position.position.szi, + entry_price: position.position.entry_px.unwrap_or_default(), + pnl: position.position.unrealized_pnl, + }) + .collect(); + + drop(status); engine.update_status().await?; - - self.broadcast(TerminalServerMessage::PositionsUpdated( - state - .asset_positions - .into_iter() - .map(|position| Position { - symbol: position.position.coin, - size: position.position.szi, - entry_price: position.position.entry_px.unwrap_or_default(), - pnl: position.position.unrealized_pnl, - }) - .collect(), - )) - .await?; } Err(e) => { self.error("orders", &format!("Unable to get open orders: {e}")) diff --git a/src/terminal/main.rs b/src/terminal/main.rs index dc8cb13..05aa89a 100644 --- a/src/terminal/main.rs +++ b/src/terminal/main.rs @@ -33,7 +33,6 @@ pub struct PulseTradeApp { status: State>, watch_list: State>, - active_positions: State>, logs: State>, signals: State>, inspect: State, @@ -128,7 +127,10 @@ impl App for PulseTradeApp { ( LayoutItem::Widget(Size::Flex(1)), Box::new( - advanced_draw(&self.scroll, 1, "POSITIONS", &self.active_positions).await, + advanced_draw_map(&self.scroll, 1, "POSITIONS", &self.status, |status| { + &status.positions + }) + .await, ), ), ( @@ -177,7 +179,6 @@ async fn main() -> tokio::io::Result<()> { command: ctx.use_state(InputState::new()), scroll: ctx.use_state(ScrollState(1, [0; 7])), watch_list: ctx.use_state(Vec::new()), - active_positions: ctx.use_state(Vec::new()), signals: ctx.use_state(Vec::new()), logs: ctx.use_state(Vec::new()), inspect: ctx.use_state(InspectTarget::None), @@ -190,6 +191,26 @@ async fn main() -> tokio::io::Result<()> { Ok(()) } +pub async fn advanced_draw_map( + scroll: &State>, + index: usize, + title: &'static str, + state: &State>, + m: impl for<'a> FnOnce(&'a T) -> &'a B, +) -> ScrollText { + let scroll = scroll.lock().await; + + scroll.scroll( + index, + format!(" {}{title}\x1b[0m", scroll.get_selected(index)), + if let Some(state) = &*state.lock().await { + apply_padding(m(state).get_formatted()).join("\n") + } else { + " Loading..".to_string() + }, + ) +} + pub async fn advanced_draw( scroll: &State>, index: usize, diff --git a/src/terminal/terminal.rs b/src/terminal/terminal.rs index fe8aea3..d6b7ec1 100644 --- a/src/terminal/terminal.rs +++ b/src/terminal/terminal.rs @@ -46,7 +46,6 @@ impl TerminalClient { let reader = reader.expect("Reader failed to swap"); let watch_list = app.watch_list.clone(); - let active_positions = app.active_positions.clone(); let logs = app.logs.clone(); let signals = app.signals.clone(); let market_overview = app.config.clone(); @@ -57,7 +56,6 @@ impl TerminalClient { if let Err(v) = Self::run_client( reader, watch_list, - active_positions, logs, signals, market_overview, @@ -99,7 +97,6 @@ impl TerminalClient { mut reader: OwnedReadHalf, watch_list: State>, - active_positions: State>, logs: State>, signals: State>, config: State>, @@ -127,10 +124,6 @@ impl TerminalClient { *watch_list.lock().await = v; } - TerminalServerMessage::PositionsUpdated(v) => { - *active_positions.lock().await = v; - } - TerminalServerMessage::ConfigUpdated(v) => { *config.lock().await = Some(v); }