# -*- coding: utf-8 -*- """Trading Bot Simulation Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/1xQA5F3HvFfWWO3Xe2PKXEM68FFx_s-rc """ import numpy as np import time # NOTE: In a real environment, you must install the MetaTrader5 package: # pip install MetaTrader5 # import MetaTrader5 as mt5 # --- MOCK MT5 LIBRARY & CONFIGURATION --- # The functions below are STUBS (placeholders) that mimic the real MT5 library behavior. # Replace the comments with your actual MT5 connection logic and credentials. # Strategy parameters SYMBOL = "EURUSD" TIMEFRAME = "M15" # E.g., 15-minute bars SHORT_WINDOW = 5 LONG_WINDOW = 15 VOLUME = 0.1 # Trading volume (lot size) def mt5_initialize_connection(login, password, server): """Initializes connection to MT5 terminal.""" print("Connecting to MT5 terminal...") # if not mt5.initialize(login=login, password=password, server=server): # print(f"Failed to initialize MT5: {mt5.last_error()}") # return False # print("MT5 connection successful.") return True def mt5_fetch_data(symbol, period_size, count): """Fetches the last 'count' bars of data from MT5.""" # This mock data simulates fetching the last 30 closing prices print(f"Fetching {count} historical bars for {symbol}...") # In a real bot, you'd use: # rates = mt5.copy_rates_from_pos(symbol, period_size, 0, count) # df = pd.DataFrame(rates) # df['time'] = pd.to_datetime(df['time'], unit='s') # return df['close'].to_numpy() # We only need the closing prices for SMA # Using the simulation data for demonstration: PRICE_DATA = [ 100.00, 101.50, 102.10, 103.00, 105.50, 104.90, 106.30, 107.80, 108.20, 107.50, 110.00, 112.40, 115.80, 114.30, 113.10, 116.70, 118.90, 120.00, 122.50, 121.10, 125.00, 126.90, 124.70, 128.00, 130.40, 127.80, 126.10, 125.50, 129.00, 132.00 ] return np.array(PRICE_DATA) def mt5_send_order(symbol, direction, volume, price_limit=None): """Mocks sending a market or limit order to MT5.""" order_type = "BUY" if direction == 1 else "SELL" # This is where your actual order execution code goes using mt5.order_send() # In a real bot, you'd calculate price, deviation, and create a request dictionary: # request = { # "action": mt5.TRADE_ACTION_DEAL, # "symbol": symbol, # "volume": volume, # "type": mt5.ORDER_TYPE_BUY if direction == 1 else mt5.ORDER_TYPE_SELL, # "price": mt5.symbol_info_tick(symbol).ask if direction == 1 else mt5.symbol_info_tick(symbol).bid, # "deviation": 20, # Max price slippage # "magic": 202409, # "comment": "SMA Crossover Bot", # "type_time": mt5.ORDER_TIME_GTC, # "type_filling": mt5.ORDER_FILLING_FOC, # } # result = mt5.order_send(request) print(f"\n[ORDER SENT] --- {order_type} {volume} lots of {symbol}") # print(f"MT5 API Response: {result}") return True # --- CORE LOGIC FUNCTIONS (RETAINED FOR TECHNICAL ANALYSIS) --- def calculate_sma(data, window): """Calculates the Simple Moving Average (SMA) for a given window.""" weights = np.repeat(1.0, window) / window smas = np.convolve(data, weights, 'valid') padding = np.full(window - 1, np.nan) return np.concatenate((padding, smas)) def generate_signals(prices, short_window, long_window): """Generates buy (1) and sell (-1) signals based on SMA Crossover.""" # We only need the last two values of the SMAs to detect a recent crossover prices_array = np.array(prices) short_sma = calculate_sma(prices_array, short_window) long_sma = calculate_sma(prices_array, long_window) # Check for non-NaN values if np.isnan(short_sma[-1]) or np.isnan(long_sma[-1]) or \ np.isnan(short_sma[-2]) or np.isnan(long_sma[-2]): return 0, short_sma, long_sma # No signal if data is insufficient # Bullish Crossover (BUY signal) if short_sma[-1] > long_sma[-1] and short_sma[-2] <= long_sma[-2]: return 1, short_sma, long_sma # Bearish Crossover (SELL signal) elif short_sma[-1] < long_sma[-1] and short_sma[-2] >= long_sma[-2]: return -1, short_sma, long_sma # No Crossover (HOLD signal) return 0, short_sma, long_sma # --- LIVE TRADING LOOP --- def live_trading_main(symbol, timeframe, short_window, long_window, volume, interval_seconds=60): """ Main loop for live trading on MT5. NOTE: Replace the mock connection details with your real MT5 credentials. """ # Replace with your actual credentials LOGIN = 12345678 PASSWORD = "your_password" SERVER = "your_server_name" if not mt5_initialize_connection(LOGIN, PASSWORD, SERVER): return # The loop runs forever, constantly checking for new data and signals print(f"\nStarting live trading loop for {symbol}. Checking every {interval_seconds} seconds...") while True: try: # 1. Fetch data required for the longest moving average (LONG_WINDOW) # We need at least LONG_WINDOW bars + 1 previous bar to detect a cross DATA_POINTS_TO_FETCH = long_window + 1 # Fetch real data (mocked here) close_prices = mt5_fetch_data(symbol, timeframe, DATA_POINTS_TO_FETCH) # 2. Generate signal based on the latest data signal, short_sma, long_sma = generate_signals( close_prices, short_window, long_window ) current_price = close_prices[-1] latest_short_ma = short_sma[-1] if not np.isnan(short_sma[-1]) else 'N/A' latest_long_ma = long_sma[-1] if not np.isnan(long_sma[-1]) else 'N/A' print(f"\n[{time.strftime('%H:%M:%S')}] Price: ${current_price:.4f} | SMA({short_window}): {latest_short_ma} | SMA({long_window}): {latest_long_ma} | Signal: {signal}") # 3. Execute Trade based on signal if signal == 1: # Check for existing open positions before sending BUY order (crucial for MT5) # If there are open SELL positions, you'd close them first. print(">>> BULLISH CROSSOVER DETECTED. ATTEMPTING TO BUY.") mt5_send_order(symbol, 1, volume) # 1 for BUY elif signal == -1: # Check for existing open positions before sending SELL order # If there are open BUY positions, you'd close them first. print(">>> BEARISH CROSSOVER DETECTED. ATTEMPTING TO SELL.") mt5_send_order(symbol, -1, volume) # -1 for SELL else: print("No signal, holding position.") except Exception as e: print(f"An error occurred: {e}") # mt5.shutdown() # Uncomment this in a real app to cleanly close the connection break # Exit loop on critical error # Wait for the next check cycle time.sleep(interval_seconds) # --- 4. EXECUTION --- if __name__ == "__main__": # The backtesting functions are now separated from the live trading execution. # To run the live trading loop, uncomment the line below. # IMPORTANT: You must install the MetaTrader5 library (pip install MetaTrader5) # and run this script from a Python environment that is allowed to connect to # your running MT5 terminal. print("--- TRADING BOT DRAFT FOR MT5 INTEGRATION ---") print("This file contains the SMA logic and the structure for MT5 integration.") print("The code below simulates the backtesting process using the mock data.") # Simulated Backtesting (using the old function structure) price_history = mt5_fetch_data(SYMBOL, TIMEFRAME, 30) signals, short_sma, long_sma = generate_signals(price_history, SHORT_WINDOW, LONG_WINDOW) print("\n--- Backtesting Results (Simulated Data) ---") print("Index | Price | Short MA | Long MA | Signal") print("--------------------------------------------------") for i in range(len(price_history)): short_val = f"{short_sma[i]:.2f}" if not np.isnan(short_sma[i]) else 'N/A' long_val = f"{long_sma[i]:.2f}" if not np.isnan(long_sma[i]) else 'N/A' print(f"{i:5} | {price_history[i]:5.2f} | {short_val:8} | {long_val:7} | {signals[i]:.0f}") # To run the live loop, uncomment this line (after installing MT5): # live_trading_main(SYMBOL, TIMEFRAME, SHORT_WINDOW, LONG_WINDOW, VOLUME)