|
|
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 |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
st.title("πΉ AI-Powered Crypto Signal Detector") |
|
|
st.markdown("Predict **LONG / SHORT / HOLD** signals using EMA, RSI, MACD and XGBoost.") |
|
|
|
|
|
|
|
|
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("---") |
|
|
|
|
|
|
|
|
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') |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
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() |
|
|
|
|
|
|
|
|
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}) |
|
|
|
|
|
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] |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
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}) |
|
|
|
|
|
|
|
|
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')) |
|
|
|
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
st.success("β
Model completed! Scroll up for results and chart.") |
|
|
st.markdown(f"**Dataset size:** {len(df)} rowsβ|β**Features:** {len(features)}β|β**Symbol:** {symbol}") |
|
|
|