import MetaTrader5 as mt5
import pandas as pd
import numpy as np
import empyrical as ep
from datetime import datetime

# Connect to MetaTrader 5
if mt5.initialize():
    print("initialize() successful")
else:
    print("initialize() failed")

# Define constants
SYMBOL = "EURUSD"
LOT = 1.0
TIMEFRAME = mt5.TIMEFRAME_H1
RSI_PERIOD = 14
MA_PERIOD = 30
BB_PERIOD = 20
BB_STDDEV = 2
ATR_PERIOD = 14
ATR_MULTIPLIER = 1.5

# Function to get historical data
def get_historical_data(symbol, num_candles):
    rates = mt5.copy_rates_from_pos(symbol, TIMEFRAME, 0, num_candles)
    df = pd.DataFrame(rates)
    df['time'] = pd.to_datetime(df['time'], unit='s')
    df.set_index('time', inplace=True)
    return df

# Function to calculate RSI
def calculate_rsi(data, period=14):
    delta = data['close'].diff()
    gain = delta.where(delta > 0, 0)
    loss = -delta.where(delta < 0, 0)
    avg_gain = gain.rolling(window=period, min_periods=1).mean()
    avg_loss = loss.rolling(window=period, min_periods=1).mean()
    rs = avg_gain / avg_loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

# Function to calculate moving average
def calculate_ma(data, period=50):
    return data['close'].rolling(window=period).mean()

# Function to calculate Bollinger Bands
def calculate_bollinger_bands(data, period=20, stddev=2):
    ma = data['close'].rolling(window=period).mean()
    std = data['close'].rolling(window=period).std()
    upper_band = ma + (std * stddev)
    lower_band = ma - (std * stddev)
    return upper_band, lower_band

# Function to calculate ATR
def calculate_atr(data, period=14):
    data['tr'] = np.maximum(data['high'] - data['low'], 
                            np.maximum(abs(data['high'] - data['close'].shift(1)), 
                                       abs(data['low'] - data['close'].shift(1))))
    atr = data['tr'].rolling(window=period).mean()
    return atr

# Backtest strategy with ATR-based stop loss and optimized RSI thresholds
def backtest_strategy_with_atr(data):
    positions = [0] * len(data)
    returns = [0] * len(data)
    
    for i in range(max(RSI_PERIOD, MA_PERIOD, BB_PERIOD, ATR_PERIOD), len(data)):
        rsi = data.iloc[i]['rsi']
        ma = data.iloc[i]['ma']
        close = data.iloc[i]['close']
        upper_band = data.iloc[i]['upper_band']
        lower_band = data.iloc[i]['lower_band']
        atr = data.iloc[i]['atr']
        
        # Dynamic Stop Loss
        stop_loss = ATR_MULTIPLIER * atr
        
        # Check for long entry with optimized RSI threshold and dynamic stop-loss
        if rsi < 25 and close > ma and close <= lower_band:
            positions[i] = 1  # Long position
            returns[i] = data.iloc[i+1]['close'] - close - stop_loss
        
        # Check for short entry with optimized RSI threshold and dynamic stop-loss
        elif rsi > 75 and close < ma and close >= upper_band:
            positions[i] = -1  # Short position
            returns[i] = close - data.iloc[i+1]['close'] - stop_loss
    
    data['positions'] = positions
    data['strategy_returns'] = returns
    return data

# Function to evaluate performance
def evaluate_performance(strategy_data):
    strategy_returns = np.array(strategy_data['strategy_returns'])
    
    annual_return = ep.annual_return(strategy_returns)
    sharpe_ratio = ep.sharpe_ratio(strategy_returns)
    max_drawdown = ep.max_drawdown(strategy_returns)
    win_rate = np.sum(strategy_returns > 0) / len(strategy_returns)
    
    print("Annual Return:", annual_return)
    print("Sharpe Ratio:", sharpe_ratio)
    print("Max Drawdown:", max_drawdown)
    print("Win Rate:", win_rate)

# Fetch historical data
data = get_historical_data(SYMBOL, 1000)

# Calculate indicators
data['rsi'] = calculate_rsi(data, RSI_PERIOD)
data['ma'] = calculate_ma(data, MA_PERIOD)
data['upper_band'], data['lower_band'] = calculate_bollinger_bands(data, BB_PERIOD, BB_STDDEV)
data['atr'] = calculate_atr(data, ATR_PERIOD)

# Backtest the strategy
strategy_data = backtest_strategy_with_atr(data)

# Evaluate the performance
evaluate_performance(strategy_data)

please improve the win rate of this strategy