Bot auto-update: src/__pycache__/main_ml.cpython-310.pyc,src/main_ml.py

This commit is contained in:
Marc Blatter 2026-07-04 13:45:01 +02:00
parent 8eececb04f
commit e312565063
2 changed files with 12 additions and 32 deletions

View File

@ -1,4 +1,3 @@
from src.persistence import load_persistent_trades, save_persistent_trades, load_binance_positions_on_startup, init_persistence
import asyncio, logging, joblib, time, json, aiohttp, os import asyncio, logging, joblib, time, json, aiohttp, os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from src.config import get_config from src.config import get_config
@ -107,24 +106,6 @@ class MLTradingBot:
self.max_drawdown = 0.0 self.max_drawdown = 0.0
self.min_daily_pnl = 0.0 self.min_daily_pnl = 0.0
self.starting_capital = 100.0 self.starting_capital = 100.0
# Initialize persistence and load trades
init_persistence()
self.current_trades, self.completed_trades, self.swaps = load_persistent_trades()
if self.current_trades:
logger.info(f"Loaded {len(self.current_trades)} trades from persistent storage")
# If portfolio value exists but no trades: recover from Binance
portfolio_val = self.binance.get_portfolio_value_usd()
if not self.current_trades and portfolio_val > 50:
logger.info(f"Portfolio exists ({portfolio_val:.2f}) but no trades - loading from Binance...")
binance_trades = load_binance_positions_on_startup()
if binance_trades:
self.current_trades.update(binance_trades)
save_persistent_trades(self.current_trades, self.completed_trades, self.swaps)
logger.info(f"Recovered {len(binance_trades)} positions from Binance API")
self.daily_loss_limit_reached = False self.daily_loss_limit_reached = False
# Symbol constraints cache # Symbol constraints cache
@ -132,7 +113,7 @@ class MLTradingBot:
self.pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT'] self.pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT']
# Track open positions # Track open positions
self.current_trades = {} # CLEAN START - reset on bot restart self.open_positions = {} # CLEAN START - reset on bot restart
logger.info('🗑️ RESET: Cleared all stored positions (dashboard will show REAL Binance state only)') logger.info('🗑️ RESET: Cleared all stored positions (dashboard will show REAL Binance state only)')
@ -485,11 +466,11 @@ class MLTradingBot:
logger.warning(f'Failed to get price for {pair}: {e}') logger.warning(f'Failed to get price for {pair}: {e}')
continue continue
if pair not in self.current_trades: if pair not in self.open_positions:
logger.debug(f'⏭️ {pair} not in open_positions (keys: {list(self.current_trades.keys())})') logger.debug(f'⏭️ {pair} not in open_positions (keys: {list(self.open_positions.keys())})')
continue continue
pos = self.current_trades[pair] pos = self.open_positions[pair]
buy_price = pos['buy_price'] buy_price = pos['buy_price']
buy_qty = pos['qty'] buy_qty = pos['qty']
buy_time = datetime.fromisoformat(pos['buy_time']) buy_time = datetime.fromisoformat(pos['buy_time'])
@ -570,7 +551,7 @@ class MLTradingBot:
f'{icon} CLOSED {exit_reason}\n' f'{icon} CLOSED {exit_reason}\n'
f'{pair}: {current_qty:.8f} @ ${current_price:.2f}\n' f'{pair}: {current_qty:.8f} @ ${current_price:.2f}\n'
f'Profit: ${profit_usd:+.2f} ({profit_pct:+.2f}%)\n' f'Profit: ${profit_usd:+.2f} ({profit_pct:+.2f}%)\n'
f'Hold: {(datetime.now() - datetime.fromisoformat(self.current_trades[pair]["buy_time"])).total_seconds() / 60:.0f} min' f'Hold: {(datetime.now() - datetime.fromisoformat(self.open_positions[pair]["buy_time"])).total_seconds() / 60:.0f} min'
) )
else: else:
logger.info(f'Loss trade skipped from Telegram (visible on dashboard): {profit_pct:.2f}%') logger.info(f'Loss trade skipped from Telegram (visible on dashboard): {profit_pct:.2f}%')
@ -583,11 +564,11 @@ class MLTradingBot:
self.error_count = 0 self.error_count = 0
# Send to dashboard BEFORE deleting position (ONLY for REAL executed trades!) # Send to dashboard BEFORE deleting position (ONLY for REAL executed trades!)
hold_time_s = (datetime.now() - datetime.fromisoformat(self.current_trades[pair]["buy_time"])).total_seconds() hold_time_s = (datetime.now() - datetime.fromisoformat(self.open_positions[pair]["buy_time"])).total_seconds()
hold_time_min = hold_time_s / 60 hold_time_min = hold_time_s / 60
await self.dashboard.record_sell(pair, current_qty, current_price, profit_usd, profit_pct, hold_time_min) await self.dashboard.record_sell(pair, current_qty, current_price, profit_usd, profit_pct, hold_time_min)
del self.current_trades[pair] del self.open_positions[pair]
logger.info(f'✅ EXIT EXECUTED & RECORDED TO DASHBOARD!') logger.info(f'✅ EXIT EXECUTED & RECORDED TO DASHBOARD!')
else: else:
logger.warning(f'❌ EXIT order FAILED or returned no result for {pair} - NOT recording') logger.warning(f'❌ EXIT order FAILED or returned no result for {pair} - NOT recording')
@ -756,7 +737,7 @@ class MLTradingBot:
# ONLY RECORD if order was SUCCESSFUL # ONLY RECORD if order was SUCCESSFUL
if result and result.get('status') in ['FILLED', 'NEW', 'PARTIALLY_FILLED']: if result and result.get('status') in ['FILLED', 'NEW', 'PARTIALLY_FILLED']:
logger.info(f'🔍 DEBUG: Storing BUY position {pair}: qty={qty}, price={price}') logger.info(f'🔍 DEBUG: Storing BUY position {pair}: qty={qty}, price={price}')
self.current_trades[pair] = { self.open_positions[pair] = {
'qty': qty, 'qty': qty,
'buy_price': price, 'buy_price': price,
'buy_time': datetime.now().isoformat(), 'buy_time': datetime.now().isoformat(),
@ -764,8 +745,7 @@ class MLTradingBot:
'trailing_stop': None, 'trailing_stop': None,
'order_id': result.get('orderId', 'unknown') 'order_id': result.get('orderId', 'unknown')
} }
save_persistent_trades(self.current_trades, self.completed_trades, self.swaps) logger.info(f'🔍 DEBUG: After storage, open_positions keys = {list(self.open_positions.keys())}')
logger.info(f'🔍 DEBUG: After storage, open_positions keys = {list(self.current_trades.keys())}')
self.trades_today += 1 self.trades_today += 1
self.error_count = 0 self.error_count = 0
@ -832,7 +812,7 @@ class MLTradingBot:
Max Drawdown: ${self.max_drawdown:.2f} (CHF {self.max_drawdown * 0.84:.2f}) 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'} 🤖 BOT STATUS: {'🟢 RUNNING' if time.time() >= self.error_cooldown_until else '🟡 ERROR_COOLDOWN'}
Open Positions: {len(self.current_trades)} Open Positions: {len(self.open_positions)}
Error Count: {self.error_count}/{self.error_threshold}''' Error Count: {self.error_count}/{self.error_threshold}'''
logger.info(report) logger.info(report)
@ -984,13 +964,13 @@ class MLTradingBot:
except: except:
pass 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.current_trades)}') 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)}')
# SYNC open_positions with dashboard # SYNC open_positions with dashboard
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.post('http://localhost:7000/api/update', json={ async with session.post('http://localhost:7000/api/update', json={
'balance': {'USDT': usdt_live}, 'balance': {'USDT': usdt_live},
'current_trades': self.current_trades, # Send ALL open positions! 'current_trades': self.open_positions, # Send ALL open positions!
'daily_pnl': self.daily_pnl, 'daily_pnl': self.daily_pnl,
'total_pnl': self.total_pnl, 'total_pnl': self.total_pnl,
'trades_today': self.trades_today, 'trades_today': self.trades_today,