feat: add Quant OS A-share baseline

This commit is contained in:
2026-07-26 12:54:04 +08:00
commit 48c5f64bbd
98 changed files with 31874 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
import unittest
from quant60.factor_risk import (
FactorExposureSnapshot,
RiskModelError,
build_factor_risk_forecast,
estimate_factor_returns,
factor_stress_loss,
portfolio_factor_variance,
)
class FactorRiskTests(unittest.TestCase):
def _exposure(self):
return FactorExposureSnapshot(
as_of="2026-07-24T15:00:00+08:00",
exposures={
"600000.SH": {"market": 1.0, "style": 1.0},
"000001.SZ": {"market": 1.0, "style": 1.0},
"300750.SZ": {"market": 1.0, "style": -1.0},
},
)
def _forecast(self):
return build_factor_risk_forecast(
factor_return_history=[
{"market": 0.01, "style": 0.02},
{"market": -0.01, "style": -0.02},
{"market": 0.02, "style": 0.01},
{"market": -0.02, "style": -0.01},
],
residual_history={
"600000.SH": [0.01, -0.01, 0.005],
"000001.SZ": [0.01, -0.01, 0.005],
"300750.SZ": [0.01, -0.01, 0.005],
},
shrinkage=0.2,
)
def test_factor_return_fit_and_residuals_are_complete(self):
fit = estimate_factor_returns(
returns={
"600000.SH": 0.03,
"000001.SZ": 0.02,
"300750.SZ": -0.01,
},
exposure=self._exposure(),
)
self.assertEqual(set(fit.factor_returns), {"market", "style"})
self.assertEqual(len(fit.residuals), 3)
def test_correlated_pair_has_more_risk_than_style_diversified_pair(self):
exposure = self._exposure()
forecast = self._forecast()
correlated = portfolio_factor_variance(
portfolio_weights={
"600000.SH": 0.5,
"000001.SZ": 0.5,
},
exposure=exposure,
forecast=forecast,
)
diversified = portfolio_factor_variance(
portfolio_weights={
"600000.SH": 0.5,
"300750.SZ": 0.5,
},
exposure=exposure,
forecast=forecast,
)
self.assertGreater(correlated, diversified)
def test_missing_risk_input_fails_closed(self):
with self.assertRaisesRegex(RiskModelError, "missing"):
portfolio_factor_variance(
portfolio_weights={"000333.SZ": 1.0},
exposure=self._exposure(),
forecast=self._forecast(),
)
def test_market_down_stress_is_positive_loss(self):
loss = factor_stress_loss(
portfolio_weights={"600000.SH": 0.5, "300750.SZ": 0.5},
exposure=self._exposure(),
factor_shocks={"market": -0.10},
)
self.assertAlmostEqual(loss, 0.10)
if __name__ == "__main__":
unittest.main()