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"))