import streamlit as st import pandas as pd import numpy as np import ccxt import matplotlib.pyplot as plt from ta.momentum import RSIIndicator from ta.trend import EMAIndicator, MACD, ADXIndicator from ta.volatility import BollingerBands from xgboost import XGBClassifier from sklearn.model_selection import TimeSeriesSplit from sklearn.metrics import classification_report # --- PAGE SETUP --- st.set_page_config(page_title="AI Crypto Signal Detector", page_icon="πŸ’Ή", layout="wide") st.markdown(""" """, unsafe_allow_html=True) # --- HEADER --- st.title("πŸ’Ή AI-Powered Crypto Signal Detector") st.markdown("Predict **LONG / SHORT / HOLD** signals using EMA, RSI, MACD and XGBoost.") # --- USER INPUTS --- col1, col2, col3 = st.columns(3) with col1: symbol = st.selectbox("Select Crypto Pair", ["BTC/USDT", "ETH/USDT", "BNB/USDT", "SOL/USDT"]) with col2: timeframe = st.selectbox("Timeframe", ["1h", "4h", "1d"]) with col3: limit = st.slider("Number of Candles", 500, 5000, 2000, step=500) st.markdown("---") # --- FETCH & RUN --- if st.button("πŸš€ Run Model"): st.info("Fetching data and training model … please wait β‰ˆ 30 sec") exchange = ccxt.binance() bars = exchange.fetch_ohlcv(symbol, timeframe=timeframe, limit=limit) df = pd.DataFrame(bars, columns=['ts','open','high','low','close','vol']) df['ts'] = pd.to_datetime(df['ts'], unit='ms') df = df.set_index('ts') # --- FEATURES --- df['ret1'] = df['close'].pct_change() df['ema12'] = EMAIndicator(df['close'], window=12).ema_indicator() df['ema26'] = EMAIndicator(df['close'], window=26).ema_indicator() df['ema_diff'] = df['ema12'] - df['ema26'] df['rsi14'] = RSIIndicator(df['close'], window=14).rsi() bb = BollingerBands(df['close']) df['bb_high'] = bb.bollinger_hband() df['bb_low'] = bb.bollinger_lband() macd = MACD(df['close']) df['macd'] = macd.macd() df['macd_signal'] = macd.macd_signal() adx = ADXIndicator(df['high'], df['low'], df['close']) df['adx'] = adx.adx() df = df.dropna() # --- TARGET --- fwd_horizon = 3 future_ret = df['close'].shift(-fwd_horizon) / df['close'] - 1 thr = 0.005 df['target'] = np.where(future_ret > thr, 1, np.where(future_ret < -thr, -1, 0)) df = df.dropna() # --- MODEL DATA --- features = ['ema_diff','rsi14','bb_high','bb_low','macd','macd_signal','adx','ret1'] X = df[features] y = df['target'].map({-1:0,0:1,1:2}) # map for XGBoost tscv = TimeSeriesSplit(n_splits=5) train_idx, test_idx = list(tscv.split(X))[-1] X_train, X_test = X.iloc[train_idx], X.iloc[test_idx] y_train, y_test = y.iloc[train_idx], y.iloc[test_idx] # --- MODEL TRAIN --- clf = XGBClassifier(n_estimators=300, learning_rate=0.05, max_depth=6, subsample=0.8, colsample_bytree=0.8, random_state=42) clf.fit(X_train, y_train) # --- PREDICT --- y_pred = clf.predict(X_test) df_test = df.iloc[test_idx].copy() df_test['pred'] = pd.Series(y_pred).map({0:-1,1:0,2:1}) # --- REPORT --- y_true = pd.Series(y_test).map({0:-1,1:0,2:1}) report = classification_report(y_true, df_test['pred'], output_dict=True) st.subheader("πŸ“Š Model Performance") st.write(pd.DataFrame(report).transpose().style.background_gradient(cmap='Blues')) # --- PLOT SIGNALS --- st.subheader("πŸ“ˆ Signals on Price Chart") fig, ax = plt.subplots(figsize=(12,5)) ax.plot(df_test.index, df_test['close'], label='Close Price', color='cyan') ax.scatter(df_test.index[df_test['pred']==1], df_test['close'][df_test['pred']==1], color='lime', label='LONG', marker='^', s=80) ax.scatter(df_test.index[df_test['pred']==-1], df_test['close'][df_test['pred']==-1], color='red', label='SHORT', marker='v', s=80) ax.set_facecolor("#0e1117") ax.legend() st.pyplot(fig) # --- SUMMARY --- st.success("βœ… Model completed! Scroll up for results and chart.") st.markdown(f"**Dataset size:** {len(df)} rows | **Features:** {len(features)} | **Symbol:** {symbol}")