
import ccxt
import pandas as pd

def get_ohlcv(symbol, timeframe):
    exchange = ccxt.binance()
    ohlcv = exchange.fetch_ohlcv(symbol, timeframe)
    df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
    df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
    return df

def get_trend(df):
    df['ema20'] = df['close'].ewm(span=20, adjust=False).mean()
    df['ema50'] = df['close'].ewm(span=50, adjust=False).mean()
    df['rsi'] = 100 - (100 / (1 + df['close'].diff().apply(lambda x: x if x > 0 else 0).ewm(alpha=1/14, adjust=False).mean() / df['close'].diff().apply(lambda x: abs(x) if x < 0 else 0).ewm(alpha=1/14, adjust=False).mean()))

    last_row = df.iloc[-1]
    if last_row['ema20'] > last_row['ema50'] and last_row['close'] > last_row['ema20'] and last_row['rsi'] > 50:
        return 'UP'
    elif last_row['ema20'] < last_row['ema50'] and last_row['close'] < last_row['ema20'] and last_row['rsi'] < 50:
        return 'DOWN'
    else:
        return None

def get_setup(df):
    df['rsi'] = 100 - (100 / (1 + df['close'].diff().apply(lambda x: x if x > 0 else 0).ewm(alpha=1/14, adjust=False).mean() / df['close'].diff().apply(lambda x: abs(x) if x < 0 else 0).ewm(alpha=1/14, adjust=False).mean()))

    last_row = df.iloc[-1]
    if last_row['rsi'] > 40 and last_row['rsi'] < 60:
        return True
    else:
        return False

def get_entry(df):
    df['ema20'] = df['close'].ewm(span=20, adjust=False).mean()
    df['ema50'] = df['close'].ewm(span=50, adjust=False).mean()
    df['rsi'] = 100 - (100 / (1 + df['close'].diff().apply(lambda x: x if x > 0 else 0).ewm(alpha=1/14, adjust=False).mean() / df['close'].diff().apply(lambda x: abs(x) if x < 0 else 0).ewm(alpha=1/14, adjust=False).mean()))
    df['volume_sma20'] = df['volume'].rolling(window=20).mean()

    last_row = df.iloc[-1]
    if last_row['ema20'] > last_row['ema50'] and last_row['rsi'] > 50 and last_row['close'] > last_row['ema20'] and last_row['volume'] > last_row['volume_sma20']:
        return 'BUY'
    elif last_row['ema20'] < last_row['ema50'] and last_row['rsi'] < 50 and last_row['close'] < last_row['ema20'] and last_row['volume'] > last_row['volume_sma20']:
        return 'SELL'
    else:
        return 'WAIT'

def generate_signal(symbol):
    # 1h trend
    df_1h = get_ohlcv(symbol, '1h')
    trend = get_trend(df_1h)

    if trend:
        # 15m setup
        df_15m = get_ohlcv(symbol, '15m')
        setup = get_setup(df_15m)

        if setup:
            # 5m entry
            df_5m = get_ohlcv(symbol, '5m')
            entry = get_entry(df_5m)

            if (trend == 'UP' and entry == 'BUY') or (trend == 'DOWN' and entry == 'SELL'):
                return entry

    return 'WAIT'

