first commit
This commit is contained in:
57
backend/app/models.py
Normal file
57
backend/app/models.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""ORM 模型。
|
||||
|
||||
Candle 表设计与 TimescaleDB hypertable 完全兼容:将来在目标 PG 库执行
|
||||
SELECT create_hypertable('candles', 'ts');
|
||||
即可升级为时序表 + Continuous Aggregates 多周期预聚合,无需改表结构。
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import DateTime, Float, Integer, String, UniqueConstraint
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from .db import Base
|
||||
|
||||
|
||||
def _utcnow() -> datetime:
|
||||
# naive UTC,避免 SQLite 存储时区带来的麻烦
|
||||
from datetime import timezone
|
||||
return datetime.now(timezone.utc).replace(tzinfo=None)
|
||||
|
||||
|
||||
class Candle(Base):
|
||||
__tablename__ = "candles"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
symbol: Mapped[str] = mapped_column(String(16), index=True)
|
||||
timeframe: Mapped[str] = mapped_column(String(4), default="1d", index=True)
|
||||
ts: Mapped[datetime] = mapped_column(DateTime, index=True) # bar 开始时间
|
||||
open: Mapped[float] = mapped_column(Float)
|
||||
high: Mapped[float] = mapped_column(Float)
|
||||
low: Mapped[float] = mapped_column(Float)
|
||||
close: Mapped[float] = mapped_column(Float)
|
||||
volume: Mapped[float] = mapped_column(Float)
|
||||
|
||||
__table_args__ = (
|
||||
UniqueConstraint("symbol", "timeframe", "ts", name="uq_candle_sym_tf_ts"),
|
||||
)
|
||||
|
||||
|
||||
class BacktestRun(Base):
|
||||
"""回测运行注册表(可复现/可审计/可回归对比的基础)。
|
||||
|
||||
完整版应记录 策略版本 + 参数快照 + 数据快照(复权/数据源/库版本)+ 环境指纹 + 结果指纹。
|
||||
MVP 先落关键字段,结构就位。
|
||||
"""
|
||||
__tablename__ = "backtest_runs"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=_utcnow)
|
||||
symbol: Mapped[str] = mapped_column(String(16))
|
||||
strategy: Mapped[str] = mapped_column(String(64))
|
||||
timeframe: Mapped[str] = mapped_column(String(4), default="1d")
|
||||
params_json: Mapped[str] = mapped_column(String, default="{}")
|
||||
initial_cash: Mapped[float] = mapped_column(Float, default=100000.0)
|
||||
total_return: Mapped[float] = mapped_column(Float, default=0.0)
|
||||
max_drawdown: Mapped[float] = mapped_column(Float, default=0.0)
|
||||
sharpe: Mapped[float] = mapped_column(Float, default=0.0)
|
||||
num_trades: Mapped[int] = mapped_column(Integer, default=0)
|
||||
Reference in New Issue
Block a user