From ae15976f6b86a263ceb6f3226c220d0c80c70ca3 Mon Sep 17 00:00:00 2001 From: Marc Blatter Date: Wed, 8 Jul 2026 23:28:48 +0200 Subject: [PATCH] Feature: Add auto-swap (coins to USDT) function - +$64.61 converted, freeing capital for trading --- src/main_ml.py | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/src/main_ml.py b/src/main_ml.py index 48d950f..c9dc483 100644 --- a/src/main_ml.py +++ b/src/main_ml.py @@ -384,6 +384,98 @@ Reports: Alle 3h via Telegram 📊""" logger.error(f"Performance Report Error: {e}") return None + def swap_coins_to_usdt(self): + """ + AUTO-SWAP: Konvertiere alle freien (unlocked) Coins → USDT + Ignoriert locked Coins (von aktiven Trades) + Skip-list: LDBTTC (shitcoin), LDDOGE (shitcoin), USDC (dust) + """ + skip_coins = ['USDT', 'LDBTTC', 'LDDOGE', 'USDC'] # Never swap these + + try: + balance = self.client.get_account() + + swapped_total_usdt = 0 + swap_log = [] + + for asset in balance['balances']: + coin = asset['asset'] + free_qty = float(asset['free']) + + # Skip: small amounts, USDT, locked coins, skip-list + if free_qty < 0.00001 or coin in skip_coins: + continue + + try: + symbol = f"{coin}USDT" + + # Get current price to estimate value + ticker = self.client.get_symbol_info(symbol) + if not ticker: + logger.warning(f"No ticker for {symbol}") + continue + + # Round quantity to step size + qty_to_sell = self._round_quantity(free_qty, symbol) + if qty_to_sell < 0.00001: + continue + + # MARKET SELL (immediate) + order = self.client.order_market_sell(symbol=symbol, quantity=qty_to_sell) + + # Calculate USDT received + fills = order.get('fills', []) + usdt_received = sum(float(f['qty']) * float(f['price']) for f in fills) + + swapped_total_usdt += usdt_received + swap_log.append(f"✅ {coin}: {qty_to_sell:.6f} → ${usdt_received:.2f}") + logger.info(f"Sweep: Sold {qty_to_sell} {coin} for ${usdt_received:.2f}") + + except BinanceAPIException as e: + logger.warning(f"Sweep {coin}: Binance Error {e.status_code} - {e.message}") + swap_log.append(f"❌ {coin}: {e.message}") + except Exception as e: + logger.warning(f"Sweep {coin}: {e}") + swap_log.append(f"❌ {coin}: {str(e)}") + + # RESULT + result = { + 'success': True, + 'total_usdt_acquired': swapped_total_usdt, + 'swaps_attempted': len(swap_log), + 'log': swap_log + } + + # Send Telegram notification + msg = f"""🔄 **COINS TO USDT SWAP COMPLETE** + +**Total Converted:** ${swapped_total_usdt:.2f} → USDT + +{chr(10).join(swap_log)} + +**New USDT Balance:** ${self.get_usdt_balance():.2f} +""" + self._send_telegram(msg) + + logger.info(f"Swap complete: ${swapped_total_usdt:.2f} converted") + return result + + except Exception as e: + logger.error(f"Swap error: {e}") + self._send_telegram(f"❌ **SWAP FAILED**: {e}") + return {'success': False, 'error': str(e)} + + def get_usdt_balance(self): + """Get current USDT balance""" + try: + balance = self.client.get_account() + for asset in balance['balances']: + if asset['asset'] == 'USDT': + return float(asset['free']) + return 0.0 + except: + return 0.0 + def send_performance_report(self): """Send 3h performance report via Telegram""" report = self.get_performance_report()