diff --git a/examples/csv_validation_example.py b/examples/csv_validation_example.py index 81f5520..2197dea 100644 --- a/examples/csv_validation_example.py +++ b/examples/csv_validation_example.py @@ -6,6 +6,7 @@ """ import pandas as pd + from quant_research_starter.data import validate_input_csv, validate_price_csv @@ -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: @@ -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}") @@ -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) @@ -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'])}") diff --git a/legacy/streamlit/streamlit_app.py b/legacy/streamlit/streamlit_app.py index 663d741..179abf0 100644 --- a/legacy/streamlit/streamlit_app.py +++ b/legacy/streamlit/streamlit_app.py @@ -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." ) diff --git a/notebooks/01-getting-started.ipynb b/notebooks/01-getting-started.ipynb index a8a300d..e4c4837 100644 --- a/notebooks/01-getting-started.ipynb +++ b/notebooks/01-getting-started.ipynb @@ -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" ] }, @@ -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" ] diff --git a/output/backtest_plot.png b/output/backtest_plot.png index 5e3189d..6eeaac2 100644 Binary files a/output/backtest_plot.png and b/output/backtest_plot.png differ diff --git a/output/backtest_results.json b/output/backtest_results.json index 84bf2cc..97ea189 100644 --- a/output/backtest_results.json +++ b/output/backtest_results.json @@ -1,519 +1,119 @@ { "metrics": { - "total_return": -1.0, - "cagr": 0, - "annualized_return": 0, - "volatility": 0, - "downside_volatility": 0, - "max_drawdown": 0.0, + "total_return": -0.056813586365103474, + "cagr": -0.19587422923064846, + "annualized_return": -0.19587422923064846, + "volatility": 0.2011139478190924, + "downside_volatility": 0.12173434517323907, + "max_drawdown": -0.1445684398076149, "drawdown_duration": 0, - "var_95": -1.0, - "cvar_95": -1.0, - "sharpe_ratio": 0, - "sortino_ratio": 0, - "calmar_ratio": 0 + "var_95": -0.019231010104213443, + "cvar_95": -0.025532708667872116, + "sharpe_ratio": -0.9739465181541899, + "sortino_ratio": -1.6090301299267808, + "calmar_ratio": -1.3548892793704417 }, "portfolio_value": [ 1000000.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0, - 0.0 + 999500.0, + 1020983.3814288847, + 1040855.2597947245, + 1031617.9616556381, + 1038169.7347261552, + 1037143.6803305667, + 1062654.988147677, + 1059209.2073003408, + 1071635.9459017066, + 1064083.0110879496, + 1051572.1244648902, + 1064232.6931356927, + 1043836.2224950673, + 1033210.4529692985, + 1029965.7664728428, + 1030642.1909003343, + 1030797.5879213361, + 1029213.0609950781, + 1045008.4968192923, + 1069840.5254072316, + 1052145.4722552695, + 1064470.9606289316, + 1055593.089863988, + 1049313.089097812, + 1029624.3656346899, + 1052513.1696791975, + 1038308.377058927, + 1031453.8035199654, + 1028318.7460267562, + 1022773.3209369407, + 1022702.5188011427, + 1026223.1427891029, + 1013819.3824762587, + 1025729.4583680343, + 1000859.5520236057, + 999062.8882925692, + 997079.2130641966, + 1001744.5823969941, + 1004311.1403878148, + 993169.4664918573, + 982970.4035495098, + 965075.483046621, + 961947.7340228327, + 950202.0747398927, + 940855.6530797088, + 942632.8300845332, + 943728.5626104218, + 951468.244273647, + 949822.8390477881, + 953402.0297732105, + 949716.6760799532, + 975228.5517105173, + 987137.4977917145, + 976291.7073484402, + 972182.8946801375, + 959757.4366244123, + 981422.2908684975, + 982397.8187979326, + 978504.7792785383, + 985273.6795080735, + 977007.5062546888, + 962501.1052683766, + 958271.8463475088, + 950547.8257397416, + 950813.5234779255, + 953864.7324460202, + 960016.9551473227, + 970746.464657049, + 982829.2794015955, + 969195.0065390804, + 982689.3608480592, + 964319.0462584958, + 969460.5961478064, + 949538.9093886046, + 946199.0324565931, + 969372.905074215, + 957198.2343847842, + 956413.2803963589, + 961301.1907152241, + 983283.473231165, + 978577.0330178489, + 973050.533479754, + 967641.3566248857, + 928652.3459703667, + 916711.2091609393, + 931225.7581704466, + 933700.7215615523, + 940032.4160829495, + 938817.4250849152, + 937018.2766361, + 955429.0306893053, + 933689.0951276519, + 934547.5682997877, + 940924.6149227251, + 922274.2786700858, + 934008.1707704184, + 945388.2073425553, + 935925.9707410528, + 943186.4136348969 ], "dates": [ "2020-01-01", @@ -615,406 +215,6 @@ "2020-04-06", "2020-04-07", "2020-04-08", - "2020-04-09", - "2020-04-10", - "2020-04-11", - "2020-04-12", - "2020-04-13", - "2020-04-14", - "2020-04-15", - "2020-04-16", - "2020-04-17", - "2020-04-18", - "2020-04-19", - "2020-04-20", - "2020-04-21", - "2020-04-22", - "2020-04-23", - "2020-04-24", - "2020-04-25", - "2020-04-26", - "2020-04-27", - "2020-04-28", - "2020-04-29", - "2020-04-30", - "2020-05-01", - "2020-05-02", - "2020-05-03", - "2020-05-04", - "2020-05-05", - "2020-05-06", - "2020-05-07", - "2020-05-08", - "2020-05-09", - "2020-05-10", - "2020-05-11", - "2020-05-12", - "2020-05-13", - "2020-05-14", - "2020-05-15", - "2020-05-16", - "2020-05-17", - "2020-05-18", - "2020-05-19", - "2020-05-20", - "2020-05-21", - "2020-05-22", - "2020-05-23", - "2020-05-24", - "2020-05-25", - "2020-05-26", - "2020-05-27", - "2020-05-28", - "2020-05-29", - "2020-05-30", - "2020-05-31", - "2020-06-01", - "2020-06-02", - "2020-06-03", - "2020-06-04", - "2020-06-05", - "2020-06-06", - "2020-06-07", - "2020-06-08", - "2020-06-09", - "2020-06-10", - "2020-06-11", - "2020-06-12", - "2020-06-13", - "2020-06-14", - "2020-06-15", - "2020-06-16", - "2020-06-17", - "2020-06-18", - "2020-06-19", - "2020-06-20", - "2020-06-21", - "2020-06-22", - "2020-06-23", - "2020-06-24", - "2020-06-25", - "2020-06-26", - "2020-06-27", - "2020-06-28", - "2020-06-29", - "2020-06-30", - "2020-07-01", - "2020-07-02", - "2020-07-03", - "2020-07-04", - "2020-07-05", - "2020-07-06", - "2020-07-07", - "2020-07-08", - "2020-07-09", - "2020-07-10", - "2020-07-11", - "2020-07-12", - "2020-07-13", - "2020-07-14", - "2020-07-15", - "2020-07-16", - "2020-07-17", - "2020-07-18", - "2020-07-19", - "2020-07-20", - "2020-07-21", - "2020-07-22", - "2020-07-23", - "2020-07-24", - "2020-07-25", - "2020-07-26", - "2020-07-27", - "2020-07-28", - "2020-07-29", - "2020-07-30", - "2020-07-31", - "2020-08-01", - "2020-08-02", - "2020-08-03", - "2020-08-04", - "2020-08-05", - "2020-08-06", - "2020-08-07", - "2020-08-08", - "2020-08-09", - "2020-08-10", - "2020-08-11", - "2020-08-12", - "2020-08-13", - "2020-08-14", - "2020-08-15", - "2020-08-16", - "2020-08-17", - "2020-08-18", - "2020-08-19", - "2020-08-20", - "2020-08-21", - "2020-08-22", - "2020-08-23", - "2020-08-24", - "2020-08-25", - "2020-08-26", - "2020-08-27", - "2020-08-28", - "2020-08-29", - "2020-08-30", - "2020-08-31", - "2020-09-01", - "2020-09-02", - "2020-09-03", - "2020-09-04", - "2020-09-05", - "2020-09-06", - "2020-09-07", - "2020-09-08", - "2020-09-09", - "2020-09-10", - "2020-09-11", - "2020-09-12", - "2020-09-13", - "2020-09-14", - "2020-09-15", - "2020-09-16", - "2020-09-17", - "2020-09-18", - "2020-09-19", - "2020-09-20", - "2020-09-21", - "2020-09-22", - "2020-09-23", - "2020-09-24", - "2020-09-25", - "2020-09-26", - "2020-09-27", - "2020-09-28", - "2020-09-29", - "2020-09-30", - "2020-10-01", - "2020-10-02", - "2020-10-03", - "2020-10-04", - "2020-10-05", - "2020-10-06", - "2020-10-07", - "2020-10-08", - "2020-10-09", - "2020-10-10", - "2020-10-11", - "2020-10-12", - "2020-10-13", - "2020-10-14", - "2020-10-15", - "2020-10-16", - "2020-10-17", - "2020-10-18", - "2020-10-19", - "2020-10-20", - "2020-10-21", - "2020-10-22", - "2020-10-23", - "2020-10-24", - "2020-10-25", - "2020-10-26", - "2020-10-27", - "2020-10-28", - "2020-10-29", - "2020-10-30", - "2020-10-31", - "2020-11-01", - "2020-11-02", - "2020-11-03", - "2020-11-04", - "2020-11-05", - "2020-11-06", - "2020-11-07", - "2020-11-08", - "2020-11-09", - "2020-11-10", - "2020-11-11", - "2020-11-12", - "2020-11-13", - "2020-11-14", - "2020-11-15", - "2020-11-16", - "2020-11-17", - "2020-11-18", - "2020-11-19", - "2020-11-20", - "2020-11-21", - "2020-11-22", - "2020-11-23", - "2020-11-24", - "2020-11-25", - "2020-11-26", - "2020-11-27", - "2020-11-28", - "2020-11-29", - "2020-11-30", - "2020-12-01", - "2020-12-02", - "2020-12-03", - "2020-12-04", - "2020-12-05", - "2020-12-06", - "2020-12-07", - "2020-12-08", - "2020-12-09", - "2020-12-10", - "2020-12-11", - "2020-12-12", - "2020-12-13", - "2020-12-14", - "2020-12-15", - "2020-12-16", - "2020-12-17", - "2020-12-18", - "2020-12-19", - "2020-12-20", - "2020-12-21", - "2020-12-22", - "2020-12-23", - "2020-12-24", - "2020-12-25", - "2020-12-26", - "2020-12-27", - "2020-12-28", - "2020-12-29", - "2020-12-30", - "2020-12-31", - "2021-01-01", - "2021-01-02", - "2021-01-03", - "2021-01-04", - "2021-01-05", - "2021-01-06", - "2021-01-07", - "2021-01-08", - "2021-01-09", - "2021-01-10", - "2021-01-11", - "2021-01-12", - "2021-01-13", - "2021-01-14", - "2021-01-15", - "2021-01-16", - "2021-01-17", - "2021-01-18", - "2021-01-19", - "2021-01-20", - "2021-01-21", - "2021-01-22", - "2021-01-23", - "2021-01-24", - "2021-01-25", - "2021-01-26", - "2021-01-27", - "2021-01-28", - "2021-01-29", - "2021-01-30", - "2021-01-31", - "2021-02-01", - "2021-02-02", - "2021-02-03", - "2021-02-04", - "2021-02-05", - "2021-02-06", - "2021-02-07", - "2021-02-08", - "2021-02-09", - "2021-02-10", - "2021-02-11", - "2021-02-12", - "2021-02-13", - "2021-02-14", - "2021-02-15", - "2021-02-16", - "2021-02-17", - "2021-02-18", - "2021-02-19", - "2021-02-20", - "2021-02-21", - "2021-02-22", - "2021-02-23", - "2021-02-24", - "2021-02-25", - "2021-02-26", - "2021-02-27", - "2021-02-28", - "2021-03-01", - "2021-03-02", - "2021-03-03", - "2021-03-04", - "2021-03-05", - "2021-03-06", - "2021-03-07", - "2021-03-08", - "2021-03-09", - "2021-03-10", - "2021-03-11", - "2021-03-12", - "2021-03-13", - "2021-03-14", - "2021-03-15", - "2021-03-16", - "2021-03-17", - "2021-03-18", - "2021-03-19", - "2021-03-20", - "2021-03-21", - "2021-03-22", - "2021-03-23", - "2021-03-24", - "2021-03-25", - "2021-03-26", - "2021-03-27", - "2021-03-28", - "2021-03-29", - "2021-03-30", - "2021-03-31", - "2021-04-01", - "2021-04-02", - "2021-04-03", - "2021-04-04", - "2021-04-05", - "2021-04-06", - "2021-04-07", - "2021-04-08", - "2021-04-09", - "2021-04-10", - "2021-04-11", - "2021-04-12", - "2021-04-13", - "2021-04-14", - "2021-04-15", - "2021-04-16", - "2021-04-17", - "2021-04-18", - "2021-04-19", - "2021-04-20", - "2021-04-21", - "2021-04-22", - "2021-04-23", - "2021-04-24", - "2021-04-25", - "2021-04-26", - "2021-04-27", - "2021-04-28", - "2021-04-29", - "2021-04-30", - "2021-05-01", - "2021-05-02", - "2021-05-03", - "2021-05-04", - "2021-05-05", - "2021-05-06", - "2021-05-07", - "2021-05-08", - "2021-05-09", - "2021-05-10", - "2021-05-11", - "2021-05-12", - "2021-05-13", - "2021-05-14" + "2020-04-09" ] } \ No newline at end of file diff --git a/src/quant_research_starter.egg-info/SOURCES.txt b/src/quant_research_starter.egg-info/SOURCES.txt index fd7f853..16db10b 100644 --- a/src/quant_research_starter.egg-info/SOURCES.txt +++ b/src/quant_research_starter.egg-info/SOURCES.txt @@ -10,7 +10,6 @@ src/quant_research_starter.egg-info/dependency_links.txt src/quant_research_starter.egg-info/entry_points.txt src/quant_research_starter.egg-info/requires.txt src/quant_research_starter.egg-info/top_level.txt -src/quant_research_starter/backtest/__init__.py src/quant_research_starter/backtest/vectorized.py src/quant_research_starter/dashboard/streamlit_app.py src/quant_research_starter/data/__init__.py @@ -37,4 +36,5 @@ tests/test_data.py tests/test_factors.py tests/test_metrics.py tests/test_plotting.py +tests/test_plotting.py tests/test_validator.py \ No newline at end of file diff --git a/test_cli.py b/test_cli.py index 8606676..8681486 100644 --- a/test_cli.py +++ b/test_cli.py @@ -15,13 +15,13 @@ def run_command(cmd): print(f"Running: {cmd}") print('='*60) result = subprocess.run(cmd, shell=True, capture_output=True, text=True) - + if result.stdout: print(result.stdout) if result.stderr and result.returncode != 0: print(f"ERROR: {result.stderr}") return False - + return result.returncode == 0 @@ -29,21 +29,21 @@ def main(): """Run all CLI tests""" print("\n🧪 Testing QuantResearch CLI") print("="*60) - + # Define test directories test_data_dir = Path("test_data") test_output_dir = Path("test_output") - + # Create test directories test_data_dir.mkdir(exist_ok=True) test_output_dir.mkdir(exist_ok=True) - + # Test 1: Show help success = run_command("python -m quant_research_starter.cli --help") if not success: print("\n❌ Test 1 FAILED: Help command") sys.exit(1) - + # Test 2: Generate data success = run_command( "python -m quant_research_starter.cli generate-data " @@ -52,7 +52,7 @@ def main(): if not success: print("\n❌ Test 2 FAILED: Generate data") sys.exit(1) - + # Test 3: Compute factors success = run_command( "python -m quant_research_starter.cli compute-factors " @@ -61,7 +61,7 @@ def main(): if not success: print("\n❌ Test 3 FAILED: Compute factors") sys.exit(1) - + # Test 4: Run backtest success = run_command( "python -m quant_research_starter.cli backtest " @@ -71,7 +71,7 @@ def main(): if not success: print("\n❌ Test 4 FAILED: Run backtest") sys.exit(1) - + # Verify output files exist print("\n📁 Checking output files...") files_to_check = [ @@ -80,7 +80,7 @@ def main(): test_output_dir / "backtest_results.json", test_output_dir / "backtest_plot.png" ] - + all_exist = True for file_path in files_to_check: if file_path.exists(): @@ -88,16 +88,16 @@ def main(): else: print(f"❌ {file_path} missing!") all_exist = False - + if not all_exist: print("\n❌ Some output files are missing") sys.exit(1) - + # Summary print("\n" + "="*60) print("✅ ALL TESTS PASSED!") print("="*60) - print(f"\n📂 Test files created in:") + print("\n📂 Test files created in:") print(f" - {test_data_dir}/") print(f" - {test_output_dir}/") print("\n💡 You can view the results and plots in the test_output directory.")