import ccxt import pandas as pd import numpy as np import xgboost as xgb import time import gc import threading import gradio as gr from utils import get_live_usdt_dominance, send_email_alert # --- 1. Your Credentials --- SENDER_EMAIL = "your_email@gmail.com" SENDER_PASSWORD = "paste_your_16_digit_app_password_here" RECEIVER_EMAIL = "your_email@gmail.com" # --- 2. The Core AI Engine --- def train_and_evaluate(symbol): exchange = ccxt.bitget() # Train Model (Historical Data) ohlcv = exchange.fetch_ohlcv(symbol, '1h', limit=2000) df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) df['buy_vol_proxy'] = np.where(df['close'] > df['open'], df['volume'] * 0.7, df['volume'] * 0.3) df['sell_vol_proxy'] = df['volume'] - df['buy_vol_proxy'] df['order_book_imbalance'] = (df['buy_vol_proxy'] - df['sell_vol_proxy']) / (df['volume'] + 1e-9) targets = [] tp_pct, sl_pct, max_candles = 0.02, 0.01, 24 for i in range(len(df)): if i + max_candles >= len(df): targets.append(0); continue entry = df['close'].iloc[i] tp, sl = entry * (1 + tp_pct), entry * (1 - sl_pct) success = 0 for j in range(1, max_candles + 1): if df['low'].iloc[i + j] <= sl: success = 0; break if df['high'].iloc[i + j] >= tp: success = 1; break targets.append(success) df['target'] = targets df['SMA_10'] = df['close'].rolling(10).mean() df['SMA_50'] = df['close'].rolling(50).mean() df['ATR'] = df['high'].rolling(14).max() - df['low'].rolling(14).min() df['Regime'] = df['close'].rolling(20).std() / (df['ATR'] + 1e-9) df['returns'] = df['close'].pct_change() df = df.dropna() features = ['open', 'high', 'low', 'close', 'volume', 'order_book_imbalance', 'SMA_10', 'SMA_50', 'ATR', 'Regime', 'returns'] X, y = df[features], df['target'] model = xgb.XGBClassifier(n_estimators=300, max_depth=5, learning_rate=0.05, scale_pos_weight=(y == 0).sum() / ((y == 1).sum() + 1e-9)) model.fit(X, y) # Live Market Check ohlcv_live = exchange.fetch_ohlcv(symbol, '1h', limit=60) df_live = pd.DataFrame(ohlcv_live, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) orderbook = exchange.fetch_order_book(symbol, limit=50) bids_vol = sum([bid[1] for bid in orderbook['bids']]) asks_vol = sum([ask[1] for ask in orderbook['asks']]) live_imbalance = (bids_vol - asks_vol) / (bids_vol + asks_vol + 1e-9) df_live['order_book_imbalance'] = live_imbalance df_live['SMA_10'] = df_live['close'].rolling(10).mean() df_live['SMA_50'] = df_live['close'].rolling(50).mean() df_live['ATR'] = df_live['high'].rolling(14).max() - df_live['low'].rolling(14).min() df_live['Regime'] = df_live['close'].rolling(20).std() / (df_live['ATR'] + 1e-9) df_live['returns'] = df_live['close'].pct_change() latest = df_live.dropna().iloc[-1:] conf = model.predict_proba(latest[features])[0][1] price = latest['close'].iloc[0] atr = latest['ATR'].iloc[0] regime = latest['Regime'].iloc[0] limit_entry = price - (atr * 0.5) stop = limit_entry * 0.99 tp = limit_entry * 1.02 del df, X, y, df_live, model gc.collect() return price, conf, limit_entry, stop, tp, regime, live_imbalance # --- 3. The Infinite Background Loop --- def run_scanner(): TOP_PAIRS = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'BNB/USDT', 'XRP/USDT', 'DOGE/USDT', 'PEPE/USDT', 'BONK/USDT', 'PI/USDT', 'WIF/USDT'] print("Initializing scanner thread...") send_email_alert(SENDER_EMAIL, SENDER_PASSWORD, RECEIVER_EMAIL, "SYSTEM", "🟢 AI Spot Sniper Bot Online. Scanning markets from Hugging Face...") while True: try: usdt_dom = get_live_usdt_dominance() if usdt_dom >= 6.50: print(f"Macro Kill Switch Active (USDT.D: {usdt_dom:.2f}%). Sleeping 15 mins.") time.sleep(900) continue for symbol in TOP_PAIRS: price, conf, entry, stop, tp, regime, imbalance = train_and_evaluate(symbol) if regime > 1.2 and conf >= 0.60 and 0.30 <= imbalance <= 0.65: alert_msg = ( f"PRIME SETUP DETECTED: {symbol}\n\n" f"Current Price: ${price:.4f}\n" f"AI Confidence: {conf:.2%}\n" f"Order Book Imbalance: {imbalance:.2f}\n\n" f"LIMIT BUY: ${entry:.4f}\n" f"TAKE PROFIT: ${tp:.4f}\n" f"STOP LOSS: ${stop:.4f}" ) send_email_alert(SENDER_EMAIL, SENDER_PASSWORD, RECEIVER_EMAIL, symbol, alert_msg) time.sleep(2) time.sleep(900) except Exception as e: print(f"Error in main loop: {e}") time.sleep(60) # --- 4. The Gradio Web Interface --- thread = threading.Thread(target=run_scanner) thread.daemon = True thread.start() with gr.Blocks() as demo: gr.Markdown("# 🟢 Email Spot Sniper is Live!") gr.Markdown("Your AI is currently scanning the markets in the background. Emails will be sent automatically when a high-probability setup is found.") gr.Markdown("**Note:** Ensure you are using a ping service (like UptimeRobot) to keep this Space from going to sleep.") demo.launch(server_name="0.0.0.0", server_port=7860)