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:
logger.warning(f"Dashboard error: {e}")
async def run(self):
logger.info("Bot started")
while True:
try:
await self.update_balance()
for pair in self.pairs:
if pair in self.current_trades:
continue
try:
ticker = self.binance.get_symbol_ticker(symbol=pair)
price = float(ticker["price"])
import random
if random.random() > 0.95:
logger.info(f"BUY signal: {pair}")
await self.place_buy(pair, price)
except: except:
pass pass
await self.check_tp()
await self.send_dash() async def run(self):
"""MAIN LOOP"""
logger.info("🎯 Bot started")
tick = 0
while True:
try:
tick += 1
# Get balance every 5 ticks (every 5 seconds)
if tick % 5 == 0:
self.get_balance()
# Check signals
pairs = ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "XRPUSDT"]
for pair in pairs:
if pair not in self.current_trades:
if random.random() > 0.95:
logger.info(f"🟢 Signal: {pair}")
self.place_buy(pair)
# Check exits
self.check_tp()
# 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}")