Spaces:
Running
Running
File size: 4,752 Bytes
4cb21eb bf96dc6 4cb21eb | 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 | import streamlit as st
import tensorflow as tf
import pandas as pd
import numpy as np
from src.data_fetcher import DataFetcher
from src.processor import Processor
from src.strategy import get_market_regime
st.set_page_config(page_title="Alpha Predict", page_icon="πΉ", layout="wide")
@st.cache_resource
def load_alpha_model():
return tf.keras.models.load_model("models/gru_booster_model.keras")
@st.cache_resource
def load_processor():
return Processor()
def main():
st.title("πΉ Alpha Predict")
st.markdown("---")
with st.sidebar:
st.header("π Strategy Logic")
st.markdown("""
**Objective:** Directional probability for the next session.
- **π’ GREEN (β₯ 57.8%)**: 3x Leverage (SPXL/UPRO)
- **π‘ YELLOW (53.0% - 57.7%)**: 1x Exposure (SPY/VOO)
- **π΄ RED (< 53.0%)**: Cash (0x)
""")
st.divider()
st.caption("Alpha Predict")
fetcher = DataFetcher()
processor = load_processor()
model = load_alpha_model()
if st.button("Generate Today's Signal", type="primary"):
with st.spinner("π Analyzing Market Nervous System..."):
# 1. Fetch data (Fetch 60 days to allow for the 26-day MACD EMA dropping NaNs)
market_df = fetcher.fetch_market_data(days=60)
news_df = fetcher.fetch_market_news(days=45)
st.warning(f"Earliest news fetched: {news_df['Date'].min()} | Total Headlines: {len(news_df)}")
# 2. Process - Now unpacking 4 items (df_features gives us the history!)
input_tensor, metrics, df_features, scored_news = processor.process(market_df, news_df)
# 3. Predict
prediction_prob = float(model.predict(input_tensor)[0][0])
# 4. Get Strategy Regime
regime = get_market_regime(prediction_prob)
# 5. UI Metrics
latest_vix = market_df['VIX'].iloc[-1]
prev_vix = market_df['VIX'].iloc[-2]
current_price = market_df['Close'].iloc[-1]
col1, col2, col3 = st.columns(3)
col1.metric("S&P 500 Baseline", f"${current_price:,.2f}")
col2.metric("VIX (Fear Gauge)", f"{latest_vix:.2f}",
delta=f"{latest_vix - prev_vix:+.2f} Fear", delta_color="inverse")
col3.metric("FinBERT Sentiment", f"{metrics['Sent_Mean']:+.2f}",
delta=f"{int(metrics['News_Volume'])} Headlines")
with st.expander("π How to interpret these values?"):
c1, c2 = st.columns(2)
c1.markdown("**VIX:** <15 Calm, 15-25 Normal, >25 Panic.")
c2.markdown("**Sentiment:** >+0.1 Bullish, Β±0.1 Neutral, <-0.1 Bearish.")
st.divider()
# --- REGIME DISPLAY ---
st.subheader(f"{regime['icon']} Current Regime: :{regime['color']}[{regime['zone']}]")
res1, res2 = st.columns([1, 2])
res1.metric("Bullish Probability", f"{prediction_prob:.2%}")
res2.info(f"**Recommended Action:** {regime['action']}")
# --- LOGIC BREAKDOWN ---
st.write("### π§ Logic Breakdown (Last 30 Days)")
e_col1, e_col2 = st.columns(2)
with e_col1:
st.write("**Volatility Regime (VIX)**")
vix_trend = market_df['VIX'].tail(30)
st.line_chart(vix_trend)
vix_slope = vix_trend.iloc[-1] - vix_trend.iloc[0]
if vix_slope > 2:
st.warning(f"β οΈ Volatility is **trending up** (+{vix_slope:.1f}pts). The AI sees rising instability.")
elif vix_slope < -2:
st.success(f"β
Volatility is **cooling off** ({vix_slope:.1f}pts). This supports the bullish case.")
else:
st.info("βοΈ Volatility is sideways. The model is focused on other factors.")
with e_col2:
st.write("**Sentiment Momentum (FinBERT)**")
# FIX: We now pull the historical trend from df_features!
sent_trend = df_features['Sent_Mean'].tail(30)
st.area_chart(sent_trend)
avg_30d = sent_trend.mean()
st.write(f"30-Day Avg Sentiment: **{avg_30d:+.2f}**")
if metrics['Sent_Mean'] > avg_30d:
st.write("π Today's news is **stronger** than the monthly average.")
else:
st.write("π Today's news is **weaker** than the monthly average.")
if __name__ == "__main__":
main() |