feat(factor): C1 因子相关性分析(横截面 Spearman 矩阵 + API)
- evaluation.factor_correlation_report:多因子共同日期 ∩ 后逐日横截面 Spearman 相关 取均值 → FactorCorrelationReport(冗余剔除前置,v3 §12 Correlation→Redundancy) - ResearchService.run_factor_correlation + POST /api/factor-correlations (universe/factors/period;与其它研究同装配口径) - tests/test_factor_correlation.py:矩阵对角=1/近线性±相关符号/对称/无共同日期补零、 API 冒烟;全量 pytest 通过
This commit is contained in:
@@ -6,13 +6,20 @@ Phase 3 为同步执行(样本有限);Phase 4 将改为 Job + SSE 异步
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from app.api.deps import ResearchServiceDep
|
||||
from app.domain.entities.research import (
|
||||
BacktestResult,
|
||||
FactorCorrelationReport,
|
||||
FactorSpec,
|
||||
FactorTestReport,
|
||||
ResearchSpec,
|
||||
SelectionSpec,
|
||||
UniverseSpec,
|
||||
)
|
||||
from app.quant.factors import FactorError
|
||||
|
||||
@@ -54,3 +61,38 @@ def last_backtest() -> BacktestResult:
|
||||
if "default" not in _LAST_BACKTEST:
|
||||
raise HTTPException(status_code=404, detail="尚无回测结果,请先 POST /api/backtests")
|
||||
return _LAST_BACKTEST["default"]
|
||||
|
||||
|
||||
class FactorCorrelationRequest(BaseModel):
|
||||
"""因子相关性分析请求(v3 §12)。"""
|
||||
|
||||
universe: UniverseSpec = UniverseSpec()
|
||||
factors: list[FactorSpec] = Field(min_length=2)
|
||||
period: tuple[date, date]
|
||||
price_adjustment: str = Field(default="none", pattern="^(none|qfq)$")
|
||||
|
||||
|
||||
@router.post(
|
||||
"/factor-correlations",
|
||||
response_model=FactorCorrelationReport,
|
||||
summary="多因子两两相关(横截面 Spearman)",
|
||||
)
|
||||
def run_factor_correlation(
|
||||
req: FactorCorrelationRequest,
|
||||
service: ResearchServiceDep,
|
||||
) -> FactorCorrelationReport:
|
||||
if req.period[0] >= req.period[1]:
|
||||
raise HTTPException(status_code=400, detail="period 必须满足 start < end")
|
||||
spec = ResearchSpec(
|
||||
type="factor_test",
|
||||
universe=req.universe,
|
||||
price_adjustment=req.price_adjustment,
|
||||
factors=req.factors,
|
||||
selection=SelectionSpec(top_n=10),
|
||||
rebalance="monthly",
|
||||
period=req.period,
|
||||
)
|
||||
try:
|
||||
return service.run_factor_correlation(spec)
|
||||
except (ValueError, FactorError) as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
Reference in New Issue
Block a user