FIRST_BOT/asli code/trading_bot_simulation.py
2025-10-28 14:11:47 +00:00

199 lines
No EOL
8.3 KiB
Python

# -*- 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)