import dash from dash import html, dcc, Input, Output import plotly.graph_objs as go import pandas as pd import ccxt from datetime import datetime from plotly.subplots import make_subplots # Init MEXC exchange = ccxt.mexc() markets = exchange.load_markets() symbols = sorted([symbol for symbol in markets if "/USDT" in symbol]) timeframes = list(exchange.timeframes.keys()) DEFAULT_SYMBOL = "BTC/USDT" DEFAULT_TIMEFRAME = "1h" def fetch_ohlcv(symbol, timeframe): try: 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 except Exception as e: print(f"❌ Error: {e}") return pd.DataFrame() def add_indicators(df): df = df.copy() df['ema12'] = df['close'].ewm(span=12).mean() df['ema26'] = df['close'].ewm(span=26).mean() df['macd'] = df['ema12'] - df['ema26'] df['macd_signal'] = df['macd'].ewm(span=9).mean() delta = df['close'].diff() gain = delta.clip(lower=0) loss = -delta.clip(upper=0) avg_gain = gain.rolling(14).mean() avg_loss = loss.rolling(14).mean() rs = avg_gain / avg_loss df['rsi'] = 100 - (100 / (1 + rs)) return df def add_signals(df): df['buy'] = (df['macd'] > df['macd_signal']) & (df['macd'].shift(1) <= df['macd_signal'].shift(1)) & (df['rsi'] < 50) df['sell'] = (df['macd'] < df['macd_signal']) & (df['macd'].shift(1) >= df['macd_signal'].shift(1)) & (df['rsi'] > 50) return df def create_chart(df): fig = make_subplots(rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.02, row_heights=[0.6, 0.2, 0.2]) fig.add_trace(go.Candlestick(x=df['timestamp'], open=df['open'], high=df['high'], low=df['low'], close=df['close'], name='Candles'), row=1, col=1) fig.add_trace(go.Scatter(x=df['timestamp'], y=df['rsi'], name='RSI', line=dict(color='orange')), row=2, col=1) fig.add_trace(go.Scatter(x=df['timestamp'], y=df['macd'], name='MACD', line=dict(color='blue')), row=3, col=1) fig.add_trace(go.Scatter(x=df['timestamp'], y=df['macd_signal'], name='MACD Signal', line=dict(color='red')), row=3, col=1) # Signal markers buys = df[df['buy']] sells = df[df['sell']] fig.add_trace(go.Scatter(x=buys['timestamp'], y=buys['close'], mode='markers', name='Buy', marker=dict(color='green', size=10, symbol='triangle-up')), row=1, col=1) fig.add_trace(go.Scatter(x=sells['timestamp'], y=sells['close'], mode='markers', name='Sell', marker=dict(color='red', size=10, symbol='triangle-down')), row=1, col=1) fig.update_layout(height=800, margin=dict(t=30, b=20), showlegend=True) return fig # Dash App app = dash.Dash(__name__) app.title = "MEXC AI Signals" app.layout = html.Div([ html.H2("📈 MEXC Crypto Signal Chart", style={'textAlign': 'center'}), html.Div([ html.Label("Select Pair:"), dcc.Dropdown(id="pair-dropdown", options=[{"label": s, "value": s} for s in symbols], value=DEFAULT_SYMBOL, style={"width": "100%"}) ], style={"width": "30%", "display": "inline-block"}), html.Div([ html.Label("Timeframes:"), html.Div([ html.Button(tf, id={'type': 'tf-button', 'index': tf}, n_clicks=0, style={"margin": "2px", "width": "50px"}) for tf in timeframes ], id="tf-button-row") ], style={"width": "68%", "display": "inline-block"}), dcc.Store(id="selected-timeframe", data=DEFAULT_TIMEFRAME), dcc.Graph(id="chart", config={"displayModeBar": True}), html.Div(id="signal-box", style={"marginTop": "10px", "textAlign": "center", "fontSize": "16px"}) ]) @app.callback( Output("selected-timeframe", "data"), Input({'type': 'tf-button', 'index': dash.dependencies.ALL}, 'n_clicks') ) def update_timeframe(n_clicks_list): ctx = dash.callback_context if not ctx.triggered: return DEFAULT_TIMEFRAME triggered_id = ctx.triggered[0]["prop_id"].split(".")[0] timeframe = eval(triggered_id)["index"] return timeframe @app.callback( [Output("chart", "figure"), Output("signal-box", "children")], [Input("pair-dropdown", "value"), Input("selected-timeframe", "data")] ) def update_chart(symbol, timeframe): df = fetch_ohlcv(symbol, timeframe) if df.empty: return go.Figure(), "❌ No data available" df = add_indicators(df) df = add_signals(df) latest_signal = "🔍 No recent signal" if df['buy'].iloc[-1]: latest_signal = f"🟢 Latest Signal: BUY at {df['close'].iloc[-1]:.2f} on {df['timestamp'].iloc[-1]}" elif df['sell'].iloc[-1]: latest_signal = f"🔴 Latest Signal: SELL at {df['close'].iloc[-1]:.2f} on {df['timestamp'].iloc[-1]}" fig = create_chart(df) return fig, latest_signal if __name__ == "__main__": app.run(host="0.0.0.0", port=7860)