Skip to content

Commit db3df0c

Browse files
feat: align elements properly
1 parent 7dde401 commit db3df0c

File tree

7 files changed

+212
-949
lines changed

7 files changed

+212
-949
lines changed

examples/csv_validation_example.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77

88
import pandas as pd
9+
910
from quant_research_starter.data import validate_input_csv, validate_price_csv
1011

1112

@@ -23,7 +24,7 @@ def example_validate_price_file():
2324

2425
# Check results
2526
if result["valid"]:
26-
print(f"✓ File is valid!")
27+
print("✓ File is valid!")
2728
print(f" Rows: {result['row_count']}")
2829
print(f" Columns: {result['column_count']}")
2930
else:
@@ -55,7 +56,7 @@ def example_validate_with_required_columns():
5556
if is_valid:
5657
print(f"✓ All required symbols present: {', '.join(required_symbols)}")
5758
else:
58-
print(f"✗ Validation failed:")
59+
print("✗ Validation failed:")
5960
for err in errors:
6061
print(f" {err}")
6162

@@ -76,7 +77,7 @@ def load_and_validate_prices(file_path: str):
7677
if not result["valid"]:
7778
# Handle errors
7879
error_messages = [err["message"] for err in result["errors"]]
79-
raise ValueError(f"Invalid price file:\n" + "\n".join(error_messages))
80+
raise ValueError("Invalid price file:\n" + "\n".join(error_messages))
8081

8182
# If valid, proceed with loading
8283
prices = pd.read_csv(file_path, index_col=0, parse_dates=True)
@@ -102,7 +103,7 @@ def example_detailed_error_info():
102103

103104
result = validate_input_csv("invalid_file.csv", csv_type="price")
104105

105-
print(f"Validation Summary:")
106+
print("Validation Summary:")
106107
print(f" Valid: {result['valid']}")
107108
print(f" Errors: {len(result['errors'])}")
108109
print(f" Warnings: {len(result['warnings'])}")

legacy/streamlit/streamlit_app.py

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,105 @@
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)
32+
2633
df = pd.DataFrame(
2734
{
2835
"date": pd.to_datetime(data["dates"]),
2936
"portfolio_value": data["portfolio_value"],
3037
}
3138
).set_index("date")
32-
fig = px.line(df, y="portfolio_value", title="Portfolio Value")
39+
40+
fig = px.line(
41+
df,
42+
y="portfolio_value",
43+
title="Portfolio Value Over Time",
44+
labels={"portfolio_value": "Portfolio Value"},
45+
)
46+
fig.update_layout(
47+
margin={"l": 30, "r": 30, "t": 40, "b": 30},
48+
height=400,
49+
title_x=0.5,
50+
)
51+
3352
st.plotly_chart(fig, use_container_width=True)
34-
st.json(data.get("metrics", {}))
53+
54+
# Centered metrics section
55+
st.markdown("#### 🔍 Summary Metrics")
56+
metrics = data.get("metrics", {})
57+
if metrics:
58+
mcol1, mcol2, mcol3 = st.columns(3)
59+
items = list(metrics.items())
60+
for i, (key, value) in enumerate(items[:3]):
61+
with [mcol1, mcol2, mcol3][i]:
62+
st.metric(
63+
label=key.replace("_", " ").title(), value=round(value, 4)
64+
)
65+
if len(items) > 3:
66+
st.json(dict(items[3:]))
67+
else:
68+
st.info("No metrics found in results.")
3569
else:
36-
st.info("Run the CLI backtest to generate results.")
70+
st.info("⚠️ Run the CLI backtest to generate results.")
3771

72+
# --- Right: Factor Signals ---
3873
with col2:
39-
st.subheader("Factor Signals")
74+
st.markdown("#### 📉 Factor Signals")
4075
if Path(factors_file).exists():
4176
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)
77+
78+
# Tabs for cleaner organization
79+
tab1, tab2 = st.tabs(["📑 Latest Data", "📊 Composite Signal"])
80+
81+
with tab1:
82+
st.dataframe(
83+
fdf.tail().style.set_table_styles(
84+
[{"selector": "th", "props": [("text-align", "center")]}]
85+
)
86+
)
87+
88+
with tab2:
89+
if "composite" in fdf.columns:
90+
fig2 = px.line(
91+
fdf[["composite"]],
92+
title="Composite Factor Signal",
93+
labels={"composite": "Composite"},
94+
)
95+
fig2.update_layout(
96+
margin={"l": 30, "r": 30, "t": 40, "b": 30},
97+
height=400,
98+
title_x=0.5,
99+
)
100+
st.plotly_chart(fig2, use_container_width=True)
101+
else:
102+
st.info("No composite signal found.")
46103
else:
47-
st.info("Compute factors to view signals.")
104+
st.info("⚠️ Compute factors to view signals.")
48105

106+
# --- Footer ---
49107
st.markdown("---")
50108
st.caption(
51-
"Tip: Use qrs CLI to generate data, factors, and backtest results. Then refresh this page."
109+
"💡 Tip: Use `qrs` CLI to generate data, factors, and backtest results, then refresh this page."
52110
)

notebooks/01-getting-started.ipynb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"\n",
4646
"# Show which Python the kernel is using (debugging)\n",
4747
"import sys as _sys\n",
48+
"\n",
4849
"print(\"Kernel Python:\", _sys.executable)\n"
4950
]
5051
},
@@ -56,14 +57,17 @@
5657
"outputs": [],
5758
"source": [
5859
"# Setup: imports\n",
59-
"import os\n",
60-
"import json\n",
61-
"import pandas as pd\n",
6260
"import matplotlib.pyplot as plt\n",
61+
"import pandas as pd\n",
6362
"\n",
64-
"from quant_research_starter.data import SampleDataLoader, SyntheticDataGenerator\n",
65-
"from quant_research_starter.factors import MomentumFactor, ValueFactor, SizeFactor, VolatilityFactor\n",
6663
"from quant_research_starter.backtest import VectorizedBacktest\n",
64+
"from quant_research_starter.data import SampleDataLoader\n",
65+
"from quant_research_starter.factors import (\n",
66+
" MomentumFactor,\n",
67+
" SizeFactor,\n",
68+
" ValueFactor,\n",
69+
" VolatilityFactor,\n",
70+
")\n",
6771
"from quant_research_starter.metrics import RiskMetrics\n",
6872
"\n"
6973
]

output/backtest_plot.png

28.9 KB
Loading

0 commit comments

Comments
 (0)