|
@@ -275,7 +275,7 @@ class HyperliquidAccountAnalyzer:
|
|
for trade in coin_trades:
|
|
for trade in coin_trades:
|
|
total_fees += trade.fee
|
|
total_fees += trade.fee
|
|
|
|
|
|
- if trade.side == 'buy':
|
|
|
|
|
|
+ if trade.side.lower() in ['buy', 'b']:
|
|
if position <= 0: # Opening long or closing short
|
|
if position <= 0: # Opening long or closing short
|
|
if position < 0: # Closing short position
|
|
if position < 0: # Closing short position
|
|
pnl = (entry_price - trade.price) * abs(position) - trade.fee
|
|
pnl = (entry_price - trade.price) * abs(position) - trade.fee
|
|
@@ -296,7 +296,7 @@ class HyperliquidAccountAnalyzer:
|
|
position += trade.size
|
|
position += trade.size
|
|
entry_price = entry_cost / position
|
|
entry_price = entry_cost / position
|
|
|
|
|
|
- elif trade.side == 'sell':
|
|
|
|
|
|
+ elif trade.side.lower() in ['sell', 's', 'a', 'ask']:
|
|
if position >= 0: # Closing long or opening short
|
|
if position >= 0: # Closing long or opening short
|
|
if position > 0: # Closing long position
|
|
if position > 0: # Closing long position
|
|
pnl = (trade.price - entry_price) * min(position, trade.size) - trade.fee
|
|
pnl = (trade.price - entry_price) * min(position, trade.size) - trade.fee
|
|
@@ -428,17 +428,17 @@ class HyperliquidAccountAnalyzer:
|
|
|
|
|
|
if window_trades:
|
|
if window_trades:
|
|
# Calculate net flow and fees for this window
|
|
# Calculate net flow and fees for this window
|
|
- net_usd_flow = 0.0
|
|
|
|
- window_fees = 0.0
|
|
|
|
|
|
+ net_usd_flow = 0.0
|
|
|
|
+ window_fees = 0.0
|
|
|
|
+
|
|
|
|
+ for trade in window_trades:
|
|
|
|
+ trade_value = trade.size * trade.price
|
|
|
|
+ if trade.side.lower() in ['buy', 'b']:
|
|
|
|
+ net_usd_flow -= trade_value # Cash out
|
|
|
|
+ elif trade.side.lower() in ['sell', 's', 'a', 'ask']: # sell
|
|
|
|
+ net_usd_flow += trade_value # Cash in
|
|
|
|
|
|
- for trade in window_trades:
|
|
|
|
- trade_value = trade.size * trade.price
|
|
|
|
- if trade.side == 'buy':
|
|
|
|
- net_usd_flow -= trade_value # Cash out
|
|
|
|
- else: # sell
|
|
|
|
- net_usd_flow += trade_value # Cash in
|
|
|
|
-
|
|
|
|
- window_fees += trade.fee
|
|
|
|
|
|
+ window_fees += trade.fee
|
|
|
|
|
|
# Window P&L = net cash flow - fees
|
|
# Window P&L = net cash flow - fees
|
|
window_pnl = net_usd_flow - window_fees
|
|
window_pnl = net_usd_flow - window_fees
|
|
@@ -522,7 +522,7 @@ class HyperliquidAccountAnalyzer:
|
|
# Check for short selling patterns (indicator of perps)
|
|
# Check for short selling patterns (indicator of perps)
|
|
total_trades = len(trades)
|
|
total_trades = len(trades)
|
|
if total_trades > 0:
|
|
if total_trades > 0:
|
|
- sell_trades = sum(1 for trade in trades if trade.side == 'sell')
|
|
|
|
|
|
+ sell_trades = sum(1 for trade in trades if trade.side.lower() in ['sell', 's', 'a', 'ask'])
|
|
buy_trades = total_trades - sell_trades
|
|
buy_trades = total_trades - sell_trades
|
|
|
|
|
|
# If significantly more sells than buys, likely includes short selling (perps)
|
|
# If significantly more sells than buys, likely includes short selling (perps)
|
|
@@ -548,18 +548,30 @@ class HyperliquidAccountAnalyzer:
|
|
'total_sells': 0,
|
|
'total_sells': 0,
|
|
'buy_sell_ratio': 0,
|
|
'buy_sell_ratio': 0,
|
|
'likely_short_trades': 0,
|
|
'likely_short_trades': 0,
|
|
|
|
+ 'short_percentage': 0,
|
|
'directional_balance': 'unknown',
|
|
'directional_balance': 'unknown',
|
|
'trading_style': 'unknown'
|
|
'trading_style': 'unknown'
|
|
}
|
|
}
|
|
|
|
|
|
- total_buys = sum(1 for trade in trades if trade.side == 'buy')
|
|
|
|
- total_sells = sum(1 for trade in trades if trade.side == 'sell')
|
|
|
|
|
|
+ # Handle Hyperliquid API format: 'b' = buy/bid, 'a' = sell/ask
|
|
|
|
+ total_buys = sum(1 for trade in trades if trade.side.lower() in ['buy', 'b'])
|
|
|
|
+ total_sells = sum(1 for trade in trades if trade.side.lower() in ['sell', 's', 'a', 'ask'])
|
|
total_trades = len(trades)
|
|
total_trades = len(trades)
|
|
|
|
|
|
- buy_sell_ratio = total_buys / max(1, total_sells)
|
|
|
|
|
|
+ # Calculate buy/sell ratio (handle edge cases)
|
|
|
|
+ if total_sells == 0:
|
|
|
|
+ buy_sell_ratio = float('inf') if total_buys > 0 else 0
|
|
|
|
+ else:
|
|
|
|
+ buy_sell_ratio = total_buys / total_sells
|
|
|
|
|
|
# Analyze trading patterns
|
|
# Analyze trading patterns
|
|
- if abs(total_buys - total_sells) / total_trades < 0.1: # Within 10%
|
|
|
|
|
|
+ if total_sells == 0 and total_buys > 0:
|
|
|
|
+ directional_balance = "buy_only"
|
|
|
|
+ trading_style = "Long-Only (buy and hold strategy)"
|
|
|
|
+ elif total_buys == 0 and total_sells > 0:
|
|
|
|
+ directional_balance = "sell_only"
|
|
|
|
+ trading_style = "Short-Only (bearish strategy)"
|
|
|
|
+ elif abs(total_buys - total_sells) / total_trades < 0.1: # Within 10%
|
|
directional_balance = "balanced"
|
|
directional_balance = "balanced"
|
|
trading_style = "Long/Short Balanced (can profit both ways)"
|
|
trading_style = "Long/Short Balanced (can profit both ways)"
|
|
elif total_sells > total_buys * 1.3: # 30% more sells
|
|
elif total_sells > total_buys * 1.3: # 30% more sells
|
|
@@ -579,19 +591,22 @@ class HyperliquidAccountAnalyzer:
|
|
for trade in sorted(trades, key=lambda x: x.timestamp):
|
|
for trade in sorted(trades, key=lambda x: x.timestamp):
|
|
coin_pos = position_tracker[trade.coin]
|
|
coin_pos = position_tracker[trade.coin]
|
|
|
|
|
|
- if trade.side == 'sell':
|
|
|
|
|
|
+ # Handle both 'sell'/'s' and 'buy'/'b' formats
|
|
|
|
+ if trade.side.lower() in ['sell', 's', 'a', 'ask']:
|
|
if coin_pos['net_position'] <= 0: # Selling without long position = likely short
|
|
if coin_pos['net_position'] <= 0: # Selling without long position = likely short
|
|
likely_shorts += 1
|
|
likely_shorts += 1
|
|
coin_pos['net_position'] -= trade.size
|
|
coin_pos['net_position'] -= trade.size
|
|
- else: # buy
|
|
|
|
|
|
+ elif trade.side.lower() in ['buy', 'b']:
|
|
coin_pos['net_position'] += trade.size
|
|
coin_pos['net_position'] += trade.size
|
|
|
|
|
|
|
|
+ short_percentage = (likely_shorts / total_trades * 100) if total_trades > 0 else 0
|
|
|
|
+
|
|
return {
|
|
return {
|
|
'total_buys': total_buys,
|
|
'total_buys': total_buys,
|
|
'total_sells': total_sells,
|
|
'total_sells': total_sells,
|
|
'buy_sell_ratio': buy_sell_ratio,
|
|
'buy_sell_ratio': buy_sell_ratio,
|
|
'likely_short_trades': likely_shorts,
|
|
'likely_short_trades': likely_shorts,
|
|
- 'short_percentage': (likely_shorts / total_trades * 100) if total_trades > 0 else 0,
|
|
|
|
|
|
+ 'short_percentage': short_percentage,
|
|
'directional_balance': directional_balance,
|
|
'directional_balance': directional_balance,
|
|
'trading_style': trading_style
|
|
'trading_style': trading_style
|
|
}
|
|
}
|
|
@@ -668,7 +683,7 @@ class HyperliquidAccountAnalyzer:
|
|
coin = trade.coin
|
|
coin = trade.coin
|
|
pos = position_tracker[coin]
|
|
pos = position_tracker[coin]
|
|
|
|
|
|
- if trade.side == 'buy':
|
|
|
|
|
|
+ if trade.side.lower() in ['buy', 'b']:
|
|
if pos['size'] <= 0 and trade.size > abs(pos['size']): # Opening new long
|
|
if pos['size'] <= 0 and trade.size > abs(pos['size']): # Opening new long
|
|
pos['start_time'] = trade.timestamp
|
|
pos['start_time'] = trade.timestamp
|
|
pos['size'] += trade.size
|
|
pos['size'] += trade.size
|
|
@@ -1009,7 +1024,15 @@ class HyperliquidAccountAnalyzer:
|
|
# Short/Long patterns - KEY ADVANTAGE
|
|
# Short/Long patterns - KEY ADVANTAGE
|
|
print(f" 📊 Trading Style: {stats.trading_style}")
|
|
print(f" 📊 Trading Style: {stats.trading_style}")
|
|
print(f" 📉 Short Trades: {stats.short_percentage:.1f}% (can profit from price drops)")
|
|
print(f" 📉 Short Trades: {stats.short_percentage:.1f}% (can profit from price drops)")
|
|
- print(f" ⚖️ Buy/Sell Ratio: {stats.buy_sell_ratio:.2f}")
|
|
|
|
|
|
+
|
|
|
|
+ # Format buy/sell ratio properly
|
|
|
|
+ if stats.buy_sell_ratio == float('inf'):
|
|
|
|
+ ratio_display = "∞ (only buys)"
|
|
|
|
+ elif stats.buy_sell_ratio == 0:
|
|
|
|
+ ratio_display = "0 (only sells)"
|
|
|
|
+ else:
|
|
|
|
+ ratio_display = f"{stats.buy_sell_ratio:.2f}"
|
|
|
|
+ print(f" ⚖️ Buy/Sell Ratio: {ratio_display}")
|
|
|
|
|
|
# Top tokens
|
|
# Top tokens
|
|
if stats.top_tokens:
|
|
if stats.top_tokens:
|