"""
Overview page — trading terminal home screen.
Shows KPI cards, strategy scatter plot, and recent signal summary.
"""
from datetime import datetime
import pandas as pd
import plotly.express as px
import streamlit as st
from tradingagents.ui.theme import COLORS, get_plotly_template, kpi_card, page_header
from tradingagents.ui.utils import (
load_open_positions,
load_recommendations,
load_statistics,
load_strategy_metrics,
)
def render() -> None:
"""Render the overview page."""
st.markdown(
page_header("Overview", f"Market session {datetime.now().strftime('%A, %B %d %Y')}"),
unsafe_allow_html=True,
)
stats = load_statistics()
positions = load_open_positions()
strategy_metrics = load_strategy_metrics()
overall = stats.get("overall_7d", {}) if stats else {}
win_rate_7d = overall.get("win_rate", 0)
avg_return_7d = overall.get("avg_return", 0)
total_recs = stats.get("total_recommendations", 0) if stats else 0
open_count = len(positions) if positions else 0
best_strat_name = "N/A"
best_strat_wr = 0.0
for item in strategy_metrics or []:
wr = item.get("Win Rate", 0) or 0
if wr > best_strat_wr:
best_strat_wr = wr
best_strat_name = item.get("Strategy", "unknown")
# ---- KPI Row ----
cols = st.columns(5)
kpis = [
(
"Win Rate 7d",
f"{win_rate_7d:.0f}%",
(
f"+{win_rate_7d - 50:.0f}pp vs 50%"
if win_rate_7d >= 50
else f"{win_rate_7d - 50:.0f}pp vs 50%"
),
"green" if win_rate_7d >= 50 else "red",
),
("Avg Return 7d", f"{avg_return_7d:+.2f}%", "", "green" if avg_return_7d > 0 else "red"),
("Open Positions", str(open_count), "", "blue"),
("Total Signals", str(total_recs), "", "amber"),
(
"Top Strategy",
best_strat_name.upper(),
f"{best_strat_wr:.0f}% WR" if best_strat_wr else "",
"green" if best_strat_wr >= 60 else "amber",
),
]
for col, (label, value, delta, color) in zip(cols, kpis):
with col:
st.markdown(kpi_card(label, value, delta, color), unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
# ---- Two-column: strategy chart + today's signals ----
left_col, right_col = st.columns([3, 2])
with left_col:
st.markdown(
'Strategy Performance // scatter
',
unsafe_allow_html=True,
)
if strategy_metrics:
df = pd.DataFrame(strategy_metrics)
template = get_plotly_template()
fig = px.scatter(
df,
x="Win Rate",
y="Avg Return",
size="Count",
color="Strategy",
hover_name="Strategy",
hover_data={
"Win Rate": ":.1f",
"Avg Return": ":.2f",
"Count": True,
"Strategy": False,
},
labels={"Win Rate": "Win Rate (%)", "Avg Return": "Avg Return (%)"},
size_max=40,
)
fig.add_hline(y=0, line_dash="dot", line_color=COLORS["text_muted"], opacity=0.4)
fig.add_vline(x=50, line_dash="dot", line_color=COLORS["text_muted"], opacity=0.4)
fig.add_annotation(
x=75,
y=5,
text="WINNERS",
showarrow=False,
font=dict(size=10, color=COLORS["green"], family="JetBrains Mono"),
opacity=0.3,
)
fig.add_annotation(
x=25,
y=-5,
text="LOSERS",
showarrow=False,
font=dict(size=10, color=COLORS["red"], family="JetBrains Mono"),
opacity=0.3,
)
fig.update_layout(
**template,
height=380,
showlegend=True,
legend=dict(
bgcolor="rgba(0,0,0,0)",
font=dict(size=10),
orientation="h",
yanchor="bottom",
y=-0.25,
),
)
st.plotly_chart(fig, width="stretch")
else:
st.info("Run the discovery pipeline to generate strategy data.")
with right_col:
st.markdown(
'Today\'s Signals // latest
',
unsafe_allow_html=True,
)
today = datetime.now().strftime("%Y-%m-%d")
recs = load_recommendations(today)
if recs:
for rec in recs[:6]:
ticker = rec.get("ticker", "???")
score = rec.get("final_score", 0)
conf = rec.get("confidence", 0)
strat = (rec.get("strategy_match") or "momentum").upper()
entry = rec.get("entry_price")
entry_str = f"${entry:.2f}" if entry else "N/A"
score_color = (
COLORS["green"]
if score >= 35
else (COLORS["amber"] if score >= 20 else COLORS["text_muted"])
)
conf_bar_w = conf * 10
conf_color = (
COLORS["green"]
if conf >= 8
else (COLORS["amber"] if conf >= 6 else COLORS["red"])
)
st.markdown(
f"""
""",
unsafe_allow_html=True,
)
if len(recs) > 6:
st.caption(
f"+{len(recs) - 6} more signals. Switch to Signals page for the full list."
)
else:
st.info("No signals generated today.")
# ---- Strategy table ----
if strategy_metrics:
st.markdown("", unsafe_allow_html=True)
st.markdown(
'Strategy Breakdown // table
',
unsafe_allow_html=True,
)
df_table = pd.DataFrame(strategy_metrics).sort_values("Win Rate", ascending=False)
st.dataframe(
df_table,
width="stretch",
hide_index=True,
column_config={
"Win Rate": st.column_config.NumberColumn(format="%.1f%%"),
"Avg Return": st.column_config.NumberColumn(format="%+.2f%%"),
"Count": st.column_config.NumberColumn(format="%d"),
},
)