diff --git a/src/strategies/ping_pong_bot.py b/src/strategies/ping_pong_bot.py index cad4fca..04eafb4 100644 --- a/src/strategies/ping_pong_bot.py +++ b/src/strategies/ping_pong_bot.py @@ -69,7 +69,7 @@ class DatabaseManager: class PingPongBot: def __init__(self, config_path="config/ping_pong_config.yaml"): - self.version = "1.3.4" + self.version = "1.3.5" with open(config_path, 'r') as f: self.config = yaml.safe_load(f) @@ -108,6 +108,7 @@ class PingPongBot: self.status_msg = "Initializing..." self.last_signal = None self.start_time = datetime.now() + self.last_refresh_time = datetime.now() self.console = Console() # Parameters @@ -236,13 +237,13 @@ class PingPongBot: logger.error(f"Trade Error: {e}") def generate_dashboard(self): - """Generates the dashboard layout without printing directly""" + """Generates the dashboard layout""" layout = Layout() layout.split_column( Layout(name="header", size=3), Layout(name="indicators", size=7), Layout(name="position", size=6), - Layout(name="footer", size=2) + Layout(name="footer", size=3) ) # Header @@ -269,7 +270,8 @@ class PingPongBot: layout["position"].update(Panel(pos_table, title="[bold green]PORTFOLIO STATUS[/]")) # Footer - footer_text = f"Status: [bold blue]{self.status_msg}[/] | Last Signal: [bold yellow]{self.last_signal or 'N/A'}[/] | Last Candle: {self.last_candle_time or 'N/A'}" + refresh_str = self.last_refresh_time.strftime("%H:%M:%S") + footer_text = f"Status: [bold blue]{self.status_msg}[/]\nLast Signal: [bold yellow]{self.last_signal or 'N/A'}[/] | Last Candle: {self.last_candle_time or 'N/A'} | [dim italic]Heartbeat: {refresh_str}[/]" layout["footer"].update(Panel(footer_text)) return layout @@ -278,32 +280,41 @@ class PingPongBot: await self.db.connect() last_exchange_update = 0 - with Live(self.generate_dashboard(), refresh_per_second=2) as live: + with Live(self.generate_dashboard(), refresh_per_second=1) as live: while True: - now = time.time() - # 1. Exchange Sync (15s) - if now - last_exchange_update >= 15: - await self.update_exchange_data() - last_exchange_update = now + try: + now = time.time() + self.last_refresh_time = datetime.now() + + # 1. Exchange Sync (15s) + if now - last_exchange_update >= 15: + await self.update_exchange_data() + last_exchange_update = now + + # 2. DB Sync (5s) + candles = await self.db.get_candles(self.db_symbol, self.db_interval, limit=100) + if candles: + latest = candles[0] + if latest['time'] != self.last_candle_time: + df = pd.DataFrame(candles[::-1]) + df = df.astype({'open': float, 'high': float, 'low': float, 'close': float, 'volume': float}) + df = self.calculate_indicators(df) + signal = self.check_signals(df) + if signal: await self.execute_trade(signal) + self.last_candle_time = latest['time'] + self.last_candle_price = latest['close'] + self.status_msg = f"New Candle processed: {latest['time']}" + else: + self.status_msg = f"No candles found for {self.db_symbol} / {self.db_interval}" + + # 3. Update Dashboard + live.update(self.generate_dashboard()) + + except Exception as e: + logger.exception(f"Loop Error: {e}") + self.status_msg = f"Error: {str(e)[:50]}" + live.update(self.generate_dashboard()) - # 2. DB Sync (5s) - candles = await self.db.get_candles(self.db_symbol, self.db_interval, limit=100) - if candles: - latest = candles[0] - if latest['time'] != self.last_candle_time: - df = pd.DataFrame(candles[::-1]) - df = df.astype({'open': float, 'high': float, 'low': float, 'close': float, 'volume': float}) - df = self.calculate_indicators(df) - signal = self.check_signals(df) - if signal: await self.execute_trade(signal) - self.last_candle_time = latest['time'] - self.last_candle_price = latest['close'] - self.status_msg = f"New Candle processed: {latest['time']}" - else: - self.status_msg = f"No candles found for {self.db_symbol} / {self.db_interval}" - - # 3. Update Dashboard - live.update(self.generate_dashboard()) await asyncio.sleep(5) if __name__ == "__main__":