Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions examples/csv_validation_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""

import pandas as pd

from quant_research_starter.data import validate_input_csv, validate_price_csv


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

# Check results
if result["valid"]:
print(f"✓ File is valid!")
print("✓ File is valid!")
print(f" Rows: {result['row_count']}")
print(f" Columns: {result['column_count']}")
else:
Expand Down Expand Up @@ -55,7 +56,7 @@ def example_validate_with_required_columns():
if is_valid:
print(f"✓ All required symbols present: {', '.join(required_symbols)}")
else:
print(f"✗ Validation failed:")
print("✗ Validation failed:")
for err in errors:
print(f" {err}")

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

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

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

print(f"Validation Summary:")
print("Validation Summary:")
print(f" Valid: {result['valid']}")
print(f" Errors: {len(result['errors'])}")
print(f" Warnings: {len(result['warnings'])}")
Expand Down
88 changes: 73 additions & 15 deletions legacy/streamlit/streamlit_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,105 @@
import streamlit as st

st.set_page_config(page_title="Quant Research Starter", layout="wide")
st.title("Quant Research Starter Dashboard")

st.title("📊 Quant Research Starter Dashboard")
output_dir = Path.cwd() / "output"
default_results = output_dir / "backtest_results.json"
default_factors = output_dir / "factors.csv"

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

col1, col2 = st.columns(2)
# --- Main Layout ---
st.markdown("### Overview")
st.caption("Visualize portfolio performance and factor signals side-by-side.")

# Create two balanced columns
col1, col2 = st.columns([1, 1], gap="large")

# --- Left: Equity Curve ---
with col1:
st.subheader("Equity Curve")
st.markdown("#### 📈 Equity Curve")
if Path(results_file).exists():
with open(results_file) as f:
data = json.load(f)

df = pd.DataFrame(
{
"date": pd.to_datetime(data["dates"]),
"portfolio_value": data["portfolio_value"],
}
).set_index("date")
fig = px.line(df, y="portfolio_value", title="Portfolio Value")

fig = px.line(
df,
y="portfolio_value",
title="Portfolio Value Over Time",
labels={"portfolio_value": "Portfolio Value"},
)
fig.update_layout(
margin={"l": 30, "r": 30, "t": 40, "b": 30},
height=400,
title_x=0.5,
)

st.plotly_chart(fig, use_container_width=True)
st.json(data.get("metrics", {}))

# Centered metrics section
st.markdown("#### 🔍 Summary Metrics")
metrics = data.get("metrics", {})
if metrics:
mcol1, mcol2, mcol3 = st.columns(3)
items = list(metrics.items())
for i, (key, value) in enumerate(items[:3]):
with [mcol1, mcol2, mcol3][i]:
st.metric(
label=key.replace("_", " ").title(), value=round(value, 4)
)
if len(items) > 3:
st.json(dict(items[3:]))
else:
st.info("No metrics found in results.")
else:
st.info("Run the CLI backtest to generate results.")
st.info("⚠️ Run the CLI backtest to generate results.")

# --- Right: Factor Signals ---
with col2:
st.subheader("Factor Signals")
st.markdown("#### 📉 Factor Signals")
if Path(factors_file).exists():
fdf = pd.read_csv(factors_file, index_col=0, parse_dates=True)
st.dataframe(fdf.tail())
if "composite" in fdf.columns:
fig2 = px.line(fdf[["composite"]], title="Composite Signal")
st.plotly_chart(fig2, use_container_width=True)

# Tabs for cleaner organization
tab1, tab2 = st.tabs(["📑 Latest Data", "📊 Composite Signal"])

with tab1:
st.dataframe(
fdf.tail().style.set_table_styles(
[{"selector": "th", "props": [("text-align", "center")]}]
)
)

with tab2:
if "composite" in fdf.columns:
fig2 = px.line(
fdf[["composite"]],
title="Composite Factor Signal",
labels={"composite": "Composite"},
)
fig2.update_layout(
margin={"l": 30, "r": 30, "t": 40, "b": 30},
height=400,
title_x=0.5,
)
st.plotly_chart(fig2, use_container_width=True)
else:
st.info("No composite signal found.")
else:
st.info("Compute factors to view signals.")
st.info("⚠️ Compute factors to view signals.")

# --- Footer ---
st.markdown("---")
st.caption(
"Tip: Use qrs CLI to generate data, factors, and backtest results. Then refresh this page."
"💡 Tip: Use `qrs` CLI to generate data, factors, and backtest results, then refresh this page."
)
14 changes: 9 additions & 5 deletions notebooks/01-getting-started.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"\n",
"# Show which Python the kernel is using (debugging)\n",
"import sys as _sys\n",
"\n",
"print(\"Kernel Python:\", _sys.executable)\n"
]
},
Expand All @@ -56,14 +57,17 @@
"outputs": [],
"source": [
"# Setup: imports\n",
"import os\n",
"import json\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"\n",
"from quant_research_starter.data import SampleDataLoader, SyntheticDataGenerator\n",
"from quant_research_starter.factors import MomentumFactor, ValueFactor, SizeFactor, VolatilityFactor\n",
"from quant_research_starter.backtest import VectorizedBacktest\n",
"from quant_research_starter.data import SampleDataLoader\n",
"from quant_research_starter.factors import (\n",
" MomentumFactor,\n",
" SizeFactor,\n",
" ValueFactor,\n",
" VolatilityFactor,\n",
")\n",
"from quant_research_starter.metrics import RiskMetrics\n",
"\n"
]
Expand Down
Binary file modified output/backtest_plot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading