Crypto / app.py
Amaanali01's picture
Create app.py
c104475 verified
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("""
<style>
.reportview-container {
background: #0e1117;
color: #fafafa;
}
h1,h2,h3 { color: #0df2c8; }
.sidebar .sidebar-content {
background: #111;
}
div.stButton > button {
color: white;
background-color: #00b894;
border-radius: 10px;
height: 3em;
width: 100%;
}
</style>
""", 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}")