Positions
This commit is contained in:
@@ -44,7 +44,6 @@ pub struct ActivePosition {
|
|||||||
pub symbol: String,
|
pub symbol: String,
|
||||||
pub size: f64,
|
pub size: f64,
|
||||||
pub entry_price: f64,
|
pub entry_price: f64,
|
||||||
pub mark_price: f64,
|
|
||||||
pub profit: f64,
|
pub profit: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+43
-1
@@ -1,5 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use pulse_wire::terminal::ActivePosition;
|
||||||
use tokio::{sync::Mutex, task::JoinHandle};
|
use tokio::{sync::Mutex, task::JoinHandle};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -41,12 +42,14 @@ impl Engine {
|
|||||||
pub async fn run_broadcaster(&self) -> tokio::io::Result<()> {
|
pub async fn run_broadcaster(&self) -> tokio::io::Result<()> {
|
||||||
let mut refresh = tokio::time::interval(tokio::time::Duration::from_secs(5));
|
let mut refresh = tokio::time::interval(tokio::time::Duration::from_secs(5));
|
||||||
|
|
||||||
|
let client = hypersdk::hypercore::mainnet();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
refresh.tick().await;
|
refresh.tick().await;
|
||||||
|
|
||||||
let watch_list = &self.config.lock().await.watchlist.symbols;
|
let watch_list = &self.config.lock().await.watchlist.symbols;
|
||||||
|
|
||||||
match crate::fetch::fetch_watch_list(watch_list).await {
|
match crate::fetch::fetch_watch_list(&client, watch_list).await {
|
||||||
Ok(watch_list) => {
|
Ok(watch_list) => {
|
||||||
if let Err(error) = self
|
if let Err(error) = self
|
||||||
.terminal_server
|
.terminal_server
|
||||||
@@ -75,6 +78,45 @@ impl Engine {
|
|||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let accounts = self.accounts.lock().await;
|
||||||
|
|
||||||
|
if let Some(acc) = accounts.get_active() {
|
||||||
|
match client.clearinghouse_state(acc.address, None).await {
|
||||||
|
Ok(state) => {
|
||||||
|
self.terminal_server
|
||||||
|
.broadcast(
|
||||||
|
pulse_wire::terminal::TerminalServerMessage::PositionsUpdated(
|
||||||
|
state
|
||||||
|
.asset_positions
|
||||||
|
.into_iter()
|
||||||
|
.map(|position| ActivePosition {
|
||||||
|
symbol: position.position.coin,
|
||||||
|
size: position.position.szi.as_f64(),
|
||||||
|
entry_price: position
|
||||||
|
.position
|
||||||
|
.entry_px
|
||||||
|
.map(|px| px.as_f64())
|
||||||
|
.unwrap_or(0.0),
|
||||||
|
profit: position.position.unrealized_pnl.as_f64(),
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
self.terminal_server
|
||||||
|
.error("orders", &format!("Unable to get open orders: {e}"))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.terminal_server.error(
|
||||||
|
"orders",
|
||||||
|
"Unable to get active account, make sure you have configured accounts properly",
|
||||||
|
).await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-2
@@ -12,8 +12,11 @@ fn number(value: &Value, field: &str) -> Result<f64, String> {
|
|||||||
.map_err(|error| format!("could not parse asset context field {field} ({raw}): {error}"))
|
.map_err(|error| format!("could not parse asset context field {field} ({raw}): {error}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_watch_list(symbols: &[String]) -> Result<Vec<WatchListItem>, String> {
|
pub async fn fetch_watch_list(
|
||||||
let response = hypersdk::hypercore::mainnet()
|
client: &hypersdk::hypercore::HttpClient,
|
||||||
|
symbols: &[String],
|
||||||
|
) -> Result<Vec<WatchListItem>, String> {
|
||||||
|
let response = client
|
||||||
.meta_and_asset_ctxs(None)
|
.meta_and_asset_ctxs(None)
|
||||||
.await
|
.await
|
||||||
.map_err(|error| format!("Hyperliquid metaAndAssetCtxs request failed: {error}"))?;
|
.map_err(|error| format!("Hyperliquid metaAndAssetCtxs request failed: {error}"))?;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::{collections::HashMap, str::FromStr};
|
use std::{collections::HashMap, str::FromStr};
|
||||||
|
|
||||||
use hypersdk::{U160, hypercore::PrivateKeySigner};
|
use hypersdk::{Address, hypercore::PrivateKeySigner};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PrivateKey(pub PrivateKeySigner, pub String);
|
pub struct PrivateKey(pub PrivateKeySigner, pub String);
|
||||||
@@ -40,7 +40,7 @@ impl serde::Serialize for PrivateKey {
|
|||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
pub address: U160,
|
pub address: Address,
|
||||||
pub private_key: PrivateKey,
|
pub private_key: PrivateKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,6 +79,10 @@ impl AccountList {
|
|||||||
toml::to_string(self)
|
toml::to_string(self)
|
||||||
.map_err(|v| tokio::io::Error::new(std::io::ErrorKind::Other, v.to_string()))
|
.map_err(|v| tokio::io::Error::new(std::io::ErrorKind::Other, v.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_active<'a>(&'a self) -> Option<&'a Account> {
|
||||||
|
self.accounts.get(&self.active)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Account {
|
impl Account {
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ impl Formatted for ActivePosition {
|
|||||||
format!("\x1b[35m{}\x1b[0m", self.symbol),
|
format!("\x1b[35m{}\x1b[0m", self.symbol),
|
||||||
format_f64(self.size),
|
format_f64(self.size),
|
||||||
format_f64(self.entry_price),
|
format_f64(self.entry_price),
|
||||||
format_f64(self.mark_price),
|
|
||||||
format!(
|
format!(
|
||||||
"{} {}",
|
"{} {}",
|
||||||
if self.profit.is_sign_positive() {
|
if self.profit.is_sign_positive() {
|
||||||
|
|||||||
Reference in New Issue
Block a user