88 lines
2.1 KiB
Python
88 lines
2.1 KiB
Python
"""Pydantic DTO —— 这就是 OpenAPI 契约(前端据此生成类型化客户端)。
|
||
|
||
契约先于业务锁定:字段一旦定下,前端可并行开发,后端实现改动不影响前端。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from datetime import datetime
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
# ---------- Candle ----------
|
||
class CandleOut(BaseModel):
|
||
ts: datetime
|
||
open: float
|
||
high: float
|
||
low: float
|
||
close: float
|
||
volume: float
|
||
|
||
model_config = {"from_attributes": True}
|
||
|
||
|
||
# ---------- Backtest ----------
|
||
class BacktestRequest(BaseModel):
|
||
symbol: str = "DEMO"
|
||
timeframe: str = "1d"
|
||
strategy: str = "macd_cross" # macd_cross | ma_cross | single_ma
|
||
params: dict[str, float] = Field(default_factory=dict) # 各策略参数
|
||
initial_cash: float = 1000000.0
|
||
fast_mode: bool = False # True => 关闭 T+1/费用,交互试探
|
||
start: datetime | None = None
|
||
end: datetime | None = None
|
||
|
||
|
||
class SignalOut(BaseModel):
|
||
ts: datetime
|
||
side: str # "buy" | "sell"
|
||
price: float
|
||
qty: float
|
||
|
||
|
||
class EquityPoint(BaseModel):
|
||
ts: datetime
|
||
value: float
|
||
|
||
|
||
class IndicatorOut(BaseModel):
|
||
strategy: str
|
||
data: dict[str, list[float | None]] = {} # 列名 -> 序列(MACD: macd/signal/hist;均线: fast/slow 或 ma)
|
||
|
||
|
||
class MetricsOut(BaseModel):
|
||
total_return: float
|
||
max_drawdown: float
|
||
sharpe: float
|
||
volatility: float
|
||
num_trades: int = 0
|
||
win_rate: float = 0.0
|
||
|
||
|
||
class BacktestResponse(BaseModel):
|
||
symbol: str
|
||
timeframe: str
|
||
strategy: str
|
||
candles: list[CandleOut]
|
||
indicators: IndicatorOut
|
||
signals: list[SignalOut]
|
||
equity: list[EquityPoint]
|
||
metrics: MetricsOut
|
||
final_cash: float
|
||
final_position: float
|
||
initial_cash: float
|
||
|
||
|
||
class SyncRequest(BaseModel):
|
||
symbol: str
|
||
start: str | None = None # YYYYMMDD
|
||
end: str | None = None
|
||
source: str = "auto" # auto | tushare | akshare
|
||
force: bool = False # True => 忽略缓存重新拉取
|
||
|
||
|
||
class SyncResponse(BaseModel):
|
||
symbol: str
|
||
bars: int
|
||
source: str
|