功能更新
This commit is contained in:
@@ -24,7 +24,7 @@ class CandleOut(BaseModel):
|
||||
|
||||
# ---------- Backtest ----------
|
||||
class BacktestRequest(BaseModel):
|
||||
symbol: str = "DEMO"
|
||||
symbol: str = "000001"
|
||||
timeframe: str = "1d"
|
||||
strategy: str = "macd_cross" # macd_cross | ma_cross | single_ma
|
||||
params: dict[str, float] = Field(default_factory=dict) # 各策略参数
|
||||
@@ -82,6 +82,68 @@ class SyncRequest(BaseModel):
|
||||
force: bool = False # True => 忽略缓存重新拉取
|
||||
|
||||
|
||||
# ---------- Event Backtest(自然语言事件回测) ----------
|
||||
class EventBacktestSpec(BaseModel):
|
||||
"""事件回测参数:entry 条件在信号日 D 收盘确认 -> D+1 买入 -> 持有 N 日卖出。"""
|
||||
entry: ScreenConditions
|
||||
entry_timing: Literal["next_open", "next_close"] = "next_open" # 次日开盘/收盘买入
|
||||
holding_days: int = Field(default=3, ge=1, le=250) # 买入后再持有 N 个交易日
|
||||
exit_timing: Literal["close", "open"] = "close" # 到期按收盘/开盘卖出
|
||||
|
||||
|
||||
class EventBacktestRequest(BaseModel):
|
||||
text: str = Field(min_length=2, max_length=500)
|
||||
spec: EventBacktestSpec | None = None # 直传则跳过 LLM 解析(调参重跑)
|
||||
ts_code: str | None = None # 指定则只回测该股;空则全市场
|
||||
start: datetime | None = None
|
||||
end: datetime | None = None
|
||||
|
||||
|
||||
class EventTradeOut(BaseModel):
|
||||
ts_code: str
|
||||
name: str | None = None
|
||||
entry_date: datetime
|
||||
entry_price: float
|
||||
exit_date: datetime
|
||||
exit_price: float
|
||||
ret_pct: float # 区间收益率 %(复权校正)
|
||||
|
||||
|
||||
class EventYearStatOut(BaseModel):
|
||||
year: int
|
||||
samples: int
|
||||
mean_pct: float
|
||||
median_pct: float
|
||||
win_rate: float
|
||||
|
||||
|
||||
class EventStatsOut(BaseModel):
|
||||
samples: int
|
||||
stocks: int
|
||||
mean_pct: float
|
||||
median_pct: float
|
||||
win_rate: float # %
|
||||
std_pct: float = 0.0
|
||||
p10_pct: float = 0.0
|
||||
p25_pct: float = 0.0
|
||||
p75_pct: float = 0.0
|
||||
p90_pct: float = 0.0
|
||||
max_pct: float = 0.0
|
||||
min_pct: float = 0.0
|
||||
by_year: list[EventYearStatOut] = Field(default_factory=list)
|
||||
|
||||
|
||||
class EventBacktestResponse(BaseModel):
|
||||
text: str
|
||||
spec: EventBacktestSpec
|
||||
universe: str # "all" 或 ts_code
|
||||
start: datetime
|
||||
end: datetime
|
||||
stats: EventStatsOut
|
||||
trades: list[EventTradeOut] = Field(default_factory=list) # 最好+最差样本(各 100)
|
||||
total: int
|
||||
|
||||
|
||||
class SyncResponse(BaseModel):
|
||||
symbol: str
|
||||
bars: int
|
||||
@@ -197,7 +259,7 @@ class PreviewInfoOut(BaseModel):
|
||||
class PreviewResponse(BaseModel):
|
||||
ts_code: str
|
||||
symbol: str
|
||||
source: str # qfq=回测缓存全量前复权 | market=近段未复权兜底
|
||||
source: str # bfq|qfq|hfq=实际复权口径(本地 adj_factor 换算) | market=近段未复权兜底
|
||||
info: PreviewInfoOut
|
||||
candles: list[CandleOut]
|
||||
indicators: dict[str, dict[str, list[float | None]]] = Field(default_factory=dict)
|
||||
@@ -220,3 +282,61 @@ class CurrentUserOut(BaseModel):
|
||||
class LoginResponse(BaseModel):
|
||||
user: CurrentUserOut
|
||||
expires_at: datetime
|
||||
|
||||
|
||||
# ---------- 股票列表(全市场浏览) ----------
|
||||
class StockListItemOut(BaseModel):
|
||||
ts_code: str
|
||||
symbol: str
|
||||
name: str
|
||||
industry: str | None = None
|
||||
market: str | None = None
|
||||
close: float | None = None # 最新收盘(candles 未复权)
|
||||
prev_close: float | None = None
|
||||
pct_chg: float | None = None # 最新两根日线计算
|
||||
last_ts: datetime | None = None
|
||||
bar_count: int | None = None # 本地缓存日线条数
|
||||
watched: bool = False # 是否自选(当前用户)
|
||||
|
||||
|
||||
class StockListResponse(BaseModel):
|
||||
total: int
|
||||
items: list[StockListItemOut]
|
||||
|
||||
|
||||
# ---------- 看股页筛选项 ----------
|
||||
class FacetItemOut(BaseModel):
|
||||
name: str
|
||||
count: int
|
||||
|
||||
|
||||
class StockFacetsResponse(BaseModel):
|
||||
industries: list[FacetItemOut] = Field(default_factory=list)
|
||||
areas: list[FacetItemOut] = Field(default_factory=list)
|
||||
|
||||
|
||||
# ---------- 用户偏好 / 自选股 / 提问历史 ----------
|
||||
class PreferencesOut(BaseModel):
|
||||
prefs: dict[str, object] = Field(default_factory=dict) # key -> JSON 值
|
||||
|
||||
|
||||
class PreferencesUpdate(BaseModel):
|
||||
prefs: dict[str, object] # 部分更新:只覆盖出现的 key(值为 null 表示删除)
|
||||
|
||||
|
||||
class WatchlistOp(BaseModel):
|
||||
ts_code: str = Field(min_length=6, max_length=12)
|
||||
|
||||
|
||||
class ScreenerQueryOut(BaseModel):
|
||||
id: int
|
||||
text: str
|
||||
conditions: ScreenConditions | None = None
|
||||
hit_count: int | None = None
|
||||
created_at: datetime
|
||||
|
||||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class ScreenerQueryListResponse(BaseModel):
|
||||
items: list[ScreenerQueryOut]
|
||||
|
||||
Reference in New Issue
Block a user