Bot auto-update: src/main_ml.py

This commit is contained in:
Marc Blatter 2026-07-04 15:15:01 +02:00
parent 524c52ccf6
commit c856478c1a
1 changed files with 83 additions and 44 deletions

View File

@ -1,28 +1,31 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os, asyncio, aiohttp import os, asyncio, aiohttp, logging, random
from datetime import datetime from datetime import datetime
from binance.client import Client from binance.client import Client
from dotenv import load_dotenv
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
load_dotenv("/home/marc/bot-deploy/.env")
# Load env
with open("/home/marc/bot-deploy/.env") as f:
env = {}
for line in f:
k, _, v = line.partition("=")
env[k.strip()] = v.strip()
class Bot: class Bot:
def __init__(self): def __init__(self):
self.binance = Client(os.getenv("BINANCE_API_KEY_LIVE"), os.getenv("BINANCE_API_SECRET_LIVE")) self.binance = Client(env.get("BINANCE_API_KEY_LIVE"), env.get("BINANCE_API_SECRET_LIVE"))
self.pairs = ["BTCUSDT","ETHUSDT","SOLUSDT","BNBUSDT","XRPUSDT"]
self.current_trades = {} self.current_trades = {}
self.completed_trades = [] self.completed_trades = []
self.balance = {} self.balance = {}
self.trades_today = 0 self.trades_today = 0
self.daily_pnl = 0.0 self.daily_pnl = 0.0
self.wins_today = 0 self.dashboard = "http://localhost:7000/api/update"
self.dashboard_url = "http://localhost:7000/api/update" logger.info("🤖 Bot initialized - CLEAN")
logger.info("Bot CLEAN initialized")
async def update_balance(self): def get_balance(self):
"""GET BALANCE FROM BINANCE (SYNC)"""
try: try:
acc = self.binance.get_account() acc = self.binance.get_account()
self.balance = {} self.balance = {}
@ -30,54 +33,82 @@ class Bot:
free, locked = float(a["free"]), float(a["locked"]) free, locked = float(a["free"]), float(a["locked"])
if free + locked > 0: if free + locked > 0:
self.balance[a["asset"]] = {"free": free, "locked": locked, "total": free+locked} self.balance[a["asset"]] = {"free": free, "locked": locked, "total": free+locked}
usdt_free = self.balance.get("USDT", {}).get("free", 0)
logger.info(f"💰 Balance updated: USDT ")
except Exception as e: except Exception as e:
logger.error(f"Balance error: {e}") logger.error(f"Balance error: {e}")
async def place_buy(self, pair, price): def place_buy(self, pair):
"""PLACE BUY ORDER"""
try: try:
usdt = self.balance.get("USDT", {}).get("free", 0) usdt_free = self.balance.get("USDT", {}).get("free", 0)
qty_usdt = usdt * 0.5 qty_usdt = usdt_free * 0.5
if qty_usdt < 10: if qty_usdt < 10:
return None return None
ticker = self.binance.get_symbol_ticker(symbol=pair)
price = float(ticker["price"])
qty = round(qty_usdt / price, 4) qty = round(qty_usdt / price, 4)
if qty <= 0:
return None
order = self.binance.order_market_buy(symbol=pair, quantity=qty) order = self.binance.order_market_buy(symbol=pair, quantity=qty)
logger.info(f"Buy: {pair} x{qty:.4f} @ ${price:.2f}")
logger.info(f"🟢 BUY: {pair} x{qty:.4f} @ ")
self.current_trades[pair] = { self.current_trades[pair] = {
"qty": qty, "buy_price": price, "buy_time": datetime.now().isoformat(), "order_id": order["orderId"] "qty": qty,
"buy_price": price,
"buy_time": datetime.now().isoformat(),
"order_id": order["orderId"]
} }
self.trades_today += 1 self.trades_today += 1
return order return order
except Exception as e: except Exception as e:
logger.error(f"Buy error {pair}: {e}") logger.error(f"Buy {pair} error: {e}")
return None return None
async def check_tp(self): def check_tp(self):
"""CHECK +1% TAKE PROFIT"""
remove = [] remove = []
for pair in list(self.current_trades.keys()): for pair in list(self.current_trades.keys()):
try: try:
trade = self.current_trades[pair] trade = self.current_trades[pair]
ticker = self.binance.get_symbol_ticker(symbol=pair) ticker = self.binance.get_symbol_ticker(symbol=pair)
current = float(ticker["price"]) current = float(ticker["price"])
profit_pct = (current / trade["buy_price"]) - 1 profit_pct = (current / trade["buy_price"]) - 1
if profit_pct >= 0.01: if profit_pct >= 0.01:
logger.info(f"TP HIT: {pair} +{profit_pct*100:.2f}%") logger.info(f"🎯 TP HIT: {pair} +{profit_pct*100:.2f}%")
sell = self.binance.order_market_sell(symbol=pair, quantity=trade["qty"]) sell = self.binance.order_market_sell(symbol=pair, quantity=trade["qty"])
sell_price = float(sell["fills"][0]["price"]) if sell.get("fills") else current sell_price = float(sell["fills"][0]["price"]) if sell.get("fills") else current
profit = (sell_price - trade["buy_price"]) * trade["qty"] profit = (sell_price - trade["buy_price"]) * trade["qty"]
self.completed_trades.append({ self.completed_trades.append({
"pair": pair, "buy_price": trade["buy_price"], "sell_price": sell_price, "pair": pair,
"qty": trade["qty"], "profit_usd": profit, "profit_pct": profit_pct, "buy_price": trade["buy_price"],
"buy_time": trade["buy_time"], "sell_time": datetime.now().isoformat() "sell_price": sell_price,
"qty": trade["qty"],
"profit_usd": profit,
"profit_pct": profit_pct,
"buy_time": trade["buy_time"],
"sell_time": datetime.now().isoformat()
}) })
self.daily_pnl += profit self.daily_pnl += profit
self.wins_today += 1
remove.append(pair) remove.append(pair)
except Exception as e: except Exception as e:
logger.warning(f"TP error {pair}: {e}") pass
for p in remove: for p in remove:
del self.current_trades[p] del self.current_trades[p]
async def send_dash(self): async def send_dashboard(self):
"""SEND STATE TO DASHBOARD"""
try: try:
state = { state = {
"current_trades": self.current_trades, "current_trades": self.current_trades,
@ -86,35 +117,43 @@ class Bot:
"trades_today": self.trades_today, "trades_today": self.trades_today,
"daily_pnl": self.daily_pnl, "daily_pnl": self.daily_pnl,
"total_pnl": self.daily_pnl, "total_pnl": self.daily_pnl,
"wins_today": self.wins_today, "wins_today": len([t for t in self.completed_trades if t.get("profit_usd", 0) > 0]),
"losses_today": 0, "losses_today": len([t for t in self.completed_trades if t.get("profit_usd", 0) < 0]),
"last_update": datetime.now().isoformat() "last_update": datetime.now().isoformat()
} }
async with aiohttp.ClientSession() as s: async with aiohttp.ClientSession() as s:
async with s.post(self.dashboard_url, json=state, timeout=2) as r: async with s.post(self.dashboard, json=state, timeout=2) as r:
pass pass
except Exception as e: except:
logger.warning(f"Dashboard error: {e}") pass
async def run(self): async def run(self):
logger.info("Bot started") """MAIN LOOP"""
logger.info("🎯 Bot started")
tick = 0
while True: while True:
try: try:
await self.update_balance() tick += 1
for pair in self.pairs:
if pair in self.current_trades: # Get balance every 5 ticks (every 5 seconds)
continue if tick % 5 == 0:
try: self.get_balance()
ticker = self.binance.get_symbol_ticker(symbol=pair)
price = float(ticker["price"]) # Check signals
import random pairs = ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "XRPUSDT"]
for pair in pairs:
if pair not in self.current_trades:
if random.random() > 0.95: if random.random() > 0.95:
logger.info(f"BUY signal: {pair}") logger.info(f"🟢 Signal: {pair}")
await self.place_buy(pair, price) self.place_buy(pair)
except:
pass # Check exits
await self.check_tp() self.check_tp()
await self.send_dash()
# Send to dashboard
await self.send_dashboard()
await asyncio.sleep(1) await asyncio.sleep(1)
except Exception as e: except Exception as e:
logger.error(f"Loop error: {e}") logger.error(f"Loop error: {e}")