feat: Implement Alpha list and metrics enhancements
Deploy production / deploy (push) Successful in 1m12s

- Added new metrics fields: sub_universe_sharpe, robust_universe_sharpe, two_year_sharpe, prod_correlation, pnl, check_type, and neutralization to the Alpha model.
- Updated snapshot_columns function to derive new metrics and check types from platform snapshots.
- Enhanced API to include failed checks and check types in responses.
- Created migration script to backfill existing Alpha records with new metrics and check types.
- Updated frontend components to display new metrics and allow editing of custom tags.
- Improved filtering and sorting capabilities for new metrics in the Alpha list.
- Added tests for new functionality including checks classification and metrics filtering.
This commit is contained in:
yuxuanhui
2026-09-09 19:02:37 +08:00
parent e57b1f7a2e
commit ba0ed9d03f
13 changed files with 678 additions and 22 deletions
+30 -1
View File
@@ -9,6 +9,7 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_valida
ResearchState = Literal["inbox", "candidate", "optimizing", "archived"]
Submission = Literal["UNSUBMITTED", "SUBMITTED"]
CheckType = Literal["PENDING", "PRE_CHECK", "PASS", "FAIL_1", "FAIL_2"]
SortField = Literal[
"id",
"name",
@@ -18,6 +19,11 @@ SortField = Literal[
"turnover",
"margin",
"drawdown",
"sub_universe_sharpe",
"robust_universe_sharpe",
"two_year_sharpe",
"prod_correlation",
"pnl",
"date_created",
"date_submitted",
"synced_at",
@@ -76,6 +82,8 @@ class AlphaFilters(Contract):
status: str | None = None
stage: str | None = None
hidden: bool | None = None
check_type: CheckType | None = None
neutralization: str | None = None
research_state: ResearchState | None = None
favorite: bool | None = None
tag: str | None = Field(default=None, max_length=60)
@@ -93,6 +101,16 @@ class AlphaFilters(Contract):
margin_max: float | None = None
drawdown_min: float | None = None
drawdown_max: float | None = None
sub_universe_sharpe_min: float | None = None
sub_universe_sharpe_max: float | None = None
robust_universe_sharpe_min: float | None = None
robust_universe_sharpe_max: float | None = None
two_year_sharpe_min: float | None = None
two_year_sharpe_max: float | None = None
prod_correlation_min: float | None = None
prod_correlation_max: float | None = None
pnl_min: float | None = None
pnl_max: float | None = None
sort: SortField = "date_created"
direction: Literal["asc", "desc"] = "desc"
limit: int = Field(default=25, ge=1, le=100)
@@ -105,7 +123,10 @@ class AlphaFilters(Contract):
@model_validator(mode="after")
def range_order(self):
for key in ("sharpe", "fitness", "returns", "turnover", "margin", "drawdown"):
for key in (
"sharpe", "fitness", "returns", "turnover", "margin", "drawdown",
"sub_universe_sharpe", "robust_universe_sharpe", "two_year_sharpe", "prod_correlation", "pnl",
):
lo, hi = getattr(self, f"{key}_min"), getattr(self, f"{key}_max")
if lo is not None and hi is not None and lo > hi:
raise ValueError(f"{key} 最小值不能大于最大值")
@@ -222,6 +243,14 @@ class AlphaSummary(BaseModel):
date_created: datetime | None
date_submitted: datetime | None
synced_at: datetime
check_type: CheckType = "PENDING"
failed_checks: list[str] = Field(default_factory=list)
neutralization: str | None = None
sub_universe_sharpe: float | None = None
robust_universe_sharpe: float | None = None
two_year_sharpe: float | None = None
prod_correlation: float | None = None
pnl: float | None = None
research: ResearchOutput
local_correlation: dict | None = None
source_kinds: list[str] = Field(default_factory=list)