148 lines
No EOL
6 KiB
Python
148 lines
No EOL
6 KiB
Python
import asyncio
|
|
import json
|
|
import os
|
|
from datetime import datetime
|
|
import pytz
|
|
from websockets import connect
|
|
from rich.console import Console
|
|
from rich.text import Text
|
|
from rich.panel import Panel
|
|
from rich.align import Align
|
|
from rich.columns import Columns
|
|
from rich.rule import Rule
|
|
|
|
LIQ_LIMIT = 0
|
|
console = Console()
|
|
websocket_url = 'wss://fstream.binance.com/ws/!forceOrder@arr'
|
|
|
|
def format_usd(amount):
|
|
"""Format USD amount with appropriate suffixes"""
|
|
if amount >= 1_000_000:
|
|
return f"${amount/1_000_000:.2f}M"
|
|
elif amount >= 1_000:
|
|
return f"${amount/1_000:.1f}K"
|
|
else:
|
|
return f"${amount:.0f}"
|
|
|
|
async def binance_liquidation(uri):
|
|
# Print header
|
|
console.print(Rule("[bold cyan]🔥 BINANCE LIQUIDATION MONITOR 🔥[/bold cyan]", style="cyan"))
|
|
console.print()
|
|
|
|
async with connect(uri) as websocket:
|
|
while True:
|
|
try:
|
|
msg = await websocket.recv()
|
|
order_data = json.loads(msg)['o']
|
|
symbol = order_data['s'].replace('USDT', '')
|
|
side = order_data['S']
|
|
timestamp = int(order_data['T'])
|
|
filled_quantity = float(order_data['z'])
|
|
price = float(order_data['p'])
|
|
usd_size = filled_quantity * price
|
|
est = pytz.timezone("US/Eastern")
|
|
time_est = datetime.fromtimestamp(timestamp / 1000, est).strftime('%H:%M:%S')
|
|
|
|
if usd_size >= LIQ_LIMIT:
|
|
liquidation_type = '📈 LONG LIQ' if side == 'SELL' else '📉 SHORT LIQ'
|
|
symbol_clean = symbol[:4]
|
|
formatted_usd = format_usd(usd_size)
|
|
|
|
# Choose colors and styling based on liquidation type and size
|
|
if side == 'SELL': # Long liquidation
|
|
border_color = "bright_green"
|
|
text_style = "bright_green"
|
|
emoji_prefix = "🟢"
|
|
else: # Short liquidation
|
|
border_color = "bright_red"
|
|
text_style = "bright_red"
|
|
emoji_prefix = "🔴"
|
|
|
|
# Create content sections
|
|
type_text = Text(liquidation_type, style=f"bold {text_style}")
|
|
symbol_text = Text(f"{symbol_clean}", style="bold yellow")
|
|
time_text = Text(f"⏰ {time_est}", style="white")
|
|
amount_text = Text(formatted_usd, style=f"bold {text_style}")
|
|
|
|
# Create the main content
|
|
content_parts = [
|
|
emoji_prefix,
|
|
type_text,
|
|
symbol_text,
|
|
time_text,
|
|
amount_text
|
|
]
|
|
|
|
if usd_size > 250000:
|
|
# Mega liquidation - very prominent
|
|
title = "💎 MEGA LIQUIDATION 💎"
|
|
panel = Panel(
|
|
Align.center(Columns(content_parts, padding=(0, 2))),
|
|
title=title,
|
|
title_align="center",
|
|
border_style=border_color,
|
|
style=f"bold {text_style}",
|
|
padding=(1, 2)
|
|
)
|
|
for _ in range(4):
|
|
console.print(panel)
|
|
|
|
elif usd_size > 100000:
|
|
# Large liquidation - prominent
|
|
title = "🚨 LARGE LIQUIDATION 🚨"
|
|
panel = Panel(
|
|
Align.center(Columns(content_parts, padding=(0, 1))),
|
|
title=title,
|
|
title_align="center",
|
|
border_style=border_color,
|
|
style=f"bold {text_style}",
|
|
padding=(0, 2)
|
|
)
|
|
for _ in range(2):
|
|
console.print(panel)
|
|
|
|
elif usd_size > 25000:
|
|
# Medium liquidation - boxed
|
|
panel = Panel(
|
|
Columns(content_parts, padding=(0, 1)),
|
|
border_style=border_color,
|
|
style=f"bold {text_style}",
|
|
padding=(0, 1)
|
|
)
|
|
console.print(panel)
|
|
|
|
else:
|
|
# Small liquidation - simple line
|
|
line_content = Text()
|
|
for i, part in enumerate(content_parts):
|
|
if i > 0:
|
|
line_content.append(" ")
|
|
line_content.append(part)
|
|
|
|
console.print(
|
|
Panel(
|
|
line_content,
|
|
border_style=border_color,
|
|
style=text_style,
|
|
padding=(0, 1),
|
|
expand=False
|
|
)
|
|
)
|
|
|
|
console.print() # Spacing
|
|
|
|
except Exception as e:
|
|
error_panel = Panel(
|
|
f"❌ Connection error: {str(e)}\n⏳ Reconnecting in 5 seconds...",
|
|
title="Error",
|
|
border_style="yellow",
|
|
style="yellow"
|
|
)
|
|
console.print(error_panel)
|
|
await asyncio.sleep(5)
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
asyncio.run(binance_liquidation(websocket_url))
|
|
except KeyboardInterrupt:
|
|
console.print(Rule("[bold red]👋 Liquidation monitor stopped[/bold red]", style="red")) |