File size: 4,460 Bytes
c104475 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
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}")
|