Handle square factor regressions without inference

This commit is contained in:
2026-04-07 16:53:16 +08:00
parent 0876c0b6af
commit 3d934b3316
2 changed files with 54 additions and 21 deletions

View File

@@ -462,19 +462,45 @@ class RegressionTests(unittest.TestCase):
self.assertEqual(result["n_obs"], 296)
def test_run_factor_regression_rejects_underdetermined_designs(self):
dates = pd.date_range("2024-01-01", periods=3, freq="B")
dates = pd.date_range("2024-01-01", periods=2, freq="B")
factors = pd.DataFrame(
{
"MKT_RF": [0.01, -0.02, 0.015],
"SMB": [0.005, 0.004, -0.001],
"MKT_RF": [0.01, -0.02],
"SMB": [0.005, 0.004],
},
index=dates,
)
strategy = pd.Series([0.012, -0.018, 0.019], index=dates)
strategy = pd.Series([0.012, -0.018], index=dates)
with self.assertRaisesRegex(ValueError, "Insufficient observations"):
run_factor_regression(strategy, factors, factor_cols=["MKT_RF", "SMB"])
def test_run_factor_regression_allows_square_full_rank_design_without_inference(self):
dates = pd.date_range("2024-01-01", periods=3, freq="B")
factors = pd.DataFrame(
{
"MKT_RF": [0.0, 1.0, 0.0],
"SMB": [0.0, 0.0, 1.0],
},
index=dates,
)
strategy = pd.Series([0.0005, 1.2005, -0.3995], index=dates)
result = run_factor_regression(strategy, factors, factor_cols=["MKT_RF", "SMB"])
self.assertAlmostEqual(result["alpha_daily"], 0.0005, places=10)
self.assertAlmostEqual(result["betas"]["MKT_RF"], 1.2, places=10)
self.assertAlmostEqual(result["betas"]["SMB"], -0.4, places=10)
self.assertEqual(result["r_squared"], 1.0)
self.assertTrue(np.isnan(result["alpha_t_stat"]))
self.assertTrue(np.isnan(result["alpha_p_value"]))
self.assertTrue(np.isnan(result["t_stats"]["MKT_RF"]))
self.assertTrue(np.isnan(result["t_stats"]["SMB"]))
self.assertTrue(np.isnan(result["p_values"]["MKT_RF"]))
self.assertTrue(np.isnan(result["p_values"]["SMB"]))
self.assertTrue(np.isnan(result["adj_r_squared"]))
self.assertTrue(np.isnan(result["residual_vol_ann"]))
def test_run_factor_regression_rejects_rank_deficient_designs(self):
dates = pd.date_range("2024-01-01", periods=6, freq="B")
market = np.array([0.01, -0.02, 0.015, 0.005, -0.01, 0.02])