Skip to content

Commit a851c17

Browse files
feat: aligned elements properly
1 parent 9da3917 commit a851c17

File tree

1 file changed

+73
-23
lines changed

1 file changed

+73
-23
lines changed

src/quant_research_starter/dashboard/streamlit_app.py

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,97 @@
66
import streamlit as st
77

88
st.set_page_config(page_title="Quant Research Starter", layout="wide")
9-
st.title("Quant Research Starter Dashboard")
10-
9+
st.title("📊 Quant Research Starter Dashboard")
1110
output_dir = Path.cwd() / "output"
1211
default_results = output_dir / "backtest_results.json"
1312
default_factors = output_dir / "factors.csv"
1413

15-
st.sidebar.header("Inputs")
14+
# --- Sidebar Inputs ---
15+
st.sidebar.header("⚙️ Inputs")
1616
results_file = st.sidebar.text_input("Backtest results JSON", str(default_results))
1717
factors_file = st.sidebar.text_input("Factors CSV", str(default_factors))
1818

19-
col1, col2 = st.columns(2)
19+
# --- Main Layout ---
20+
st.markdown("### Overview")
21+
st.caption("Visualize portfolio performance and factor signals side-by-side.")
22+
23+
# Create two balanced columns
24+
col1, col2 = st.columns([1, 1], gap="large")
2025

26+
# --- Left: Equity Curve ---
2127
with col1:
22-
st.subheader("Equity Curve")
28+
st.markdown("#### 📈 Equity Curve")
2329
if Path(results_file).exists():
2430
with open(results_file) as f:
2531
data = json.load(f)
26-
df = pd.DataFrame(
27-
{
28-
"date": pd.to_datetime(data["dates"]),
29-
"portfolio_value": data["portfolio_value"],
30-
}
31-
).set_index("date")
32-
fig = px.line(df, y="portfolio_value", title="Portfolio Value")
32+
33+
df = pd.DataFrame({
34+
"date": pd.to_datetime(data["dates"]),
35+
"portfolio_value": data["portfolio_value"],
36+
}).set_index("date")
37+
38+
fig = px.line(
39+
df,
40+
y="portfolio_value",
41+
title="Portfolio Value Over Time",
42+
labels={"portfolio_value": "Portfolio Value"},
43+
)
44+
fig.update_layout(
45+
margin=dict(l=30, r=30, t=40, b=30),
46+
height=400,
47+
title_x=0.5,
48+
)
49+
3350
st.plotly_chart(fig, use_container_width=True)
34-
st.json(data.get("metrics", {}))
51+
52+
# Centered metrics section
53+
st.markdown("#### 🔍 Summary Metrics")
54+
metrics = data.get("metrics", {})
55+
if metrics:
56+
mcol1, mcol2, mcol3 = st.columns(3)
57+
items = list(metrics.items())
58+
for i, (key, value) in enumerate(items[:3]):
59+
with [mcol1, mcol2, mcol3][i]:
60+
st.metric(label=key.replace("_", " ").title(), value=round(value, 4))
61+
if len(items) > 3:
62+
st.json(dict(items[3:]))
63+
else:
64+
st.info("No metrics found in results.")
3565
else:
36-
st.info("Run the CLI backtest to generate results.")
66+
st.info("⚠️ Run the CLI backtest to generate results.")
3767

68+
# --- Right: Factor Signals ---
3869
with col2:
39-
st.subheader("Factor Signals")
70+
st.markdown("#### 📉 Factor Signals")
4071
if Path(factors_file).exists():
4172
fdf = pd.read_csv(factors_file, index_col=0, parse_dates=True)
42-
st.dataframe(fdf.tail())
43-
if "composite" in fdf.columns:
44-
fig2 = px.line(fdf[["composite"]], title="Composite Signal")
45-
st.plotly_chart(fig2, use_container_width=True)
73+
74+
# Tabs for cleaner organization
75+
tab1, tab2 = st.tabs(["📑 Latest Data", "📊 Composite Signal"])
76+
77+
with tab1:
78+
st.dataframe(fdf.tail().style.set_table_styles(
79+
[{'selector': 'th', 'props': [('text-align', 'center')]}]
80+
))
81+
82+
with tab2:
83+
if "composite" in fdf.columns:
84+
fig2 = px.line(
85+
fdf[["composite"]],
86+
title="Composite Factor Signal",
87+
labels={"composite": "Composite"},
88+
)
89+
fig2.update_layout(
90+
margin=dict(l=30, r=30, t=40, b=30),
91+
height=400,
92+
title_x=0.5,
93+
)
94+
st.plotly_chart(fig2, use_container_width=True)
95+
else:
96+
st.info("No composite signal found.")
4697
else:
47-
st.info("Compute factors to view signals.")
98+
st.info("⚠️ Compute factors to view signals.")
4899

100+
# --- Footer ---
49101
st.markdown("---")
50-
st.caption(
51-
"Tip: Use qrs CLI to generate data, factors, and backtest results. Then refresh this page."
52-
)
102+
st.caption("💡 Tip: Use `qrs` CLI to generate data, factors, and backtest results, then refresh this page.")

0 commit comments

Comments
 (0)