# 跟单回测功能产品需求文档 (PRD) ## 一、功能概述 跟单回测功能允许用户对历史数据进行模拟跟单交易,评估不同跟单策略的收益表现,帮助用户在实际投入资金前验证策略的有效性。 ## 二、用户故事 ### 主要用户场景 1. **作为用户**,我希望能够创建回测任务,选择特定的 Leader 和跟单配置,以便评估在过去一段时间内使用该策略的收益情况 2. **作为用户**,我希望能够查看所有历史回测结果,并按收益额或收益率排序,以便找到最优策略 3. **作为用户**,我希望能够按 Leader 筛选回测记录,以便比较不同 Leader 的表现 4. **作为用户**,我希望回测结果能够展示详细的交易记录和收益变化,以便深入分析策略表现 5. **作为用户**,我希望回测在资金不足时能够自动停止,模拟真实交易场景 ## 三、功能需求 ### 3.1 回测管理页面 #### 3.1.1 页面布局 - **页面位置**: 在跟单管理模块下新增"回测管理"菜单项 - **页面标题**: "回测管理" / "Backtest Management" #### 3.1.2 列表功能 **筛选功能**: - Leader 筛选下拉框,支持按 Leader 过滤回测记录 - 状态筛选: 全部 / 运行中 / 已完成 / 已停止 **排序功能**: - 按收益额排序 (升序/降序) - 按收益率排序 (升序/降序) - 按创建时间排序 (默认降序) **列表字段**: | 字段名 | 说明 | 示例 | |-------|------|------| | 回测ID | 唯一标识 | #12345 | | 配置名称 | 回测任务名称 | "激进策略-Leader A" | | Leader名称 | 跟单的Leader | "Smart Trader" | | 初始金额 | 回测起始资金 | $1000 | | 最终金额 | 回测结束时资金 | $1250 | | 收益额 | 最终金额 - 初始金额 | +$250 | | 收益率 | (收益额/初始金额) × 100% | +25% | | 回测天数 | 回测的时间跨度 | 30天 | | 交易笔数 | 回测期间执行的交易数量 | 45笔 | | 状态 | 运行中/已完成/已停止 | 已完成 | | 开始时间 | 回测开始时间 | 2026-01-01 10:00 | | 结束时间 | 回测结束时间 | 2026-01-31 15:30 | | 操作 | 查看详情/删除 | - | #### 3.1.3 列表操作 - **查看详情**: 点击后展开详细信息,包括: - 回测配置参数 - 详细交易记录 - 资金变化曲线图 - 收益统计 - **删除**: 删除回测记录(确认后不可恢复) ### 3.2 新增回测任务 #### 3.2.1 创建入口 - 列表页面右上角"新增回测"按钮 - 点击后弹出创建对话框或跳转到创建页面 #### 3.2.2 配置表单 **基本配置**: - **回测名称** (必填): 用户自定义名称,方便识别 - **选择Leader** (必填): 下拉框选择已添加的Leader - **初始投入金额** (必填): 模拟起始资金,单位USDC,范围: 1 - 1,000,000 - **回测天数** (必填): 选择回测的历史天数,范围: 1 - 30天 **跟单配置** (参照现有跟单配置参数): | 配置项 | 字段名 | 说明 | 默认值 | |-------|-------|------|-------| | 跟单模式 | copyMode | RATIO(比例模式) / FIXED(固定金额) | RATIO | | 跟单比例 | copyRatio | 比例模式下生效,相对Leader订单金额的比例 | 1.0 | | 固定金额 | fixedAmount | 固定金额模式下生效,每笔固定投入金额 | null | | 最大单笔订单 | maxOrderSize | 单笔订单最大金额限制 | 1000 | | 最小单笔订单 | minOrderSize | 单笔订单最小金额限制 | 1 | | 最大每日亏损 | maxDailyLoss | 每日最大亏损限制 | 10000 | | 最大每日订单数 | maxDailyOrders | 每日最大订单数量限制 | 100 | | 价格容忍度 | priceTolerance | 价格偏差容忍百分比 | 5% | | 延迟秒数 | delaySeconds | 跟单延迟时间 | 0 | | 支持卖出 | supportSell | 是否跟随卖出 | true | | 最小订单深度 | minOrderDepth | 订单簿深度要求 | null | | 最大价差 | maxSpread | 买卖价差限制 | null | | 最低价格 | minPrice | 最低价格限制 | null | | 最高价格 | maxPrice | 最高价格限制 | null | | 最大仓位金额 | maxPositionValue | 最大持仓总金额 | null | | 关键字过滤模式 | keywordFilterMode | DISABLED/WHITELIST/BLACKLIST | DISABLED | | 关键字列表 | keywords | 关键字数组 | [] | | 市场截止时间限制 | maxMarketEndDate | 市场结束时间限制 | null | > [!IMPORTANT] > 跟单配置表单应完全复用现有的跟单配置组件,保持参数一致性 #### 3.2.3 表单验证 - 回测名称: 不能为空,长度1-100字符 - Leader: 必须选择有效的Leader - 初始金额: 必须大于0 - 回测天数: 必须在1-30之间 - 其他配置参数: 遵循现有跟单配置的验证规则 #### 3.2.4 提交逻辑 1. 表单验证通过后,提交到后端API 2. 后端保存回测任务到数据库,状态设置为"待执行" 3. 前端显示创建成功提示,自动跳转到列表页面 4. 回测任务由后端轮询服务自动获取并执行 ### 3.3 回测详情页面 #### 3.3.1 页面布局 **顶部概览卡片**: - 回测名称 - Leader信息 - 初始金额 / 最终金额 - 收益额 / 收益率 - 回测时间范围 - 总交易笔数 - 状态 **资金变化图表**: - X轴: 时间 - Y轴: 账户余额 - 折线图展示资金随时间的变化 **交易记录表格**: | 时间 | 市场 | 方向 | 数量 | 价格 | 金额 | 盈亏 | 余额 | |-----|------|-----|------|------|------|------|------| | 2026-01-01 10:05 | BTC > $100k | 买入 YES | 100 | 0.65 | 65 | - | 935.00 | | 2026-01-01 14:20 | BTC > $100k | 卖出 YES | 100 | 0.72 | 72 | +7.00 | 942.00 | | 2026-01-05 16:00 | ETH > $5k | 买入 YES | 50 | 0.80 | 40 | - | 902.00 | | 2026-01-10 00:00 | ETH > $5k | 市场结算 YES | 50 | 1.00 | 50 | +10.00 | 952.00 | > [!NOTE] > **交易类型说明**: > - **买入**: 跟随Leader买入 > - **卖出**: 跟随Leader卖出 > - **市场结算**: 市场到期自动结算(赎回) > > **手续费**: 回测不计算手续费,简化计算逻辑 **统计数据**: - 总交易笔数 - 买入笔数 / 卖出笔数 - 胜率 (盈利交易 / 总交易) - 平均收益 - 最大单笔盈利 - 最大单笔亏损 - 最大回撤 ## 四、业务规则 ### 4.1 回测执行规则 #### 4.1.1 资金检查 - **停止条件**: 当账户余额 < $1 **且无任何持仓**时,回测自动停止 - **继续条件**: 如果余额 < $1 但仍有持仓,继续处理后续交易 - 原因: Leader 可能卖出,或市场到期结算,释放资金 - 处理: 跳过无法执行的买入订单,继续处理卖出和结算 - **订单检查**: 每次下单前检查余额是否充足 - **不足处理**: 余额不足时跳过该买入订单,记录日志,继续监听后续交易 > [!IMPORTANT] > 只要有持仓存在,就不应停止回测,因为后续可能通过卖出或市场结算回收资金 #### 4.1.2 历史数据获取 - 从 Polymarket API 获取 Leader 的历史交易记录 - 根据回测天数计算起始时间: `startTime = now - (backtestDays × 24 × 3600 × 1000)` - 按时间顺序回放交易 #### 4.1.3 交易执行模拟 - 按照配置的跟单规则计算跟单金额 - 应用所有过滤条件 (价格、深度、关键字等) - 模拟订单成交(不计算手续费) - 更新账户余额 > [!NOTE] > 回测不计算手续费,简化计算逻辑,避免过于复杂的精度问题 #### 4.1.3.1 余额不足的处理 ⚠️ **场景说明**: - 当前余额不足以执行买入订单 - 但有持仓未卖出(相当于"待赎回资产") **处理策略**: **方案A: 严格模式**(推荐) - ✅ 仅使用当前可用余额(`currentBalance`) - ✅ 余额不足时跳过该订单,不考虑持仓价值 - ✅ 理由: 更保守,模拟真实场景(持仓未卖出前资金不可用) **方案B: 宽松模式**(可选) - 计算"潜在可用资金" = `currentBalance + 持仓市值` - 允许"透支"买入,后续通过卖出或结算平衡 - 风险: 可能产生不切实际的回测结果 **推荐实现**: ```kotlin // 严格检查余额 if (totalCost > currentBalance) { logger.info("余额不足以执行买入订单: 需要 $totalCost, 可用 $currentBalance") logger.debug("当前持仓价值: ${calculatePositionValue(positions)}, 但不计入可用余额") continue // 跳过该订单 } ``` **特殊情况: 市场即将结算** - 如果持仓市场在接下来很短时间内会结算,可以提前释放资金 - 实现: 在每次交易前先执行市场结算检查(已在4.1.5实现) > [!IMPORTANT] > 采用**严格模式**更符合真实跟单场景,避免回测结果过于乐观 #### 4.1.4 卖出跟随 - 如果 `supportSell = true`,跟随 Leader 的卖出操作 - 按照买入时的比例卖出持仓 - 计算盈亏并更新余额 #### 4.1.5 市场结算处理 ⭐ - **触发时机**: - **实时检查**: 在处理每笔Leader交易前,检查所有持仓市场的`endDate` - **到期即结算**: 如果市场结束时间 ≤ 当前交易时间,立即结算该持仓 - **兜底处理**: 回测结束时,结算所有剩余持仓 - **结算规则**: - 获取市场最终结果 (通过Polymarket API) - 持仓方向为胜出方: 按 **1.0** 价格结算 - 持仓方向为失败方: 按 **0.0** 价格结算 - 市场未结算或无法获取结果: 按**成本价**结算 (保守估计) - **资金流转**: 结算后的资金立即计入余额,可用于后续交易 - **交易记录**: 生成"市场结算"类型的交易记录,用于详情展示 > [!IMPORTANT] > **实时结算的优势**: > - ✅ 模拟真实场景: 市场结束时资金会自动返还 > - ✅ 提高资金利用率: 结算后的资金可以参与后续交易 > - ✅ 更准确的收益计算: 反映实际的资金周转情况 ### 4.2 数据持久化 #### 4.2.1 回测任务表 - 保存回测基本信息和配置 - 记录执行状态和结果 #### 4.2.2 回测交易记录表 - 保存每笔模拟交易的详细信息 - 用于详情页面展示和分析 ### 4.3 并发控制 - 同一时间最多支持 5 个回测任务并发执行 - 新任务排队等待,FIFO策略 - 前端显示任务队列位置 ## 五、UI/UX 要求 ### 5.1 响应式设计 - 支持桌面和移动端浏览 - 表格在小屏幕上支持横向滚动 ### 5.2 国际化 - 支持中文和英文 - 所有文案提供双语版本 ### 5.3 交互体验 - 创建回测: 表单提交时显示Loading状态 - 回测执行中: 显示进度条或百分比 - 数据加载: Skeleton占位符 - 操作反馈: Toast提示 (成功/失败/警告) ### 5.4 数据可视化 - 资金变化图表使用 ECharts 或 Recharts - 支持图表缩放和数据点Tooltip - 图表颜色: 盈利绿色,亏损红色 ## 六、非功能需求 ### 6.1 性能要求 - 回测列表页面加载时间 < 2秒 - 单个回测任务执行时间 < 5分钟 (30天数据) - 详情页图表渲染时间 < 1秒 ### 6.2 数据准确性 - 回测结果误差 < 0.1% - 余额计算使用 BigDecimal 避免精度丢失 - 价格和数量精确到小数点后8位 ### 6.3 安全性 - 回测数据仅用户本人可见 - API接口需要身份认证 - 防止SQL注入和XSS攻击 ## 七、后续迭代规划 ### Phase 2 (可选) - 支持批量创建回测任务 - 回测结果对比功能 - 导出回测报告 (PDF/Excel) - AI策略推荐 ### Phase 3 (可选) - 实时回测 (边交易边回测) - 社区策略分享 - 策略市场 --- ## 附录: 页面路由规划 - 回测列表: `/copy-trading/backtest` - 新增回测: `/copy-trading/backtest/create` - 回测详情: `/copy-trading/backtest/:id`