import MetaTrader5 as mt5
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
import winsound
import matplotlib.dates as mdates
from datetime import datetime

# Função para selecionar o par de moedas
def select_symbol():
    symbols = ["EURUSD", "GBPUSD", "USDJPY", "USDCHF", "AUDUSD", "USDCAD", "NZDUSD", "GOLD", "BTCUSD", "US500Cash", "US30Cash"]
    print("Escolha o par de moedas:")
    for i, symbol in enumerate(symbols, 1):
        print(f"{i}. {symbol}")
    choice = int(input("Digite o número correspondente ao par de moedas: "))
    return symbols[choice - 1]

# Função para selecionar o timeframe
def select_timeframe():
    timeframes = {
        1: ("15 Minutos", mt5.TIMEFRAME_M15),
        2: ("30 Minutos", mt5.TIMEFRAME_M30),
        3: ("1 Hora", mt5.TIMEFRAME_H1),
        4: ("4 Horas", mt5.TIMEFRAME_H4),
        5: ("1 Dia", mt5.TIMEFRAME_D1),
        6: ("1 Semana", mt5.TIMEFRAME_W1),
        7: ("1 Mês", mt5.TIMEFRAME_MN1)
    }
    print("Escolha o timeframe:")
    for i, (name, _) in timeframes.items():
        print(f"{i}. {name}")
    choice = int(input("Digite o número correspondente ao timeframe: "))
    return timeframes[choice][1]

# Função para cálculo do RSI
def rsi(data, period):
    delta = data['close'].diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
    rs = gain / loss
    rsi = 100 - (100 / (1 + rs))
    return rsi

# Função para cálculo do CCI
def cci(data, period):
    tp = (data['high'] + data['low'] + data['close']) / 3
    sma_tp = tp.rolling(window=period).mean()
    mad = tp.rolling(window=period).apply(lambda x: np.mean(np.abs(x - np.mean(x))), raw=True)
    cci = (tp - sma_tp) / (0.015 * mad)
    return cci

# Função para cálculo do MACD
def macd(data, short_period=12, long_period=26, signal_period=9):
    ema_short = data['close'].ewm(span=short_period, adjust=False).mean()
    ema_long = data['close'].ewm(span=long_period, adjust=False).mean()
    macd_line = ema_short - ema_long
    signal_line = macd_line.ewm(span=signal_period, adjust=False).mean()
    histogram = macd_line - signal_line
    return macd_line, signal_line, histogram

# Função para cálculo do Estocástico
def stochastic(data, period=14):
    high_max = data['high'].rolling(window=period).max()
    low_min = data['low'].rolling(window=period).min()
    k = 100 * (data['close'] - low_min) / (high_max - low_min)
    d = k.rolling(window=3).mean()
    return k, d

# Função para cálculo do KDJ
def kdj(data, period=14):
    low_min = data['low'].rolling(window=period).min()
    high_max = data['high'].rolling(window=period).max()
    rsv = 100 * ((data['close'] - low_min) / (high_max - low_min))
    k = rsv.ewm(span=3).mean()
    d = k.ewm(span=3).mean()
    j = 3 * k - 2 * d
    return k, d, j

# Função para tocar alerta sonoro
def play_alert_sound():
    frequency = 1000  # Hertz
    duration = 1000  # Milliseconds
    for _ in range(3):
        winsound.Beep(frequency, duration)
        time.sleep(0.5)

# Função para análise da tendência de mercado
def analyze_trend(data):
    macd_line, signal_line, _ = macd(data)
    
    # Determine o estado da tendência
    if macd_line.iloc[-1] > signal_line.iloc[-1]:
        if macd_line.iloc[-1] > macd_line.iloc[-2]:
            return "Tendência de Alta Forte"
        else:
            return "Tendência de Alta"
    elif macd_line.iloc[-1] < signal_line.iloc[-1]:
        if macd_line.iloc[-1] < macd_line.iloc[-2]:
            return "Tendência de Baixa Forte"
        else:
            return "Tendência de Baixa"
    else:
        return "Neutro"

# Função para calcular a volatilidade
def calculate_volatility(data, period=14):
    data['log_return'] = np.log(data['close'] / data['close'].shift(1))
    volatility = data['log_return'].rolling(window=period).std() * np.sqrt(252)  # Anualizar a volatilidade
    return volatility.iloc[-1]

# Função para classificar a volatilidade
def classify_volatility(volatility, high_threshold=0.2, low_threshold=0.1):
    if volatility > high_threshold:
        return "Alta"
    elif volatility < low_threshold:
        return "Baixa"
    else:
        return "Moderada"

# Função para calcular e exibir sinais de compra e venda
def calculate_signals(data, symbol):
    period_rsi = 14
    period_cci = 20
    period_stochastic = 14
    period_kdj = 14
    
    rsi_values = rsi(data, period_rsi)
    cci_values = cci(data, period_cci)
    macd_line, signal_line, histogram = macd(data)
    k, d = stochastic(data, period_stochastic)
    kdj_k, kdj_d, kdj_j = kdj(data, period_kdj)
    
    data['RSI'] = rsi_values
    data['CCI'] = cci_values
    data['MACD Line'] = macd_line
    data['Signal Line'] = signal_line
    data['Histogram'] = histogram
    data['K'] = k
    data['D'] = d
    data['KDJ K'] = kdj_k
    data['KDJ D'] = kdj_d
    data['KDJ J'] = kdj_j
    
    # Sinais de compra e venda
    data['Buy Signal'] = (rsi_values < 30) & (cci_values < -100) & (k < 15) & (kdj_j < 20)
    data['Sell Signal'] = (rsi_values > 70) & (cci_values > 100) & (k > 85) & (kdj_j > 80)
    
    # Sinais fortes de compra e venda
    data['Strong Buy'] = (rsi_values < 20) & (cci_values < -150) & (k < 10) & (kdj_j < 10)
    data['Strong Sell'] = (rsi_values > 80) & (cci_values > 150) & (k > 90) & (kdj_j > 90)
    
    trend = analyze_trend(data)
    volatility = calculate_volatility(data)
    volatility_class = classify_volatility(volatility)
    
    plot_indicators(data, rsi_values, cci_values, macd_line, signal_line, histogram, k, d, kdj_k, kdj_d, kdj_j, trend, volatility, volatility_class, symbol)
    
    latest_signals = {
        'Buy': data['Buy Signal'].iloc[-1],
        'Sell': data['Sell Signal'].iloc[-1]
    }
    
    if latest_signals['Buy']:
        play_alert_sound()
    if latest_signals['Sell']:
        play_alert_sound()

# Função para plotar os indicadores e sinais
def plot_indicators(data, rsi, cci, macd_line, signal_line, histogram, k, d, kdj_k, kdj_d, kdj_j, trend, volatility, volatility_class, symbol):
    fig, axes = plt.subplots(4, 1, figsize=(14, 18), sharex=True)
    
    # Adicionar título com o nome do ativo e a volatilidade
    plt.suptitle(f'Análise do Ativo: {symbol} - {trend} - Volatilidade: {volatility_class}', fontsize=16, fontweight='bold')
    
    # RSI
    axes[0].plot(data.index, rsi, label='RSI', color='blue')
    axes[0].axhline(70, linestyle='--', color='red')
    axes[0].axhline(30, linestyle='--', color='green')
    axes[0].fill_between(data.index, 0, rsi, where=(rsi < 30), color='lightgreen', alpha=0.5, label='Zona de Compra')
    axes[0].fill_between(data.index, 70, 100, where=(rsi > 70), color='salmon', alpha=0.5, label='Zona de Venda')
    axes[0].scatter(data.index[data['Buy Signal']], rsi[data['Buy Signal']], marker='^', color='green', s=100, edgecolor='black', label='Buy Signal')
    axes[0].scatter(data.index[data['Sell Signal']], rsi[data['Sell Signal']], marker='v', color='red', s=100, edgecolor='black', label='Sell Signal')
    
    # Adicionar sinais fortes
    axes[0].scatter(data.index[data['Strong Buy']], rsi[data['Strong Buy']], marker='*', color='cyan', s=150, edgecolor='black', label='Strong Buy', alpha=1)
    axes[0].scatter(data.index[data['Strong Sell']], rsi[data['Strong Sell']], marker='*', color='magenta', s=150, edgecolor='black', label='Strong Sell', alpha=1)
    
    axes[0].set_title('RSI')
    axes[0].legend()
    
    # CCI
    axes[1].plot(data.index, cci, label='CCI', color='purple')
    axes[1].axhline(100, linestyle='--', color='red')
    axes[1].axhline(-100, linestyle='--', color='green')
    axes[1].fill_between(data.index, 0, cci, where=(cci < -100), color='lightgreen', alpha=0.5, label='Zona de Compra')
    axes[1].fill_between(data.index, 100, 0, where=(cci > 100), color='salmon', alpha=0.5, label='Zona de Venda')
    axes[1].set_title('CCI')
    axes[1].legend()
    
    # MACD
    axes[2].plot(data.index, macd_line, label='MACD Line', color='blue', linewidth=1.5)
    axes[2].plot(data.index, signal_line, label='Signal Line', color='red', linewidth=1.5)
    axes[2].bar(data.index, histogram, label='Histogram', color='grey')
    axes[2].set_title('MACD')
    axes[2].legend()
    
    # KDJ
    axes[3].plot(data.index, kdj_k, label='KDJ K', color='blue')
    axes[3].plot(data.index, kdj_d, label='KDJ D', color='red')
    axes[3].plot(data.index, kdj_j, label='KDJ J', color='green')
    axes[3].set_title('KDJ')
    axes[3].legend()
    
    # Adicionar timestamp no gráfico
    for ax in axes:
        for label in ax.get_xticklabels():
            label.set_rotation(45)
            label.set_fontsize(6)
            label.set_horizontalalignment('right')
        ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d\n%H:%M'))

    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    plt.show()

def main():
    symbol = select_symbol()
    timeframe = select_timeframe()
    
    if not mt5.initialize():
        print("Falha na inicialização do MetaTrader 5")
        mt5.shutdown()
        return
    
    now = datetime.now()
    rates = mt5.copy_rates_range(symbol, timeframe, now - pd.DateOffset(days=365), now)
    data = pd.DataFrame(rates)
    data['time'] = pd.to_datetime(data['time'], unit='s')
    data.set_index('time', inplace=True)
    
    calculate_signals(data, symbol)
    
    mt5.shutdown()

if __name__ == "__main__":
    main()


remova a janela do KDJ no grafico mas mantenha todas funções e analises de todos indicadores como ja estao  e repito é apenas para remover a janela do KDJ visualmente do grafico nao remova mais nada alem disso!