mirror of
https://github.com/exchanges-lab/tradesync.git
synced 2026-08-05 05:06:07 +08:00
feat: enhance HyperliquidMonitor to parse and emit all trade actions: Open, Increase, Decrease, Close
This commit is contained in:
+11
-3
@@ -28,11 +28,19 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
});
|
||||
|
||||
info!("Listening for position open events. Close with Ctrl+C...");
|
||||
info!("Listening for position trade events. Close with Ctrl+C...");
|
||||
while let Some(event) = rx.recv().await {
|
||||
info!(
|
||||
"DEMO RECEIVED POSITION OPEN: coin={}, side={}, px={}, sz={}, time={}, tid={}",
|
||||
event.coin, event.side, event.px, event.sz, event.time, event.tid
|
||||
"DEMO RECEIVED POSITION TRADE: coin={}, side={}, px={}, sz={}, action={:?}, start_pos={}, end_pos={}, time={}, tid={}",
|
||||
event.coin,
|
||||
event.side,
|
||||
event.px,
|
||||
event.sz,
|
||||
event.action,
|
||||
event.start_pos,
|
||||
event.end_pos,
|
||||
event.time,
|
||||
event.tid
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+48
-30
@@ -1,4 +1,4 @@
|
||||
use crate::structs::PositionOpenEvent;
|
||||
use crate::structs::{PositionTradeEvent, TradeAction};
|
||||
use alloy::primitives::Address;
|
||||
use hyperliquid_rust_sdk::{BaseUrl, InfoClient, Message, Subscription, UserData};
|
||||
use thiserror::Error;
|
||||
@@ -31,7 +31,7 @@ impl HyperliquidMonitor {
|
||||
/// Runs the monitor WebSocket subscription in a loop, reconnecting if disconnected.
|
||||
pub async fn run(
|
||||
&self,
|
||||
event_tx: UnboundedSender<PositionOpenEvent>,
|
||||
event_tx: UnboundedSender<PositionTradeEvent>,
|
||||
) -> Result<(), HyperliquidMonitorError> {
|
||||
let base_url = if self.is_testnet {
|
||||
BaseUrl::Testnet
|
||||
@@ -90,36 +90,54 @@ impl HyperliquidMonitor {
|
||||
debug!(user_msg = ?user_msg, "Received user event message");
|
||||
if let UserData::Fills(fills) = user_msg.data {
|
||||
for fill in fills {
|
||||
// Check if start_position is 0, which indicates a new position is opening
|
||||
// Parse position details
|
||||
let start_pos: f64 = fill.start_position.parse().unwrap_or(0.0);
|
||||
if start_pos == 0.0 {
|
||||
info!(
|
||||
coin = %fill.coin,
|
||||
side = %fill.side,
|
||||
px = %fill.px,
|
||||
sz = %fill.sz,
|
||||
tid = fill.tid,
|
||||
"Position opening detected!"
|
||||
);
|
||||
let event = PositionOpenEvent {
|
||||
coin: fill.coin,
|
||||
side: fill.side,
|
||||
px: fill.px,
|
||||
sz: fill.sz,
|
||||
time: fill.time,
|
||||
tid: fill.tid,
|
||||
};
|
||||
if let Err(e) = event_tx.send(event) {
|
||||
error!(
|
||||
error = ?e,
|
||||
"Failed to send PositionOpenEvent through channel"
|
||||
);
|
||||
}
|
||||
let sz: f64 = fill.sz.parse().unwrap_or(0.0);
|
||||
let dir = if fill.side == "B" { 1.0 } else { -1.0 };
|
||||
let change = dir * sz;
|
||||
let end_pos = start_pos + change;
|
||||
|
||||
// Determine the trade action
|
||||
let action = if start_pos == 0.0 {
|
||||
TradeAction::Open
|
||||
} else if end_pos == 0.0 {
|
||||
TradeAction::Close
|
||||
} else if start_pos.signum() != end_pos.signum() {
|
||||
TradeAction::Decrease
|
||||
} else if end_pos.abs() > start_pos.abs() {
|
||||
TradeAction::Increase
|
||||
} else {
|
||||
debug!(
|
||||
coin = %fill.coin,
|
||||
start_pos = start_pos,
|
||||
"Ignore non-opening trade fill"
|
||||
TradeAction::Decrease
|
||||
};
|
||||
|
||||
info!(
|
||||
coin = %fill.coin,
|
||||
side = %fill.side,
|
||||
px = %fill.px,
|
||||
sz = %fill.sz,
|
||||
action = ?action,
|
||||
start_pos = start_pos,
|
||||
end_pos = end_pos,
|
||||
tid = fill.tid,
|
||||
"Wallet trade fill detected!"
|
||||
);
|
||||
|
||||
let event = PositionTradeEvent {
|
||||
coin: fill.coin,
|
||||
side: fill.side,
|
||||
px: fill.px,
|
||||
sz: fill.sz,
|
||||
time: fill.time,
|
||||
tid: fill.tid,
|
||||
action,
|
||||
start_pos: fill.start_position.clone(),
|
||||
end_pos: format!("{:.5}", end_pos),
|
||||
};
|
||||
|
||||
if let Err(e) = event_tx.send(event) {
|
||||
error!(
|
||||
error = ?e,
|
||||
"Failed to send PositionTradeEvent through channel"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,4 +2,4 @@ pub mod hyperliquid;
|
||||
pub mod structs;
|
||||
|
||||
pub use hyperliquid::{HyperliquidMonitor, HyperliquidMonitorError};
|
||||
pub use structs::PositionOpenEvent;
|
||||
pub use structs::{PositionTradeEvent, TradeAction};
|
||||
|
||||
+4
-1
@@ -48,9 +48,12 @@ async fn main() -> Result<()> {
|
||||
side = %event.side,
|
||||
px = %event.px,
|
||||
sz = %event.sz,
|
||||
action = ?event.action,
|
||||
start_pos = %event.start_pos,
|
||||
end_pos = %event.end_pos,
|
||||
time = event.time,
|
||||
tid = event.tid,
|
||||
"Captured position opening event!"
|
||||
"Captured position trade event!"
|
||||
);
|
||||
// Notion database integration will be wired here in the future
|
||||
}
|
||||
|
||||
+20
-4
@@ -1,10 +1,26 @@
|
||||
/// Represents a detected position opening event on Hyperliquid.
|
||||
/// The action type of a trade fill relative to the position.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum TradeAction {
|
||||
/// Opening a position (initial position size was 0)
|
||||
Open,
|
||||
/// Adding to an existing position (absolute position size increases)
|
||||
Increase,
|
||||
/// Reducing an existing position (absolute position size decreases but remains non-zero)
|
||||
Decrease,
|
||||
/// Fully closing an existing position (resulting position size becomes 0)
|
||||
Close,
|
||||
}
|
||||
|
||||
/// Represents a detected trade event on Hyperliquid affecting a wallet's position.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PositionOpenEvent {
|
||||
pub struct PositionTradeEvent {
|
||||
pub coin: String,
|
||||
pub side: String, // "B" (Buy) or "S" (Sell)
|
||||
pub px: String, // Price as string
|
||||
pub sz: String, // Size as string
|
||||
pub sz: String, // Trade size as string
|
||||
pub time: u64, // Epoch timestamp in milliseconds
|
||||
pub tid: u64, // Unique trade/fill ID
|
||||
pub tid: u64, // Unique trade ID
|
||||
pub action: TradeAction,
|
||||
pub start_pos: String, // Position size before the trade
|
||||
pub end_pos: String, // Position size after the trade
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user