feat: add scoped alpha sync and local self-correlation
This commit is contained in:
+32
-4
@@ -1,13 +1,14 @@
|
||||
"""Validated public API contracts. Platform state is intentionally not a closed enum."""
|
||||
|
||||
import re
|
||||
from datetime import datetime, timezone
|
||||
from datetime import date, datetime, timezone
|
||||
from typing import Literal
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
||||
|
||||
ResearchState = Literal["inbox", "candidate", "optimizing", "archived"]
|
||||
Submission = Literal["UNSUBMITTED", "SUBMITTED"]
|
||||
SortField = Literal[
|
||||
"id",
|
||||
"name",
|
||||
@@ -62,6 +63,7 @@ class PreferencesInput(Contract):
|
||||
|
||||
|
||||
class AlphaFilters(Contract):
|
||||
submission: Submission | None = None
|
||||
q: str | None = Field(default=None, max_length=300)
|
||||
region: str | None = None
|
||||
universe: str | None = None
|
||||
@@ -160,16 +162,34 @@ class BulkUpdate(BulkInput):
|
||||
|
||||
|
||||
class JobInput(Contract):
|
||||
kind: Literal["full_sync", "alpha_refresh", "pnl_refresh"]
|
||||
kind: Literal["full_sync", "daily_sync", "alpha_refresh", "pnl_refresh", "self_correlation"]
|
||||
alpha_ids: list[str] = Field(default_factory=list)
|
||||
submission: Submission | None = None
|
||||
date_from: date | None = None
|
||||
date_to: date | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_ids(self):
|
||||
if self.kind == "full_sync":
|
||||
if self.kind in ("full_sync", "daily_sync"):
|
||||
if self.alpha_ids:
|
||||
raise ValueError("全量同步不接受 Alpha ID")
|
||||
raise ValueError("列表同步不接受 Alpha ID")
|
||||
if self.kind == "full_sync":
|
||||
if self.submission == "UNSUBMITTED":
|
||||
raise ValueError("待提交 Alpha 必须选择日期逐天同步")
|
||||
self.submission = "SUBMITTED"
|
||||
if self.date_from is not None or self.date_to is not None:
|
||||
raise ValueError("全量同步不接受日期范围")
|
||||
else:
|
||||
if not self.submission or not self.date_from or not self.date_to:
|
||||
raise ValueError("按天同步必须选择待提交/已提交和起止日期")
|
||||
if self.date_from > self.date_to:
|
||||
raise ValueError("开始日期不能晚于结束日期")
|
||||
if self.date_to > datetime.now(timezone.utc).date():
|
||||
raise ValueError("同步日期不能晚于今天(UTC)")
|
||||
else:
|
||||
self.alpha_ids = valid_ids(self.alpha_ids)
|
||||
if self.submission is not None or self.date_from is not None or self.date_to is not None:
|
||||
raise ValueError("按 ID 操作不接受分组或日期范围")
|
||||
return self
|
||||
|
||||
|
||||
@@ -199,6 +219,7 @@ class AlphaSummary(BaseModel):
|
||||
date_submitted: datetime | None
|
||||
synced_at: datetime
|
||||
research: ResearchOutput
|
||||
local_correlation: dict | None = None
|
||||
|
||||
|
||||
class AlphaDetail(AlphaSummary):
|
||||
@@ -230,6 +251,8 @@ class JobOutput(BaseModel):
|
||||
next_retry_at: datetime | None
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
payload: dict = Field(default_factory=dict)
|
||||
checkpoint: dict = Field(default_factory=dict)
|
||||
|
||||
|
||||
class PlatformSessionOutput(BaseModel):
|
||||
@@ -286,6 +309,11 @@ class PnlOutput(BaseModel):
|
||||
fetched_at: datetime | None
|
||||
|
||||
|
||||
class SelfCorrelationOutput(BaseModel):
|
||||
cached: bool
|
||||
result: dict | None
|
||||
|
||||
|
||||
class FacetsOutput(BaseModel):
|
||||
region: list[str]
|
||||
universe: list[str]
|
||||
|
||||
Reference in New Issue
Block a user