--- comet_change: trade-reflection-system role: technical-design canonical_spec: openspec archived-with: trade-reflection-system --- # 交易反思系统 (Trade Reflection System) - Design Doc ## 1. 概述 在现有交易复盘模块基础上,构建「人工反思 → AI 提炼 → 经验沉淀」的学习闭环。核心能力包括:按天组织交易视图、跨日交易自动配对、结构化反思、标签系统、AI 重新分析、历史经验库。 ## 2. 架构设计 ### 2.1 整体架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ 前 端 层 │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ 按天交易视图 │ │ 反思编辑面板 │ │ 经验库页面 │ │ │ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │ │ └─────────────────┴────────────────────┘ │ │ 现有交易复盘页面 (改造) │ └─────────────────────────┬───────────────────────────────────┘ │ REST API ┌─────────────────────────┴───────────────────────────────────┐ │ 后 端 层 │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ trade_review.py (现有 + 8个新端点) │ │ │ └──────────────────────────────────────────────────────┘ │ │ ┌──────────────┐ ┌──────────────────────────────┐ │ │ │trade_parser │ │ ai_analysis.py (扩展) │ │ │ │(不变) │ │ └── 反思增强分析 + 版本存储 │ │ │ └──────────────┘ └──────────────────────────────┘ │ └─────────────────────────┬───────────────────────────────────┘ │ SQLAlchemy ORM ┌─────────────────────────┴───────────────────────────────────┐ │ 数 据 层 │ │ TradeRecord(扩展) + 6新表 + SQLite/MySQL │ └─────────────────────────────────────────────────────────────┘ ``` ### 2.2 模块职责 | 模块 | 职责 | 变更类型 | |------|------|---------| | `trade_review.py` | 新增 8 个 API 端点 | 扩展 | | `analysis_models.py` | 扩展 TradeRecord + 新增 6 个模型 | 扩展 | | `ai_analysis.py` | 新增反思增强分析提示词 + 版本化存储 | 扩展 | | `trade_parser.py` | 不变 | 无变更 | | `futures_analysis.js` | 新增前端视图和交互逻辑 | 扩展 | ## 3. 数据模型详细设计 ### 3.1 TradeRecord (扩展) 在现有表上新增字段: ```python # 新增字段 reflection_status = Column(String(16), default='none') # none/pending/done ``` - `none`: 未写反思 - `pending`: 已写反思,待 AI 分析 - `done`: 已完成 AI 分析 ### 3.2 TradePair (新表) 存储跨日交易配对关系: ```python class TradePair(AnalysisBase): __tablename__ = "trade_pairs" id = Column(Integer, primary_key=True, autoincrement=True) pair_type = Column(String(16), nullable=False) # auto/manual symbol = Column(String(32), nullable=False, index=True) variety = Column(String(16), nullable=False, index=True) direction = Column(String(8), nullable=False) # long/short open_trade_id = Column(Integer, nullable=False, index=True) open_date = Column(String(16), nullable=False) open_time = Column(String(32), nullable=False) open_price = Column(Float, nullable=True) close_trade_ids = Column(JSON, nullable=True) # [id1, id2, ...] close_date = Column(String(16), nullable=True) close_time = Column(String(32), nullable=True) close_price = Column(Float, nullable=True) status = Column(String(16), nullable=False, default='open') # open/closed pnl = Column(Float, nullable=True) # 配对盈亏 commission_total = Column(Float, nullable=True) # 总手续费 created_at = Column(DateTime, nullable=False, default=datetime.now) updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now) ``` ### 3.3 TradeReflection (新表) 每笔交易的结构化反思: ```python class TradeReflection(AnalysisBase): __tablename__ = "trade_reflections" id = Column(Integer, primary_key=True, autoincrement=True) trade_id = Column(Integer, nullable=False, index=True) trade_pair_id = Column(Integer, nullable=True, index=True) # 模板字段 entry_reason = Column(Text, nullable=True) # 入场理由 entry_timing = Column(String(16), nullable=True) # good/fair/poor position_management = Column(Text, nullable=True) # 仓位管理反思 exit_reason = Column(Text, nullable=True) # 出场理由 exit_timing = Column(String(16), nullable=True) # good/fair/poor discipline_score = Column(Integer, nullable=True) # 1-5 # 自由文本 free_reflection = Column(Text, nullable=True) # AI 分析状态 ai_analysis_status = Column(String(16), default='none') # none/pending/done ai_analysis_version = Column(Integer, default=0) created_at = Column(DateTime, nullable=False, default=datetime.now) updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now) ``` ### 3.4 DailyReflection (新表) 当日整体反思: ```python class DailyReflection(AnalysisBase): __tablename__ = "daily_reflections" id = Column(Integer, primary_key=True, autoincrement=True) trade_date = Column(String(16), nullable=False, unique=True, index=True) emotion_state = Column(String(32), nullable=True) # 情绪状态 market_judgment = Column(Text, nullable=True) # 市场判断 execution_discipline = Column(Integer, nullable=True) # 1-5 overall_rating = Column(Integer, nullable=True) # 1-5 summary = Column(Text, nullable=True) # 总结 improvements = Column(Text, nullable=True) # 改进方向 created_at = Column(DateTime, nullable=False, default=datetime.now) updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now) ``` ### 3.5 TradeTag (新表) 标签定义: ```python class TradeTag(AnalysisBase): __tablename__ = "trade_tags" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(64), nullable=False, unique=True) category = Column(String(32), nullable=True) # operation/mindset/discipline/technical/custom description = Column(Text, nullable=True) is_preset = Column(Boolean, nullable=False, default=False) usage_count = Column(Integer, nullable=False, default=0) created_at = Column(DateTime, nullable=False, default=datetime.now) ``` 预设标签清单: - 操作类: 追涨杀跌, 逆市操作, 提前入场, 延迟出场, 加仓过早 - 心态类: 情绪化交易, 恐惧平仓, 贪婪持仓, 报复性交易 - 纪律类: 严格执行计划, 违反止损, 超仓交易, 频繁交易 - 技术类: 突破交易, 回调交易, 趋势跟踪, 震荡交易 ### 3.6 TradeRecordTag (关联表) ```python class TradeRecordTag(AnalysisBase): __tablename__ = "trade_record_tags" id = Column(Integer, primary_key=True, autoincrement=True) trade_id = Column(Integer, nullable=False, index=True) tag_id = Column(Integer, nullable=False, index=True) __table_args__ = ( Index('ix_trade_tag_unique', 'trade_id', 'tag_id', unique=True), ) ``` ### 3.7 TradeExperience (新表) 经验教训: ```python class TradeExperience(AnalysisBase): __tablename__ = "trade_experiences" id = Column(Integer, primary_key=True, autoincrement=True) trade_id = Column(Integer, nullable=False, index=True) trade_pair_id = Column(Integer, nullable=True, index=True) reflection_id = Column(Integer, nullable=True, index=True) title = Column(String(128), nullable=False) # 经验标题 content = Column(Text, nullable=False) # 经验内容 lesson_type = Column(String(16), nullable=False) # lesson/tip/warning tags = Column(JSON, nullable=True) # [tag_name, ...] ai_version = Column(Integer, nullable=True) # AI分析版本号 created_from = Column(String(16), nullable=False) # ai/manual created_at = Column(DateTime, nullable=False, default=datetime.now) updated_at = Column(DateTime, nullable=False, default=datetime.now, onupdate=datetime.now) ``` ## 4. API 详细设计 ### 4.1 按天获取交易+配对 ``` GET /api/v1/trade-review/daily-trades/{date} Response: { "success": true, "data": { "trade_date": "2026-07-05", "trades": [...], // 原始交易记录 "pairs": [...], // 配对结果 "daily_reflection": {...}, // 当日反思 (如有) "statistics": {...} // 当天统计 } } ``` ### 4.2 配对 CRUD ``` POST /api/v1/trade-review/trade-pairs { "pair_type": "manual", "symbol": "AG2608", "open_trade_id": 123, "close_trade_ids": [456, 789] } PUT /api/v1/trade-review/trade-pairs/{id} DELETE /api/v1/trade-review/trade-pairs/{id} ``` ### 4.3 反思 CRUD ``` POST /api/v1/trade-review/reflections { "trade_id": 123, "entry_reason": "...", "entry_timing": "good", "position_management": "...", "exit_reason": "...", "exit_timing": "fair", "discipline_score": 4, "free_reflection": "..." } PUT /api/v1/trade-review/reflections/{id} GET /api/v1/trade-review/reflections?trade_id=123 ``` ### 4.4 当日反思 CRUD ``` POST /api/v1/trade-review/daily-reflections { "trade_date": "2026-07-05", "emotion_state": "平静", "market_judgment": "...", "execution_discipline": 4, "overall_rating": 4, "summary": "...", "improvements": "..." } PUT /api/v1/trade-review/daily-reflections/{id} GET /api/v1/trade-review/daily-reflections/{date} ``` ### 4.5 标签管理 ``` GET /api/v1/trade-review/tags # 获取所有标签 POST /api/v1/trade-review/tags # 创建自定义标签 { "name": "我的标签", "category": "custom" } POST /api/v1/trade-review/records/{trade_id}/tags { "tag_ids": [1, 2, 3] } DELETE /api/v1/trade-review/records/{trade_id}/tags/{tag_id} ``` ### 4.6 AI 重新分析 ``` POST /api/v1/trade-review/reanalyze { "trade_id": 123, # 或 trade_pair_id "reflection_id": 456 } Response: { "success": true, "data": { "analysis_id": 789, "version": 2, "analysis": "...", "experience_suggestions": [...] # 经验提炼建议 } } ``` ### 4.7 经验库 CRUD ``` GET /api/v1/trade-review/experiences ?tag=追涨杀跌 &lesson_type=warning &keyword=止损 &page=1&page_size=20 POST /api/v1/trade-review/experiences { "trade_id": 123, "title": "...", "content": "...", "lesson_type": "lesson", "tags": ["追涨杀跌", "违反止损"] } PUT /api/v1/trade-review/experiences/{id} DELETE /api/v1/trade-review/experiences/{id} ``` ## 5. 核心业务流程 ### 5.1 交易配对流程 ``` 1. 用户导入结算单 → TradeRecord 表 2. 用户选择日期 → 触发配对逻辑 3. 配对引擎: a. 按 variety + trade_date 筛选 b. 按品种分组 c. 对每个品种: - 找出所有开仓记录 (offset='开') - 找出所有平仓记录 (offset='平') - 按时间顺序配对 (FIFO) - 同一方向连续开仓合并为一个头寸 d. 生成 TradePair 记录 (pair_type='auto') 4. 前端展示配对结果 5. 用户可手动修正 (创建 pair_type='manual' 记录) ``` ### 5.2 反思 → AI 分析 → 经验提炼流程 ``` 1. 用户给某笔交易写反思 → POST /reflections 2. 系统更新 TradeRecord.reflection_status = 'pending' 3. 用户点击「重新 AI 分析」→ POST /reanalyze 4. 后端: a. 获取交易详情 + 多周期 K 线 b. 获取反思内容 c. 构建增强提示词 (交易信息 + K 线 + 反思) d. 调用 AI 模型 e. 解析响应,保存为 TradeExperience (ai_version=N) f. 更新 TradeReflection.ai_analysis_status = 'done' g. 更新 TradeReflection.ai_analysis_version = N h. 更新 TradeRecord.reflection_status = 'done' 5. 前端展示 AI 分析结果和经验建议 6. 用户可编辑经验建议后保存 ``` ### 5.3 AI 提示词设计 ```python prompt = f""" 你是一个有20年经验的期货交易教练。请分析以下交易及其反思,提炼经验教训。 【交易信息】 品种: {symbol} 方向: {direction} 开仓: {open_date} {open_time} @ {open_price} 平仓: {close_date} {close_time} @ {close_price} 盈亏: {pnl} 手续费: {commission} 【多周期 K 线 context】 {kline_context} 【交易者反思】 入场理由: {entry_reason} 入场时机评价: {entry_timing} 仓位管理反思: {position_management} 出场理由: {exit_reason} 出场时机评价: {exit_timing} 纪律评分: {discipline_score}/5 自由反思: {free_reflection} 请从以下维度分析并输出 JSON: {{ "trade_analysis": "对这笔交易的综合评价", "strengths": ["优点1", "优点2"], "weaknesses": ["不足1", "不足2"], "experience_lessons": [ {{ "title": "经验标题", "content": "经验内容", "lesson_type": "lesson/tip/warning", "tags": ["标签1", "标签2"] }} ] }} """ ``` ## 6. 前端设计 ### 6.1 按天交易视图 ``` ┌─────────────────────────────────────────────────────────────┐ │ 日期选择器: [2026-07-05] [<] [>] │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 当日反思 [编辑] │ │ │ │ 情绪: 平静 | 纪律: ★★★★ | 总体: ★★★★ │ │ │ │ 总结: ... │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 交易配对 #1 (AG2608 多头) 盈亏: +1200 │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ 开 09:30│→ │ 平 14:20│ [反思] [标签] [AI分析] │ │ │ │ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 交易配对 #2 (RB2610 空头) 盈亏: -800 │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ 开 10:15│→ │ 平 11:30│ [反思✓] [标签] [AI分析✓] │ │ │ │ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 未配对交易: CU2609 买开 09:45 @ 78500 │ │ │ │ [手动配对] [反思] [标签] │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 6.2 反思编辑面板 (Modal) ``` ┌─────────────────────────────────────────────────────────────┐ │ 反思编辑 - AG2608 多头 09:30→14:20 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 入场理由: [文本框] │ │ 入场时机: ○ 良好 ○ 一般 ○ 较差 │ │ │ │ 仓位管理反思: [文本框] │ │ │ │ 出场理由: [文本框] │ │ 出场时机: ○ 良好 ○ 一般 ○ 较差 │ │ │ │ 纪律评分: ☆☆☆☆☆ │ │ │ │ ─── 自由反思 ─── │ │ [多行文本框] │ │ │ │ ─── 标签 ─── │ │ [预设标签选择] + [自定义标签输入] │ │ │ │ [保存] [保存并AI分析] [取消] │ └─────────────────────────────────────────────────────────────┘ ``` ### 6.3 经验库页面 ``` ┌─────────────────────────────────────────────────────────────┐ │ 历史经验库 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ [搜索框] [标签筛选: 全部▼] [类型: 全部▼] [视图: 列表▼] │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 2026-07-05 | ⚠️ 警告 │ │ │ │ 追涨杀跌导致亏损 - AG2608 │ │ │ │ 在突破不明显的情况下追多,未设止损... │ │ │ │ 标签: 追涨杀跌 | 违反止损 │ │ │ │ [查看原交易] [编辑] │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ 2026-07-04 | 💡 经验 │ │ │ │ 严格执行计划带来稳定收益 - RB2610 │ │ │ │ 按计划入场,按止损出场,避免情绪干扰... │ │ │ │ 标签: 严格执行计划 | 趋势跟踪 │ │ │ │ [查看原交易] [编辑] │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ [时间线视图] [分类视图] │ └─────────────────────────────────────────────────────────────┘ ``` ## 7. 错误处理 | 场景 | 处理策略 | |------|---------| | 配对逻辑无法匹配 | 标记为「未配对交易」,用户手动配对 | | AI 模型调用失败 | 返回错误提示,保留 pending 状态,可重试 | | 反思为空时触发 AI 分析 | 允许,但提示用户「补充反思可获得更精准的分析」 | | 标签重复创建 | 自动去重,返回已存在标签 | | 经验保存时交易已删除 | 软删除标记,经验保留但标记「来源已删除」 | ## 8. Demo 确认环节 在设计完成后、执行代码前,需要创建一个交互式 Demo 展示以下关键交互流程: 1. 按天查看交易 + 配对展示 2. 编辑反思 + 打标签 3. 触发 AI 重新分析 4. 经验提炼和保存 5. 经验库浏览和筛选 Demo 使用静态数据模拟,确认交互后再进入实际开发。 ## 9. 测试策略 ### 9.1 单元测试 - `test_trade_pairing.py`: 配对逻辑测试 (FIFO、跨日、多次开仓) - `test_ai_prompt_builder.py`: AI 提示词构建测试 - `test_experience_extractor.py`: 经验提炼逻辑测试 ### 9.2 API 测试 - `test_reflection_api.py`: 反思 CRUD - `test_tag_api.py`: 标签管理 - `test_experience_api.py`: 经验库 CRUD - `test_reanalyze_api.py`: AI 重新分析 ### 9.3 集成测试 - `test_reflection_to_experience_flow.py`: 完整流程测试 ### 9.4 边界测试 - 空反思 AI 分析 - 跨日配对边界 (周末/节假日) - 标签去重 - 经验库分页/搜索/筛选 ## 10. 非目标确认 - 不改变现有结算单导入逻辑 - 不改变 K 线数据获取和展示 - 不改变复盘计划 V2 生成逻辑 - 不改变品种分析主页 - 不重构现有交易复盘统计功能