mirror of
https://github.com/laoxong/nofx.git
synced 2026-06-04 09:58:22 +08:00
25 KiB
25 KiB
NOFX 辩论竞技场模块 - 技术文档
概述
辩论竞技场是一个多 AI 协作决策系统,多个具有不同性格的 AI 模型对市场状况进行辩论并达成交易决策共识。系统支持多轮辩论、实时流推送、投票机制和自动交易执行。
1. 架构概览
┌─────────────────────────────────────────────────────────────────────────────┐
│ 辩论竞技场系统 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 多头 AI │ │ 空头 AI │ │ 分析 AI │ │ 风控 AI │ │
│ │ 🐂 │ │ 🐻 │ │ 📊 │ │ 🛡️ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └──────────────────┴──────────────────┴──────────────────┘ │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ 辩论引擎 │ │
│ │ (debate/engine) │ │
│ └─────────┬─────────┘ │
│ │ │
│ ┌──────────────────────────┼──────────────────────────┐ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌─────────▼─────────┐ ┌────────▼────────┐ │
│ │ 市场数据 │ │ 投票系统 │ │ 自动执行器 │ │
│ │ 组装 │ │ 与共识机制 │ │ (可选) │ │
│ └─────────────┘ └───────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
文件结构
├── debate/
│ └── engine.go # 核心辩论引擎逻辑
├── api/
│ └── debate.go # HTTP 处理器和 SSE 流
├── store/
│ └── debate.go # 数据库操作和模式
└── web/src/pages/
└── DebateArenaPage.tsx # 前端 UI
2. 性格系统
2.1 可用性格
| 性格 | 图标 | 名称 | 描述 | 交易偏向 |
|---|---|---|---|---|
| Bull | 🐂 | 激进多头 | 寻找做多机会 | 乐观,趋势跟随 |
| Bear | 🐻 | 谨慎空头 | 关注风险 | 悲观,做空偏向 |
| Analyst | 📊 | 数据分析师 | 纯数据驱动 | 无偏见,客观分析 |
| Contrarian | 🔄 | 逆势者 | 挑战多数观点 | 另类视角 |
| Risk Manager | 🛡️ | 风控经理 | 关注风险控制 | 仓位管理,止损 |
2.2 性格提示词增强
文件位置: debate/engine.go:buildDebateSystemPrompt() (365-426行)
## 辩论模式 - 第 {round}/{max_rounds} 轮
你作为 {emoji} {personality} 参与辩论。
### 你的辩论角色:
{personality_description}
### 辩论规则:
1. 分析所有候选币种
2. 用具体数据支持论点
3. 回应其他参与者 (第2轮起)
4. 有说服力但基于数据
5. 可以推荐多个不同操作的币种
### 输出格式 (严格 JSON):
<reasoning>
- 带数据引用的市场分析
- 主要交易论点
- 对他人的回应 (第2轮起)
</reasoning>
<decision>
[
{"symbol": "BTCUSDT", "action": "open_long", "confidence": 75, ...},
{"symbol": "ETHUSDT", "action": "open_short", "confidence": 80, ...}
]
</decision>
3. 辩论执行流程
3.1 会话创建
POST /api/debates
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 验证用户认证 │
│ 2. 解析 CreateDebateRequest: │
│ - name, strategy_id, symbol, max_rounds, participants │
│ - interval_minutes, prompt_variant, auto_execute │
│ 3. 验证策略所有权 │
│ 4. 自动选择币种 (如未提供): │
│ - 静态币种 → 使用策略第一个币种 │
│ - CoinPool → 从 AI500 API 获取 │
│ - OI Top → 从 OI 排行 API 获取 │
│ - Mixed → 先尝试池,回退到 OI │
│ 5. 设置默认值: │
│ - max_rounds: 3 (范围 2-5) │
│ - interval_minutes: 5 │
│ - prompt_variant: "balanced" │
│ 6. 在数据库创建 DebateSession │
│ 7. 添加带 AI 模型和性格的参与者 │
│ 8. 返回完整会话及参与者 │
└─────────────────────────────────────────────────────────────┘
3.2 辩论轮次执行
文件位置: debate/engine.go:runDebate() (157-289行)
┌─────────────────────────────────────────────────────────────┐
│ 每轮 (1 到 max_rounds): │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. 广播 "round_start" 事件 │ │
│ │ 2. 每个参与者 (按 speak_order): │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ a. 构建性格增强的系统提示词 │ │ │
│ │ │ b. 构建用户提示词: │ │ │
│ │ │ - 市场数据 (来自策略引擎) │ │ │
│ │ │ - 之前的辩论消息 (第2轮起) │ │ │
│ │ │ c. 调用 AI 模型,60秒超时 │ │ │
│ │ │ d. 从响应解析多币种决策 │ │ │
│ │ │ e. 保存消息到数据库 │ │ │
│ │ │ f. 广播 "message" 事件 │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ │ 3. 广播 "round_end" 事件 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 所有轮次后: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ 1. 进入投票阶段 (status = "voting") │ │
│ │ 2. 收集所有参与者的最终投票 │ │
│ │ 3. 确定多币种共识 │ │
│ │ 4. 存储最终决策 │ │
│ │ 5. 更新状态为 "completed" │ │
│ │ 6. 广播 "consensus" 事件 │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
4. 共识算法
4.1 投票收集
文件位置: debate/engine.go:collectVotes() (542-567行)
每个参与者:
┌─────────────────────────────────────────────────────────────┐
│ 1. 构建投票系统提示词 │
│ 2. 构建带辩论摘要的投票用户提示词 │
│ 3. 调用 AI 模型获取最终投票 │
│ 4. 解析多币种决策 │
│ 5. 验证/修复币种与 session.Symbol 一致 │
│ 6. 保存投票到数据库 │
│ 7. 广播 "vote" 事件 │
└─────────────────────────────────────────────────────────────┘
4.2 多币种共识确定
文件位置: debate/engine.go:determineMultiCoinConsensus() (752-924行)
算法:
1. 收集所有投票中的所有币种决策
2. 按 symbol → action → 聚合数据 分组
3. 对每个投票决策:
weight = confidence / 100.0
累加:
┌─────────────────────────────────────────────────────────┐
│ score += weight │
│ total_confidence += confidence │
│ total_leverage += leverage │
│ total_position_pct += position_pct │
│ total_stop_loss += stop_loss │
│ total_take_profit += take_profit │
│ count++ │
└─────────────────────────────────────────────────────────┘
4. 对每个币种:
找到胜出操作 (最高 score)
计算平均值:
┌─────────────────────────────────────────────────────────┐
│ avg_confidence = total_confidence / count │
│ avg_leverage = clamp(total_leverage / count, 1, 20) │
│ avg_position_pct = clamp(total_pct / count, 0.1, 1.0) │
│ avg_stop_loss = 默认 3% (如未设置) │
│ avg_take_profit = 默认 6% (如未设置) │
└─────────────────────────────────────────────────────────┘
5. 返回共识决策数组
4.3 共识示例
输入投票:
AI1 (多头): BTC open_long (conf=80, lev=10, pos=0.3)
AI2 (空头): BTC open_short (conf=60, lev=5, pos=0.2)
AI3 (分析): BTC open_long (conf=70, lev=8, pos=0.25)
计算:
open_long:
score = 0.80 + 0.70 = 1.50
avg_conf = (80 + 70) / 2 = 75
avg_lev = (10 + 8) / 2 = 9
avg_pos = (0.3 + 0.25) / 2 = 0.275
open_short:
score = 0.60
avg_conf = 60
avg_lev = 5
avg_pos = 0.2
胜出: open_long (score 1.50 > 0.60)
输出:
{
"symbol": "BTCUSDT",
"action": "open_long",
"confidence": 75,
"leverage": 9,
"position_pct": 0.275,
"stop_loss": 0.03,
"take_profit": 0.06
}
5. 自动执行
5.1 执行流程
文件位置: debate/engine.go:ExecuteConsensus() (932-1052行)
POST /api/debates/:id/execute
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 验证会话状态 = completed │
│ 2. 验证 final_decision 存在且未执行 │
│ 3. 验证操作是 open_long 或 open_short │
│ 4. 获取当前市场价格 │
│ 5. 获取账户余额: │
│ - 尝试 available_balance │
│ - 回退到 total_equity 或 wallet_balance │
│ 6. 计算仓位大小: │
│ position_size_usd = available_balance × position_pct │
│ (最小 $12 以满足交易所要求) │
│ 7. 计算止损和止盈价格: │
│ ┌───────────────────────────────────────────────────┐ │
│ │ open_long: │ │
│ │ SL = price × (1 - stop_loss_pct) │ │
│ │ TP = price × (1 + take_profit_pct) │ │
│ │ open_short: │ │
│ │ SL = price × (1 + stop_loss_pct) │ │
│ │ TP = price × (1 - take_profit_pct) │ │
│ └───────────────────────────────────────────────────┘ │
│ 8. 创建 Decision 对象 │
│ 9. 调用 executor.ExecuteDecision() │
│ 10. 更新 final_decision: │
│ - executed = true/false │
│ - executed_at = 时间戳 │
│ - error 消息 (如失败) │
└─────────────────────────────────────────────────────────────┘
6. API 接口
6.1 接口列表
| 接口 | 方法 | 描述 |
|---|---|---|
/api/debates |
GET | 列出用户所有辩论 |
/api/debates/personalities |
GET | 获取 AI 性格配置 |
/api/debates/:id |
GET | 获取辩论详情 |
/api/debates |
POST | 创建新辩论 |
/api/debates/:id/start |
POST | 开始辩论执行 |
/api/debates/:id/cancel |
POST | 取消运行中的辩论 |
/api/debates/:id/execute |
POST | 执行共识交易 |
/api/debates/:id |
DELETE | 删除辩论 |
/api/debates/:id/messages |
GET | 获取所有消息 |
/api/debates/:id/votes |
GET | 获取所有投票 |
/api/debates/:id/stream |
GET | SSE 实时流 |
6.2 创建辩论请求
POST /api/debates
{
"name": "BTC 市场辩论",
"strategy_id": "strategy-uuid",
"symbol": "BTCUSDT",
"max_rounds": 3,
"interval_minutes": 5,
"prompt_variant": "balanced",
"auto_execute": false,
"trader_id": "trader-uuid",
"enable_oi_ranking": true,
"oi_ranking_limit": 10,
"oi_duration": "1h",
"participants": [
{"ai_model_id": "deepseek-v3", "personality": "bull"},
{"ai_model_id": "qwen-max", "personality": "bear"},
{"ai_model_id": "gpt-5.2", "personality": "analyst"}
]
}
7. 实时更新 (SSE)
7.1 SSE 接口
文件位置: api/debate.go:HandleDebateStream() (407-453行)
GET /api/debates/:id/stream
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 验证用户所有权 │
│ 2. 设置 SSE 头: │
│ Content-Type: text/event-stream │
│ Cache-Control: no-cache │
│ Connection: keep-alive │
│ 3. 发送初始状态 │
│ 4. 订阅事件 │
│ 5. 流式推送更新直到客户端断开 │
└─────────────────────────────────────────────────────────────┘
7.2 事件类型
| 事件 | 触发时机 | 数据 |
|---|---|---|
initial |
连接开始 | 完整会话状态 |
round_start |
轮次开始 | {round, status} |
message |
AI 发言 | DebateMessage 对象 |
round_end |
轮次结束 | {round, status} |
vote |
AI 投票 | DebateVote 对象 |
consensus |
辩论完成 | DebateDecision 对象 |
error |
发生错误 | {error: string} |
8. 数据库模式
8.1 表结构
debate_sessions:
CREATE TABLE debate_sessions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
strategy_id TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
symbol TEXT NOT NULL,
max_rounds INTEGER DEFAULT 3,
current_round INTEGER DEFAULT 0,
interval_minutes INTEGER DEFAULT 5,
prompt_variant TEXT DEFAULT 'balanced',
final_decision TEXT,
final_decisions TEXT,
auto_execute BOOLEAN DEFAULT 0,
trader_id TEXT,
enable_oi_ranking BOOLEAN DEFAULT 0,
oi_ranking_limit INTEGER DEFAULT 10,
oi_duration TEXT DEFAULT '1h',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
debate_participants:
CREATE TABLE debate_participants (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
ai_model_id TEXT NOT NULL,
ai_model_name TEXT NOT NULL,
provider TEXT NOT NULL,
personality TEXT NOT NULL,
color TEXT NOT NULL,
speak_order INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES debate_sessions(id) ON DELETE CASCADE
);
debate_messages:
CREATE TABLE debate_messages (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
round INTEGER NOT NULL,
ai_model_id TEXT NOT NULL,
ai_model_name TEXT NOT NULL,
provider TEXT NOT NULL,
personality TEXT NOT NULL,
message_type TEXT NOT NULL,
content TEXT NOT NULL,
decision TEXT,
decisions TEXT,
confidence INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES debate_sessions(id) ON DELETE CASCADE
);
debate_votes:
CREATE TABLE debate_votes (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL,
ai_model_id TEXT NOT NULL,
ai_model_name TEXT NOT NULL,
action TEXT NOT NULL,
symbol TEXT NOT NULL,
confidence INTEGER DEFAULT 0,
leverage INTEGER DEFAULT 5,
position_pct REAL DEFAULT 0.2,
stop_loss_pct REAL DEFAULT 0.03,
take_profit_pct REAL DEFAULT 0.06,
reasoning TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (session_id) REFERENCES debate_sessions(id) ON DELETE CASCADE
);
9. 前端组件
9.1 页面结构
文件位置: web/src/pages/DebateArenaPage.tsx
DebateArenaPage
├── 左侧边栏 (w-56)
│ ├── 新建辩论按钮
│ ├── 辩论会话列表
│ │ └── SessionItem (状态, 名称, 时间戳)
│ └── 在线交易员列表
│ └── TraderItem (名称, 状态, AI 模型)
│
├── 主内容区
│ ├── 头部栏
│ │ ├── 会话信息 (名称, 状态, 币种)
│ │ ├── 参与者头像
│ │ └── 投票摘要
│ │
│ ├── 内容区 (双栏)
│ │ ├── 左: 讨论记录
│ │ │ ├── 轮次标题
│ │ │ └── MessageCards (可展开)
│ │ │
│ │ └── 右: 最终投票
│ │ └── VoteCards (操作, 置信度, 理由)
│ │
│ └── 共识栏
│ ├── 最终决策显示
│ └── 执行按钮 (如果 auto_execute 禁用)
│
└── 弹窗
├── CreateModal
│ ├── 名称输入
│ ├── 策略选择器
│ ├── 币种输入 (自动填充)
│ ├── 最大轮数选择器
│ └── 参与者选择器 (AI 模型 + 性格)
│
└── ExecuteModal
└── 交易员选择器
9.2 状态颜色
const STATUS_COLOR = {
pending: 'bg-gray-500',
running: 'bg-blue-500 animate-pulse',
voting: 'bg-yellow-500 animate-pulse',
completed: 'bg-green-500',
cancelled: 'bg-red-500',
}
9.3 操作样式
const ACT = {
open_long: {
color: 'text-green-400',
bg: 'bg-green-500/20',
icon: <TrendingUp />,
label: 'LONG'
},
open_short: {
color: 'text-red-400',
bg: 'bg-red-500/20',
icon: <TrendingDown />,
label: 'SHORT'
},
hold: {
color: 'text-blue-400',
bg: 'bg-blue-500/20',
icon: <Minus />,
label: 'HOLD'
},
wait: {
color: 'text-gray-400',
bg: 'bg-gray-500/20',
icon: <Clock />,
label: 'WAIT'
},
}
10. 集成点
10.1 策略系统
辩论会话依赖保存的策略:
- 币种来源配置: static/pool/OI top
- 市场数据指标: K线、时间周期、技术指标
- 风控参数: 杠杆限制、仓位大小
- 自定义提示词: 角色定义、交易规则
10.2 AI 模型系统
每个参与者需要:
- AI 模型配置 (provider, API key, 自定义 URL)
- 支持的 providers: deepseek, qwen, openai, claude, gemini, grok, kimi
- 客户端初始化带超时处理 (每次调用 60s)
10.3 交易员系统
自动执行需要:
- 运行中状态的活跃交易员
- 交易员必须有有效的交易所连接
- 执行器接口:
ExecuteDecision(),GetBalance()
总结
辩论竞技场模块提供了一个复杂的多 AI 协作决策系统:
- 多性格辩论: 5 种独特的 AI 性格 (多头、空头、分析师、逆势者、风控经理),具有独特的交易偏向
- 共识机制: 基于置信度的加权投票来确定最终决策
- 实时更新: SSE 流推送实时辩论进度
- 自动执行: 可选的基于共识的自动交易执行
- 策略集成: 与策略配置深度集成,用于市场数据和风控参数
- 多币种支持: 能够同时分析和决策多个币种
该系统使用户能够利用多个 AI 视角做出更稳健的交易决策,同时保持对执行的完全控制。
文档版本: 1.0.0 最后更新: 2025-01-15