import ccxt import pandas as pd import plotly.graph_objects as go import gradio as gr # Fetch OHLCV from MEXC def fetch_ohlcv(symbol='BTC/USDT', timeframe='1h', limit=150): exchange = ccxt.mexc() ohlcv = exchange.fetch_ohlcv(symbol, timeframe=timeframe, limit=limit) df = pd.DataFrame(ohlcv, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume']) df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms') return df # Indicators def calculate_ema(df, period): return df['close'].ewm(span=period, adjust=False).mean() def calculate_supertrend(df, period=10, multiplier=3): hl2 = (df['high'] + df['low']) / 2 atr = (df['high'] - df['low']).rolling(period).mean() upper = hl2 + multiplier * atr lower = hl2 - multiplier * atr st = [True] * len(df) for i in range(1, len(df)): if df['close'].iloc[i] > upper.iloc[i - 1]: st[i] = True elif df['close'].iloc[i] < lower.iloc[i - 1]: st[i] = False else: st[i] = st[i - 1] return pd.Series(st, index=df.index) def calculate_rsi(df, period=14): delta = df['close'].diff() gain = delta.clip(lower=0) loss = -delta.clip(upper=0) avg_gain = gain.rolling(period).mean() avg_loss = loss.rolling(period).mean() rs = avg_gain / avg_loss return 100 - (100 / (1 + rs)) def detect_rsi_divergence(df): df['rsi'] = calculate_rsi(df) df['bullish_div'] = False df['bearish_div'] = False for i in range(2, len(df)): if (df['close'].iloc[i] < df['close'].iloc[i - 1] < df['close'].iloc[i - 2] and df['rsi'].iloc[i] > df['rsi'].iloc[i - 1] > df['rsi'].iloc[i - 2]): df.at[df.index[i], 'bullish_div'] = True if (df['close'].iloc[i] > df['close'].iloc[i - 1] > df['close'].iloc[i - 2] and df['rsi'].iloc[i] < df['rsi'].iloc[i - 1] < df['rsi'].iloc[i - 2]): df.at[df.index[i], 'bearish_div'] = True return df # Signal Logic def generate_signal(df): df['ema_50'] = calculate_ema(df, 50) df['ema_200'] = calculate_ema(df, 200) df['supertrend'] = calculate_supertrend(df) df = detect_rsi_divergence(df) ema_sig = 'BULLISH' if df['ema_50'].iloc[-1] > df['ema_200'].iloc[-1] else 'BEARISH' st_sig = 'BULLISH' if df['supertrend'].iloc[-1] else 'BEARISH' if ema_sig == 'BULLISH' and st_sig == 'BULLISH': label = "🔥 STRONG BUY" elif ema_sig == 'BEARISH' and st_sig == 'BEARISH': label = "💀 STRONG SELL" elif ema_sig == st_sig: label = f"⚠️ {ema_sig}" else: label = "🤔 NEUTRAL / HOLD" if df['bullish_div'].iloc[-1]: label += " + 📈 Bullish RSI Divergence" if df['bearish_div'].iloc[-1]: label += " + 📉 Bearish RSI Divergence" return label # Plotly chart def plot_chart(df): df['ema_50'] = calculate_ema(df, 50) df['ema_200'] = calculate_ema(df, 200) df['supertrend'] = calculate_supertrend(df) df = detect_rsi_divergence(df) fig = go.Figure() fig.add_trace(go.Candlestick( x=df['timestamp'], open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='Candles' )) fig.add_trace(go.Scatter(x=df['timestamp'], y=df['ema_50'], line=dict(color='orange'), name='EMA 50')) fig.add_trace(go.Scatter(x=df['timestamp'], y=df['ema_200'], line=dict(color='purple'), name='EMA 200')) bull = df[df['bullish_div']] bear = df[df['bearish_div']] fig.add_trace(go.Scatter( x=bull['timestamp'], y=bull['low'], mode='markers+text', text=['📈']*len(bull), textposition="bottom center", marker=dict(color='green', size=10), name='Bullish RSI Divergence' )) fig.add_trace(go.Scatter( x=bear['timestamp'], y=bear['high'], mode='markers+text', text=['📉']*len(bear), textposition="top center", marker=dict(color='red', size=10), name='Bearish RSI Divergence' )) fig.update_layout( title="Interactive Crypto Chart", xaxis_rangeslider_visible=False, xaxis_title="Time", yaxis_title="Price", template="plotly_dark", margin=dict(t=40, b=40), height=600 ) return fig # Gradio handler def analyze(pair, timeframe): try: df = fetch_ohlcv(pair, timeframe) if len(df) < 50: return "⚠️ Not enough data", go.Figure() signal = generate_signal(df) chart = plot_chart(df) return signal, chart except Exception as e: return f"❌ Error: {e}", go.Figure() # Available pairs and timeframes pairs = ['BTC/USDT', 'ETH/USDT', 'SOL/USDT', 'MX/USDT'] timeframes = ['1m', '5m', '15m', '1h', '4h'] with gr.Blocks() as demo: gr.Markdown("## 📊 Crypto Signal Generator with Interactive Chart") with gr.Row(): pair_dropdown = gr.Dropdown(choices=pairs, value='BTC/USDT', label="Trading Pair") timeframe_dropdown = gr.Dropdown(choices=timeframes, value='1h', label="Timeframe") run_button = gr.Button("🔍 Analyze") signal_output = gr.Textbox(label="Trading Signal", interactive=False) chart_output = gr.Plot(label="Interactive Chart") run_button.click(fn=analyze, inputs=[pair_dropdown, timeframe_dropdown], outputs=[signal_output, chart_output]) demo.launch()