QSSS_new / backend /app /models /backtest.py
misonL's picture
特性:实现对话框、表单、输入框、标签、下拉菜单、分隔线、骨架屏、滑块、表格、文本区域的 UI 组件
c78ce9e
Raw
History Blame Contribute Delete
9.74 kB
from sqlalchemy import Column, String, Float, Integer, DateTime, Text, Boolean, JSON, ForeignKey, Index
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
import uuid
from datetime import datetime
from typing import Optional, Dict, Any
from enum import Enum
from app.core.db_selector import Base
class BacktestStatus(str, Enum):
"""回测状态枚举"""
PENDING = "pending" # 等待中
RUNNING = "running" # 运行中
COMPLETED = "completed" # 已完成
FAILED = "failed" # 失败
CANCELLED = "cancelled" # 已取消
class BacktestType(str, Enum):
"""回测类型枚举"""
SINGLE_STRATEGY = "single_strategy" # 单策略回测
MULTI_STRATEGY = "multi_strategy" # 多策略回测
PORTFOLIO = "portfolio" # 投资组合回测
WALK_FORWARD = "walk_forward" # 滚动回测
class Backtest(Base):
"""回测任务表"""
__tablename__ = "backtests"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
name = Column(String(100), nullable=False, comment="回测名称")
description = Column(Text, comment="回测描述")
backtest_type = Column(String(20), nullable=False, comment="回测类型")
status = Column(String(20), default=BacktestStatus.PENDING, comment="回测状态")
# 策略配置
strategy_id = Column(String(36), ForeignKey('strategies.id'), comment="策略ID")
strategy_config = Column(JSON, comment="策略配置")
# 回测参数
start_date = Column(DateTime, nullable=False, comment="开始日期")
end_date = Column(DateTime, nullable=False, comment="结束日期")
initial_capital = Column(Float, default=1000000.0, comment="初始资金")
benchmark = Column(String(20), comment="基准指数")
# 交易设置
commission = Column(Float, default=0.0003, comment="手续费率")
slippage = Column(Float, default=0.001, comment="滑点")
min_commission = Column(Float, default=5.0, comment="最小手续费")
# 股票池设置
universe = Column(JSON, comment="股票池")
filters = Column(JSON, comment="筛选条件")
# 风险控制
max_position_size = Column(Float, default=0.1, comment="最大单股仓位")
max_sector_exposure = Column(Float, default=0.3, comment="最大行业敞口")
stop_loss = Column(Float, comment="止损比例")
take_profit = Column(Float, comment="止盈比例")
# 执行信息
start_time = Column(DateTime, comment="开始时间")
end_time = Column(DateTime, comment="结束时间")
execution_time = Column(Float, comment="执行时长(秒)")
error_message = Column(Text, comment="错误信息")
# 创建者信息
created_by = Column(String(36), comment="创建者ID")
# 时间戳
created_at = Column(DateTime, default=func.now(), comment="创建时间")
updated_at = Column(
DateTime,
default=func.now(),
onupdate=func.now(),
comment="更新时间")
# 关系
strategy = relationship("Strategy", backref="backtests")
# 索引
__table_args__ = (
Index('idx_backtest_strategy', 'strategy_id'),
Index('idx_backtest_status', 'status'),
Index('idx_backtest_creator', 'created_by'),
Index('idx_backtest_date_range', 'start_date', 'end_date'),
)
def __repr__(self):
return f"<Backtest(name='{self.name}', status='{self.status}', period='{self.start_date}~{self.end_date}')>"
class BacktestResult(Base):
"""回测结果表"""
__tablename__ = "backtest_results"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
backtest_id = Column(String(36), ForeignKey('backtests.id'), nullable=False)
# 基本信息
total_days = Column(Integer, comment="总交易天数")
trading_days = Column(Integer, comment="实际交易天数")
# 收益指标
total_return = Column(Float, comment="总收益率")
annual_return = Column(Float, comment="年化收益率")
benchmark_return = Column(Float, comment="基准收益率")
excess_return = Column(Float, comment="超额收益率")
# 风险指标
volatility = Column(Float, comment="年化波动率")
sharpe_ratio = Column(Float, comment="夏普比率")
sortino_ratio = Column(Float, comment="索提诺比率")
calmar_ratio = Column(Float, comment="卡玛比率")
# 回撤指标
max_drawdown = Column(Float, comment="最大回撤")
max_drawdown_duration = Column(Integer, comment="最大回撤持续天数")
recovery_time = Column(Integer, comment="回撤恢复天数")
# 交易统计
total_trades = Column(Integer, comment="总交易次数")
winning_trades = Column(Integer, comment="盈利交易次数")
losing_trades = Column(Integer, comment="亏损交易次数")
win_rate = Column(Float, comment="胜率")
# 盈亏统计
avg_win = Column(Float, comment="平均盈利")
avg_loss = Column(Float, comment="平均亏损")
profit_factor = Column(Float, comment="盈亏比")
largest_win = Column(Float, comment="最大盈利")
largest_loss = Column(Float, comment="最大亏损")
# 资金曲线
final_capital = Column(Float, comment="最终资金")
peak_capital = Column(Float, comment="资金峰值")
# 基准比较
tracking_error = Column(Float, comment="跟踪误差")
information_ratio = Column(Float, comment="信息比率")
beta = Column(Float, comment="贝塔值")
alpha = Column(Float, comment="阿尔法值")
# 详细数据
daily_returns = Column(JSON, comment="日收益率序列")
equity_curve = Column(JSON, comment="资金曲线")
drawdown_series = Column(JSON, comment="回撤序列")
# 时间戳
created_at = Column(DateTime, default=func.now(), comment="创建时间")
# 关系
backtest = relationship("Backtest", backref="results")
# 索引
__table_args__ = (
Index('idx_result_backtest', 'backtest_id'),
)
def __repr__(self):
return f"<BacktestResult(backtest_id='{self.backtest_id}', return={self.total_return}, sharpe={self.sharpe_ratio})>"
class BacktestMetrics(Base):
"""回测指标详情表"""
__tablename__ = "backtest_metrics"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
backtest_id = Column(String(36), ForeignKey('backtests.id'), nullable=False)
metric_date = Column(DateTime, nullable=False, comment="指标日期")
# 每日指标
portfolio_value = Column(Float, comment="组合价值")
cash = Column(Float, comment="现金")
positions_value = Column(Float, comment="持仓价值")
daily_return = Column(Float, comment="日收益率")
cumulative_return = Column(Float, comment="累计收益率")
# 基准对比
benchmark_value = Column(Float, comment="基准价值")
benchmark_return = Column(Float, comment="基准日收益率")
excess_return = Column(Float, comment="超额收益率")
# 风险指标
drawdown = Column(Float, comment="回撤")
volatility = Column(Float, comment="滚动波动率")
# 持仓信息
positions_count = Column(Integer, comment="持仓股票数量")
turnover = Column(Float, comment="换手率")
# 时间戳
created_at = Column(DateTime, default=func.now(), comment="创建时间")
# 关系
backtest = relationship("Backtest", backref="metrics")
# 索引
__table_args__ = (
Index('idx_metrics_backtest_date', 'backtest_id', 'metric_date'),
Index('idx_metrics_date', 'metric_date'),
)
def __repr__(self):
return f"<BacktestMetrics(backtest_id='{self.backtest_id}', date='{self.metric_date}', value={self.portfolio_value})>"
class BacktestTrade(Base):
"""回测交易记录表"""
__tablename__ = "backtest_trades"
id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
backtest_id = Column(String(36), ForeignKey('backtests.id'), nullable=False)
# 交易基本信息
symbol = Column(String(20), nullable=False, comment="股票代码")
trade_date = Column(DateTime, nullable=False, comment="交易日期")
action = Column(String(10), nullable=False, comment="交易动作") # buy, sell
# 价格和数量
price = Column(Float, nullable=False, comment="交易价格")
quantity = Column(Integer, nullable=False, comment="交易数量")
amount = Column(Float, nullable=False, comment="交易金额")
# 费用
commission = Column(Float, comment="手续费")
slippage = Column(Float, comment="滑点成本")
total_cost = Column(Float, comment="总成本")
# 信号信息
signal_type = Column(String(20), comment="信号类型")
signal_strength = Column(Float, comment="信号强度")
# 持仓信息
position_before = Column(Integer, comment="交易前持仓")
position_after = Column(Integer, comment="交易后持仓")
# 盈亏信息(针对卖出交易)
buy_price = Column(Float, comment="买入价格")
pnl = Column(Float, comment="盈亏金额")
pnl_pct = Column(Float, comment="盈亏比例")
holding_days = Column(Integer, comment="持有天数")
# 时间戳
created_at = Column(DateTime, default=func.now(), comment="创建时间")
# 关系
backtest = relationship("Backtest", backref="trades")
# 索引
__table_args__ = (
Index('idx_trade_backtest_date', 'backtest_id', 'trade_date'),
Index('idx_trade_symbol', 'symbol'),
Index('idx_trade_action', 'action'),
)
def __repr__(self):
return f"<BacktestTrade(backtest_id='{self.backtest_id}', symbol='{self.symbol}', action='{self.action}', price={self.price})>"