Bot auto-update: src/main_ml.py

This commit is contained in:
Marc Blatter 2026-07-04 19:20:01 +02:00
parent 09dc561027
commit 336542728e
1 changed files with 60 additions and 54 deletions

View File

@ -2,11 +2,11 @@
import os, asyncio, aiohttp, logging, random 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 decimal import Decimal
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 env
with open("/home/marc/bot-deploy/.env") as f: with open("/home/marc/bot-deploy/.env") as f:
env = {} env = {}
for line in f: for line in f:
@ -22,10 +22,9 @@ class Bot:
self.trades_today = 0 self.trades_today = 0
self.daily_pnl = 0.0 self.daily_pnl = 0.0
self.dashboard = "http://localhost:7000/api/update" self.dashboard = "http://localhost:7000/api/update"
logger.info("🤖 Bot initialized - CLEAN") logger.info("🤖 Bot initialized")
def get_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 = {}
@ -33,45 +32,66 @@ 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")
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}")
def place_buy(self, pair): def place_buy(self, pair):
"""PLACE BUY ORDER"""
try: try:
usdt_free = self.balance.get("USDT", {}).get("free", 0) usdt_free = self.balance.get("USDT", {}).get("free", 0)
qty_usdt = usdt_free * 0.5 if usdt_free < 5:
if qty_usdt < 1:
return None return None
# Use 25% per trade
qty_usdt = usdt_free * 0.25
ticker = self.binance.get_symbol_ticker(symbol=pair) ticker = self.binance.get_symbol_ticker(symbol=pair)
price = float(ticker["price"]) price = float(ticker["price"])
qty = round(qty_usdt / price, 4) # Get symbol info for filters
if qty <= 0: info = self.binance.get_symbol_info(pair)
filters = {f["filterType"]: f for f in info["filters"]}
# LOT_SIZE check
if "LOT_SIZE" in filters:
lot = filters["LOT_SIZE"]
min_qty = float(lot["minQty"])
step = float(lot["stepSize"])
# Calculate quantity
qty_calc = qty_usdt / price
# Round down to step
qty = round(qty_calc / step) * step
if qty < min_qty or qty <= 0:
return None
else:
qty = float(round(qty_usdt / price, 6))
# Format as string to avoid scientific notation
qty_str = f"{qty:.8f}".rstrip("0").rstrip(".")
try:
order = self.binance.order_market_buy(symbol=pair, quantity=qty_str)
logger.info(f"🟢 BUY: {pair} x{qty_str}")
self.current_trades[pair] = {
"qty": float(qty_str),
"buy_price": price,
"buy_time": datetime.now().isoformat(),
"order_id": order["orderId"]
}
self.trades_today += 1
return order
except Exception as e:
logger.error(f"Buy {pair} error: {e}")
return None return None
order = self.binance.order_market_buy(symbol=pair, quantity=qty)
logger.info(f"🟢 BUY: {pair} x{qty:.4f} @ ")
self.current_trades[pair] = {
"qty": qty,
"buy_price": price,
"buy_time": datetime.now().isoformat(),
"order_id": order["orderId"]
}
self.trades_today += 1
return order
except Exception as e: except Exception as e:
logger.error(f"Buy {pair} error: {e}") logger.error(f"place_buy error: {e}")
return None return None
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:
@ -108,7 +128,6 @@ class Bot:
del self.current_trades[p] del self.current_trades[p]
async def send_dashboard(self): async def send_dashboard(self):
"""SEND STATE TO DASHBOARD"""
try: try:
state = { state = {
"current_trades": self.current_trades, "current_trades": self.current_trades,
@ -128,40 +147,27 @@ class Bot:
pass pass
async def run(self): async def run(self):
"""MAIN LOOP"""
logger.info("🎯 Bot started") logger.info("🎯 Bot started")
tick = 0
while True: while True:
try: try:
tick += 1 self.get_balance()
# 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() self.check_tp()
# Send to dashboard pairs = ['BTCUSDT', 'ETHUSDT', 'SOLUSDT', 'BNBUSDT', 'XRPUSDT']
await self.send_dashboard()
await asyncio.sleep(1) for pair in pairs:
except Exception as e: if pair not in self.current_trades and random.random() < 0.05:
logger.error(f"Loop error: {e}") logger.info(f"🟢 Signal: {pair}")
self.place_buy(pair)
await self.send_dashboard()
await asyncio.sleep(5) await asyncio.sleep(5)
async def main(): except Exception as e:
bot = Bot() logger.error(f"Run error: {e}")
await bot.run() await asyncio.sleep(10)
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) bot = Bot()
asyncio.run(bot.run())