From 823aa9b73f2db22df9ce9a6eb06743744267fa30 Mon Sep 17 00:00:00 2001 From: Marc Blatter Date: Sat, 4 Jul 2026 13:33:11 +0200 Subject: [PATCH] Bot auto-update: src/main_ml.py --- src/main_ml.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main_ml.py b/src/main_ml.py index 5e8aefc..661ce9a 100644 --- a/src/main_ml.py +++ b/src/main_ml.py @@ -114,7 +114,7 @@ class MLTradingBot: self.pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'] # Track open positions - self.open_positions = {} # CLEAN START - reset on bot restart + self.current_trades = {} # CLEAN START - reset on bot restart logger.info('🗑️ RESET: Cleared all stored positions (dashboard will show REAL Binance state only)') @@ -467,11 +467,11 @@ class MLTradingBot: logger.warning(f'Failed to get price for {pair}: {e}') continue - if pair not in self.open_positions: - logger.debug(f'⏭️ {pair} not in open_positions (keys: {list(self.open_positions.keys())})') + if pair not in self.current_trades: + logger.debug(f'⏭️ {pair} not in open_positions (keys: {list(self.current_trades.keys())})') continue - pos = self.open_positions[pair] + pos = self.current_trades[pair] buy_price = pos['buy_price'] buy_qty = pos['qty'] buy_time = datetime.fromisoformat(pos['buy_time']) @@ -552,7 +552,7 @@ class MLTradingBot: f'{icon} CLOSED {exit_reason}\n' f'{pair}: {current_qty:.8f} @ ${current_price:.2f}\n' f'Profit: ${profit_usd:+.2f} ({profit_pct:+.2f}%)\n' - f'Hold: {(datetime.now() - datetime.fromisoformat(self.open_positions[pair]["buy_time"])).total_seconds() / 60:.0f} min' + f'Hold: {(datetime.now() - datetime.fromisoformat(self.current_trades[pair]["buy_time"])).total_seconds() / 60:.0f} min' ) else: logger.info(f'Loss trade skipped from Telegram (visible on dashboard): {profit_pct:.2f}%') @@ -565,11 +565,11 @@ class MLTradingBot: self.error_count = 0 # Send to dashboard BEFORE deleting position (ONLY for REAL executed trades!) - hold_time_s = (datetime.now() - datetime.fromisoformat(self.open_positions[pair]["buy_time"])).total_seconds() + hold_time_s = (datetime.now() - datetime.fromisoformat(self.current_trades[pair]["buy_time"])).total_seconds() hold_time_min = hold_time_s / 60 await self.dashboard.record_sell(pair, current_qty, current_price, profit_usd, profit_pct, hold_time_min) - del self.open_positions[pair] + del self.current_trades[pair] logger.info(f'✅ EXIT EXECUTED & RECORDED TO DASHBOARD!') else: logger.warning(f'❌ EXIT order FAILED or returned no result for {pair} - NOT recording') @@ -738,7 +738,7 @@ class MLTradingBot: # ONLY RECORD if order was SUCCESSFUL if result and result.get('status') in ['FILLED', 'NEW', 'PARTIALLY_FILLED']: logger.info(f'🔍 DEBUG: Storing BUY position {pair}: qty={qty}, price={price}') - self.open_positions[pair] = { + self.current_trades[pair] = { 'qty': qty, 'buy_price': price, 'buy_time': datetime.now().isoformat(), @@ -746,7 +746,8 @@ class MLTradingBot: 'trailing_stop': None, 'order_id': result.get('orderId', 'unknown') } - logger.info(f'🔍 DEBUG: After storage, open_positions keys = {list(self.open_positions.keys())}') + save_persistent_trades(self.current_trades, self.completed_trades, self.swaps) + logger.info(f'🔍 DEBUG: After storage, open_positions keys = {list(self.current_trades.keys())}') self.trades_today += 1 self.error_count = 0 @@ -813,7 +814,7 @@ class MLTradingBot: Max Drawdown: ${self.max_drawdown:.2f} (CHF {self.max_drawdown * 0.84:.2f}) 🤖 BOT STATUS: {'🟢 RUNNING' if time.time() >= self.error_cooldown_until else '🟡 ERROR_COOLDOWN'} - Open Positions: {len(self.open_positions)} + Open Positions: {len(self.current_trades)} Error Count: {self.error_count}/{self.error_threshold}''' logger.info(report) @@ -965,13 +966,13 @@ class MLTradingBot: except: pass - logger.info(f'✅ Sending to dashboard: USDT={usdt_live:.2f}, portfolio={portfolio_value_usd:.2f}, trades_today={self.trades_today}, open_trades={len(self.open_positions)}') + logger.info(f'✅ Sending to dashboard: USDT={usdt_live:.2f}, portfolio={portfolio_value_usd:.2f}, trades_today={self.trades_today}, open_trades={len(self.current_trades)}') # SYNC open_positions with dashboard async with aiohttp.ClientSession() as session: async with session.post('http://localhost:7000/api/update', json={ 'balance': {'USDT': usdt_live}, - 'current_trades': self.open_positions, # Send ALL open positions! + 'current_trades': self.current_trades, # Send ALL open positions! 'daily_pnl': self.daily_pnl, 'total_pnl': self.total_pnl, 'trades_today': self.trades_today,