0vergeared's picture
Update app.py
97518a8 verified
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()