""" HFT SCALPER BOT PRO - Python + MT5 Auteur: Pour Bakafils - Lubumbashi Stratégie: Scalping tick + EMA 20/200 + RSI + Spread Filter + News Filter Paires: EURUSD, GBPUSD, XAUUSD """ import MetaTrader5 as mt5 import pandas as pd import time from datetime import datetime, timedelta import pytz # ================= CONFIG ================= CONFIG = { "SYMBOL": "EURUSD", "LOT": 0.01, "MAX_SPREAD_PIP": 0.8, "MAX_SLIPPAGE": 10, "TP_PIPS": 5, # 5 pips TP = style HFT "SL_PIPS": 10, # 10 pips SL = ratio 1:0.5 mais winrate élevé "MAGIC": 202606, "TIMEFRAME": mt5.TIMEFRAME_M1, "TRADING_HOURS": [(8, 11), (13, 17)], # Heure GMT - Londres + NY seulement } # ================= INIT MT5 ================= if not mt5.initialize(): print("❌ MT5 init failed", mt5.last_error()) quit() symbol_info = mt5.symbol_info(CONFIG["SYMBOL"]) if symbol_info is None: print(f"{CONFIG['SYMBOL']} not found") mt5.shutdown() quit() if not symbol_info.visible: mt5.symbol_select(CONFIG["SYMBOL"], True) print(f"✅ Bot HFT lancé sur {CONFIG['SYMBOL']} - Compte: {mt5.account_info().balance}$") # ================= FONCTIONS HFT ================= def get_spread_pip(): tick = mt5.symbol_info_tick(CONFIG["SYMBOL"]) if tick is None: return 999 pip = 0.0001 if "JPY" not in CONFIG["SYMBOL"] else 0.01 if "XAU" in CONFIG["SYMBOL"]: pip = 0.1 return (tick.ask - tick.bid) / pip def is_market_good(): """FILTRE HFT N°1: Spread + Trading Hours""" spread = get_spread_pip() if spread > CONFIG["MAX_SPREAD_PIP"]: print(f"⏸️ Spread trop haut: {spread:.2f} pip") return False # Filtre horaire - HFT ne trade que quand il y a de la liquidité now_gmt = datetime.now(pytz.timezone('Etc/GMT')).hour in_session = any(start <= now_gmt < end for start, end in CONFIG["TRADING_HOURS"]) if not in_session: print(f"⏸️ Hors session Londres/NY - GMT hour: {now_gmt}") return False return True def get_signals(): """FILTRE HFT N°2: Tendance + Momentum""" rates = mt5.copy_rates(CONFIG["SYMBOL"], CONFIG["TIMEFRAME"], 0, 300) if rates is None or len(rates) < 200: return None df = pd.DataFrame(rates) df['ema_fast'] = df['close'].ewm(span=20).mean() df['ema_slow'] = df['close'].ewm(span=200).mean() df['rsi'] = compute_rsi(df['close'], 14) df['atr'] = compute_atr(df, 14) last = df.iloc[-1] # Filtre volatilité: si ATR trop haut = News, on ne trade pas if last['atr'] > df['atr'].mean() * 2.5: print("⏸️ Volatilité NEWS détectée - pause") return None if last['ema_fast'] > last['ema_slow'] and last['rsi'] > 55 and last['rsi'] < 75: return "BUY" if last['ema_fast'] < last['ema_slow'] and last['rsi'] < 45 and last['rsi'] > 25: return "SELL" return None def compute_rsi(series, period=14): delta = series.diff() gain = delta.where(delta > 0, 0).rolling(window=period).mean() loss = -delta.where(delta < 0, 0).rolling(window=period).mean() rs = gain / loss return 100 - (100 / (1 + rs)) def compute_atr(df, period=14): high_low = df['high'] - df['low'] high_close = abs(df['high'] - df['close'].shift()) low_close = abs(df['low'] - df['close'].shift()) tr = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1) return tr.rolling(period).mean() def open_trade(order_type): tick = mt5.symbol_info_tick(CONFIG["SYMBOL"]) if tick is None: return price = tick.ask if order_type == mt5.ORDER_TYPE_BUY else tick.bid pip = 0.0001 if "XAU" in CONFIG["SYMBOL"]: pip = 0.1 if "JPY" in CONFIG["SYMBOL"]: pip = 0.01 sl = price - CONFIG["SL_PIPS"]*pip*10 if order_type == mt5.ORDER_TYPE_BUY else price + CONFIG["SL_PIPS"]*pip*10 tp = price + CONFIG["TP_PIPS"]*pip*10 if order_type == mt5.ORDER_TYPE_BUY else price - CONFIG["TP_PIPS"]*pip*10 request = { "action": mt5.TRADE_ACTION_DEAL, "symbol": CONFIG["SYMBOL"], "volume": CONFIG["LOT"], "type": order_type, "price": price, "sl": sl, "tp": tp, "deviation": CONFIG["MAX_SLIPPAGE"], "magic": CONFIG["MAGIC"], "comment": "HFT BOT PRO", "type_time": mt5.ORDER_TIME_GTC, } result = mt5.order_send(request) if result.retcode == mt5.TRADE_RETCODE_DONE: print(f"✅ { 'BUY' if order_type==0 else 'SELL'} ouvert à {price} | SL: {sl} TP: {tp}") else: print(f"❌ Erreur: {result.retcode} - {result.comment}") # ================= BOUCLE PRINCIPALE HFT ================= print("🚀 Bot en attente de signal... (Ctrl+C pour stopper)") try: while True: # On ne trade que si aucune position déjà ouverte par ce bot positions = mt5.positions_get(symbol=CONFIG["SYMBOL"], magic=CONFIG["MAGIC"]) if positions is None or len(positions) == 0: if is_market_good(): signal = get_signals() if signal == "BUY": open_trade(mt5.ORDER_TYPE_BUY) elif signal == "SELL": open_trade(mt5.ORDER_TYPE_SELL) time.sleep(0.5) # Check chaque 500ms = esprit HFT sans spammer le broker except KeyboardInterrupt: print("Bot stoppé") mt5.shutdown()