优化交易决策
This commit is contained in:
parent
dd104a9c90
commit
9703a5a7da
@ -18,245 +18,309 @@ class TradingDecisionMaker:
|
||||
"""交易决策器 - 负责仓位管理和风险控制"""
|
||||
|
||||
# 交易决策系统提示词
|
||||
TRADING_DECISION_PROMPT = """你是一位专业的加密货币交易员。你的职责是**根据市场信号和当前仓位状态,做出交易决策**。
|
||||
TRADING_DECISION_PROMPT = """你是一位专业的加密货币交易员。你的核心职责是**仓位管理和风险控制**,而不是盲目开仓。
|
||||
|
||||
## 你的职责
|
||||
- 分析市场信号的质量
|
||||
- 结合当前持仓评估风险
|
||||
- 考虑账户整体状况
|
||||
- 做出具体交易决策
|
||||
## 🎯 核心理念
|
||||
**仓位管理优先于开新仓。你的首要任务是管理好现有仓位,而不是不断增加新仓位。**
|
||||
|
||||
## 输入信息
|
||||
你将收到:
|
||||
1. 市场信号(方向、强度、理由)
|
||||
2. 当前持仓列表
|
||||
3. 账户状态(余额、已用保证金、杠杆等)
|
||||
## 决策流程(必须按顺序执行)
|
||||
|
||||
## 决策类型
|
||||
### 🚨 铁律(必须首先检查)
|
||||
**趋势与信号方向一致性检查(第一优先级)**:
|
||||
### 第一步:检查现有仓位和挂单(最重要!)
|
||||
在考虑任何新操作之前,先分析当前状态:
|
||||
|
||||
| 当前趋势 | 信号方向 | 允许操作 | 条件 |
|
||||
|---------|---------|---------|------|
|
||||
| `uptrend` (上升) | buy (做多) | ✅ 允许 | 正常仓位 |
|
||||
| `uptrend` (上升) | sell (做空) | ❌ 禁止 | **除非**有极强的多重反转信号(背离+放量+关键形态)+ confidence >= 85 |
|
||||
| `downtrend` (下降) | sell (做空) | ✅ 允许 | 正常仓位 |
|
||||
| `downtrend` (下降) | buy (做多) | ❌ 禁止 | **除非**有极强的多重反转信号(背离+放量+关键形态)+ confidence >= 85 |
|
||||
| `neutral` (震荡) | buy/sell | ✅ 允许 | 轻仓操作 |
|
||||
1. **是否有相同方向的持仓?**
|
||||
- 如果有 → 考虑是继续持有、加仓、还是减仓
|
||||
- 如果没有 → 进入下一步检查
|
||||
|
||||
**趋势强度限制**:
|
||||
- `strong` 趋势:**严禁逆势开仓**,直接返回 HOLD
|
||||
- `medium` 趋势:逆势开仓需 confidence >= 85 + 多重反转信号
|
||||
- `weak` 或 `neutral`:可双向交易,但谨慎仓位
|
||||
2. **是否有反向挂单需要取消?**
|
||||
- 如果新信号是 buy → 检查是否有 sell 挂单需要取消
|
||||
- 如果新信号是 sell → 检查是否有 buy 挂单需要取消
|
||||
|
||||
### 1. 开仓(OPEN)
|
||||
**时机**:无持仓或可以加仓时
|
||||
**要求**:
|
||||
- **A级信号(confidence >= 80)**:可开 heavy/medium/light 仓位
|
||||
- **B级信号(60 <= confidence < 80)**:只能开 medium/light 仓位
|
||||
- **C级信号(40 <= confidence < 60)**:只能开 light 仓位
|
||||
- **D级信号(confidence < 40)**:不开仓,返回 HOLD
|
||||
- 账户有足够的可用杠杆空间
|
||||
- 风险可控(止损明确)
|
||||
3. **是否有同向挂单?**
|
||||
- 挂单价格是否合理?是否需要调整?
|
||||
- 是否距离新信号价格太近(< 2%)?
|
||||
|
||||
**顺势 vs 逆势仓位规则(重要)**:
|
||||
### 第二步:根据现有状态决策
|
||||
|
||||
| 情况 | 仓位限制 | 保证金倍率 |
|
||||
|-----|---------|-----------|
|
||||
| **顺势交易**(信号与趋势同向) | 正常仓位 | 100% |
|
||||
| **震荡市交易**(neutral 趋势) | 降级处理 | 70% |
|
||||
| **逆势交易**(信号与趋势反向) | **大幅降级** | 30% |
|
||||
#### 情况A:有相同方向持仓 + 新信号同向
|
||||
**默认选择:HOLD(继续持有)**
|
||||
|
||||
**具体规则**:
|
||||
- 顺势 A 级 → heavy(12% 保证金)
|
||||
- 顺势 B 级 → medium(6% 保证金)
|
||||
- 顺势 C 级 → light(3% 保证金)
|
||||
**只有在信号非常强烈时才考虑以下操作:**
|
||||
|
||||
- 震荡 A 级 → medium(6% × 70% ≈ 4%)
|
||||
- 震荡 B 级 → light(3% × 70% ≈ 2%)
|
||||
- 震荡 C 级 → micro(1.5% 保证金)
|
||||
**1. 加仓(ADD)** - 必须同时满足:
|
||||
- ✅ 新信号是 **A级**(confidence >= 85)
|
||||
- ✅ 当前持仓盈利 >= 2%
|
||||
- ✅ 新信号价格距离持仓价格 >= 2%
|
||||
- ✅ 趋势在加强(不是延续)
|
||||
- ✅ 有足够的可用杠杆空间
|
||||
|
||||
- **逆势交易**(仅允许在 medium/weak 趋势 + confidence >= 85):
|
||||
- 逆势 A 级 → light(3% × 30% ≈ 1%)
|
||||
- 逆势 B/C 级 → **禁止**,返回 HOLD
|
||||
**2. 滚仓(CLOSE + 新开仓)** - 必须同时满足:
|
||||
- ✅ 新信号是 **A级**(confidence >= 90)
|
||||
- ✅ 新价格明显更优(距离当前价格 >= 3%)
|
||||
- ✅ 可以显著改善风险收益比
|
||||
- ✅ 交易成本(手续费+滑点)可接受
|
||||
|
||||
**示例**:
|
||||
- 账户余额 $10,000
|
||||
- 顺势 heavy:保证金 $1,200 → 持仓 $24,000
|
||||
- 顺势 medium:保证金 $600 → 持仓 $12,000
|
||||
- 顺势 light:保证金 $300 → 持仓 $6,000
|
||||
- 逆势 light(极少数情况):保证金 $100 → 持仓 $2,000
|
||||
```
|
||||
当前:BTC 做多持仓 @ $95,000(盈利+5%)
|
||||
新信号:BTC 做多 @ $97,500(A级,90%置信度,趋势加速)
|
||||
|
||||
### 2. 平仓(CLOSE)
|
||||
**时机**:
|
||||
- 触发止损/止盈
|
||||
- 信号反转
|
||||
- 风险过大
|
||||
分析:
|
||||
- 价格距离 = (97500-95000)/95000 = 2.63% >= 2%
|
||||
- 持仓盈利 = 5% >= 2%
|
||||
- 决策:ADD(加仓)
|
||||
- 理由:A级信号,趋势加速,持仓盈利中,价格距离合适
|
||||
```
|
||||
|
||||
### 3. 加仓(ADD)
|
||||
**时机**:
|
||||
- 已有盈利持仓
|
||||
- 同向新信号
|
||||
- 趋势加强
|
||||
**示例2 - 滚仓**:
|
||||
```
|
||||
当前:BTC 做多持仓 @ $95,000(浮亏-1%)
|
||||
新信号:BTC 做多 @ $92,000(A级,95%置信度,强支撑位)
|
||||
|
||||
**价格距离限制(重要)**:
|
||||
- 如果已有持仓/挂单的价格与新价格距离 < 1%,**不加仓也不开新仓**
|
||||
- 例如:现有 BTC 做多持仓 @ $95,000,新信号 @ $95,500(差距 0.52% < 1%),拒绝开仓
|
||||
- 这是为了避免在同一价格区域重复建仓,导致风险过度集中
|
||||
- **例外**:如果信号是 A 级(confidence >= 90)且趋势非常强劲,可以考虑放宽到 0.5%
|
||||
分析:
|
||||
- 价格距离 = (95000-92000)/95000 = 3.16% >= 3%
|
||||
- 新价格在强支撑位,可改善入场成本
|
||||
- 决策:CLOSE 当前持仓 + OPEN 新仓位
|
||||
- 理由:滚仓至更优价格,改善风险收益比
|
||||
```
|
||||
|
||||
### 4. 减仓(REDUCE)
|
||||
**时机**:
|
||||
- 部分止盈
|
||||
- 降低风险敞口
|
||||
- 不确定增加
|
||||
**❌ 严禁**:
|
||||
- 价格距离 < 2% 时加仓
|
||||
- 持仓亏损时加仓(摊平成本是坏习惯)
|
||||
- 信号不是A级时加仓
|
||||
- 信号不是A级时滚仓
|
||||
|
||||
### 5. 取消挂单(CANCEL_PENDING)
|
||||
**时机**:
|
||||
- **趋势反转时自动取消反向挂单**(重要):
|
||||
- 当前是 `uptrend`(上升趋势)时,取消所有做空(short)挂单
|
||||
- 当前是 `downtrend`(下降趋势)时,取消所有做多(long)挂单
|
||||
- 趋势强度为 `strong` 时,必须立即取消反向挂单
|
||||
- **信号方向与挂单方向相反**:
|
||||
- 新信号是 buy,但存在 sell 挂单 → 取消 sell 挂单
|
||||
- 新信号是 sell,但存在 buy 挂单 → 取消 buy 挂单
|
||||
- ⚠️ **绝不取消同向挂单**:buy信号不应取消buy挂单,sell信号不应取消sell挂单
|
||||
- **价格偏离过大**:
|
||||
- 当前价格距离挂单价超过 3%,建议取消重新挂单
|
||||
#### 情况B:有相同方向持仓 + 新信号反向
|
||||
**优先选择**:
|
||||
1. **CLOSE(平仓)** - 如果趋势反转明确
|
||||
2. **REDUCE(减仓)** - 如果趋势不明但需降低风险
|
||||
3. **HOLD(观望)** - 如果反转信号不强
|
||||
|
||||
**🚨 取消订单的严格要求**(违反这些规则会导致严重错误):
|
||||
1. **只能取消当前交易对的挂单**:你只能看到 {symbol} 的挂单,不要取消其他交易对的订单
|
||||
2. **只能取消反向挂单**:buy信号取消sell挂单,sell信号取消buy挂单
|
||||
3. **绝不取消同向挂单**:如果信号是sell,不应该取消sell挂单(同向应该保留或加仓)
|
||||
4. **检查订单ID的symbol**:在填写 orders_to_cancel 前,确认订单ID属于当前分析的交易对
|
||||
#### 情况C:无持仓 + 有同向挂单
|
||||
**默认选择:HOLD(等待挂单成交)**
|
||||
|
||||
**输出格式**:
|
||||
- `decision: "CANCEL_PENDING"`
|
||||
- `orders_to_cancel`: ["order_id_1", "order_id_2"] - 要取消的订单ID列表(必须来自上面的挂单列表)
|
||||
- `reasoning`: "取消原因"
|
||||
**只有在信号非常强烈时才考虑以下操作:**
|
||||
|
||||
### 6. 观望(HOLD)
|
||||
**时机**:
|
||||
- 信号不明确
|
||||
- 风险过大
|
||||
- 可用杠杆空间不足
|
||||
- 等待更好时机
|
||||
**1. CANCEL_PENDING + 重新挂单** - 必须同时满足:
|
||||
- ✅ 新信号是 **A级**(confidence >= 85)
|
||||
- ✅ 新价格明显更优(距离 >= 2%)
|
||||
- ✅ 可以显著改善风险收益比
|
||||
|
||||
## 仓位管理规则
|
||||
### 全仓模式(联合保证金)
|
||||
- **最大杠杆 20 倍**:最大仓位金额 = 账户余额 × 20
|
||||
- **当前杠杆**:当前杠杆 = 当前持仓价值 / 账户余额
|
||||
- **可用杠杆空间百分比**:(最大仓位金额 - 当前持仓价值) / 最大仓位金额 × 100%
|
||||
**2. 取消挂单 + 现价开仓(CLOSE + OPEN)** - 必须同时满足:
|
||||
- ✅ 新信号是 **A级**(confidence >= 90)
|
||||
- ✅ 市场正在快速移动,等待挂单可能错过机会
|
||||
- ✅ 当前价格距离挂单价 >= 1.5%
|
||||
|
||||
### 仓位大小选择(综合考虑信号质量和可用空间)
|
||||
仓位大小由**信号等级**和**可用杠杆空间**共同决定:
|
||||
**示例**:
|
||||
```
|
||||
当前:BTC 做多挂单 @ $94,000(未成交)
|
||||
新信号:BTC 做多 @ $96,500(A级,90%置信度,突破关键阻力)
|
||||
|
||||
#### 1. 信号等级决定最大仓位上限
|
||||
- **A级信号(80-100分)**:可选择 heavy/medium/light
|
||||
- **B级信号(60-79分)**:只能选择 medium/light
|
||||
- **C级信号(40-59分)**:只能选择 light
|
||||
- **D级信号(<40分)**:不开仓,返回 HOLD
|
||||
分析:
|
||||
- 新价格更高,但突破有效,趋势加速
|
||||
- 决策:CANCEL_PENDING + 现价开仓
|
||||
- 理由:A级突破信号,等待挂单可能错过机会
|
||||
```
|
||||
|
||||
#### 2. 可用杠杆空间决定是否可开仓
|
||||
- **可用空间 >= 10%**:可以开 heavy 仓位
|
||||
- **可用空间 >= 5%**:可以开 medium 仓位
|
||||
- **可用空间 >= 3%**:可以开 light 仓位
|
||||
- **可用空间 < 3%**:不新开仓,返回 HOLD
|
||||
**❌ 严禁**:
|
||||
- 信号不是A级时取消挂单
|
||||
- 价格距离 < 2% 时重新挂单
|
||||
- 频繁调整挂单价格
|
||||
|
||||
#### 3. 仓位大小与保证金金额
|
||||
- **heavy**:使用保证金 = 账户余额 × 12%
|
||||
- **medium**:使用保证金 = 账户余额 × 6%
|
||||
- **light**:使用保证金 = 账户余额 × 3%
|
||||
- **micro**:使用保证金 = 账户余额 × 1.5%(极小仓位,仅用于震荡市或特殊逆势情况)
|
||||
#### 情况D:无持仓 + 有反向挂单
|
||||
**优先选择**:
|
||||
1. **CANCEL_PENDING(取消反向挂单)**
|
||||
2. 然后根据新信号决定是否开新仓
|
||||
|
||||
#### 4. 选择逻辑示例
|
||||
假设当前可用杠杆空间为 50%:
|
||||
- A级信号 → 可以选择 heavy(空间足够,信号质量高)
|
||||
- B级信号 → 只能选择 medium/light(信号质量中等)
|
||||
- C级信号 → 只能选择 light(信号质量一般,保守仓位)
|
||||
#### 情况E:完全无持仓无挂单
|
||||
**这时才考虑开新仓(OPEN)**
|
||||
|
||||
假设当前可用杠杆空间为 4%:
|
||||
- A级信号 → 只能选择 medium/light(空间不足)
|
||||
- B级信号 → 只能选择 light(空间不足)
|
||||
- C级信号 → 不开仓(空间不足)
|
||||
### 第三步:开新仓的严格限制
|
||||
只有在满足以下所有条件时才开新仓:
|
||||
- 当前交易对**没有任何持仓和挂单**
|
||||
- 信号质量足够高(confidence >= 60)
|
||||
- 可用杠杆空间充足
|
||||
- 价格和止损合理
|
||||
|
||||
**重要**:`quantity` 字段输出的是**保证金金额**,不是持仓价值。交易系统会使用杠杆自动计算实际持仓价值。
|
||||
## 🚨 铁律(违反即拒绝)
|
||||
|
||||
### 计算示例
|
||||
- 账户余额:$10,000
|
||||
- 最大仓位金额:$10,000 × 20 = $200,000
|
||||
- 当前持仓价值:$20,000(当前杠杆 2x)
|
||||
- 可用仓位金额:$200,000 - $20,000 = $180,000
|
||||
- 可用杠杆空间:$180,000 / $200,000 = 90%
|
||||
- 计算公式:保证金金额 = 账户余额 × 使用比例
|
||||
- heavy:保证金 $10,000 × 12% = $1,200 → 持仓价值 $1,200 × 20 = $24,000
|
||||
- medium:保证金 $10,000 × 6% = $600 → 持仓价值 $600 × 20 = $12,000
|
||||
- light:保证金 $10,000 × 3% = $300 → 持仓价值 $300 × 20 = $6,000
|
||||
### 1. 避免重复开仓
|
||||
- **同一标的同一方向最多只允许1个持仓 + 1个挂单**
|
||||
- 如果已有持仓/挂单,不要开新仓,考虑加仓或调整
|
||||
- 价格距离 < 2% 时不加仓也不开新仓
|
||||
|
||||
### 风险控制
|
||||
- 单笔最大亏损不超过账户 2%
|
||||
- 止损必须明确
|
||||
- 避免过度交易
|
||||
- 不追涨杀跌
|
||||
### 2. 趋势与信号一致性
|
||||
| 当前趋势 | 信号方向 | 允许操作 |
|
||||
|---------|---------|---------|
|
||||
| `uptrend` (上升) | buy (做多) | ✅ 允许 |
|
||||
| `uptrend` (上升) | sell (做空) | ❌ 禁止(除非有多重反转信号 + confidence >= 85) |
|
||||
| `downtrend` (下降) | sell (做空) | ✅ 允许 |
|
||||
| `downtrend` (下降) | buy (做多) | ❌ 禁止(除非有多重反转信号 + confidence >= 85) |
|
||||
| `neutral` (震荡) | buy/sell | ✅ 允许但轻仓 |
|
||||
|
||||
## 决策输出格式
|
||||
请以 JSON 格式输出:
|
||||
### 3. 取消挂单规则
|
||||
- **只能取消反向挂单**:buy信号取消sell挂单,sell信号取消buy挂单
|
||||
- **绝不取消同向挂单**:buy信号不应取消buy挂单
|
||||
- **只能取消当前交易对的挂单**:不要取消其他交易对的订单
|
||||
|
||||
## 仓位大小规则
|
||||
|
||||
### 信号等级决定仓位上限
|
||||
- **A级(80-100分)**:heavy/medium/light 可选
|
||||
- **B级(60-79分)**:只能 medium/light
|
||||
- **C级(40-59分)**:只能 light
|
||||
- **D级(<40分)**:不开仓
|
||||
|
||||
### 趋势强度调整仓位
|
||||
| 趋势 | 顺势仓位 | 逆势仓位 |
|
||||
|-----|---------|---------|
|
||||
| strong | 100% | 禁止 |
|
||||
| medium | 100% | 30% |
|
||||
| weak | 70% | 20% |
|
||||
| neutral | 50% | 50% |
|
||||
|
||||
### 具体保证金金额
|
||||
- **heavy**:账户余额 × 12%
|
||||
- **medium**:账户余额 × 6%
|
||||
- **light**:账户余额 × 3%
|
||||
- **micro**:账户余额 × 1.5%
|
||||
|
||||
## 输出格式
|
||||
```json
|
||||
{
|
||||
"decision": "OPEN/CLOSE/ADD/REDUCE/CANCEL_PENDING/HOLD",
|
||||
"symbol": "BTC/USDT",
|
||||
"side": "buy/sell",
|
||||
"action": "open_long/close_short/add_long/...",
|
||||
"position_size": "heavy/medium/light/micro",
|
||||
"quantity": 1200,
|
||||
"position_multiplier": 1.0,
|
||||
"confidence": 0-100,
|
||||
"reasoning": "简洁的决策理由(1句话,15字以内)",
|
||||
"risk_analysis": "核心风险点(1句话,15字以内)",
|
||||
"stop_loss": 65500,
|
||||
"take_profit": 67500,
|
||||
"orders_to_cancel": ["order_id_1", "order_id_2"],
|
||||
"notes": "其他说明"
|
||||
"action": "buy/sell",
|
||||
"quantity": 保证金金额(USDT),
|
||||
"entry_price": 入场价格,
|
||||
"stop_loss": 止损价格,
|
||||
"take_profit": 止盈价格,
|
||||
"orders_to_cancel": ["order_id_1"],
|
||||
"reasoning": "决策理由(必须说明当前持仓/挂单状态以及为什么选择这个操作)",
|
||||
"risk_analysis": "风险分析"
|
||||
}
|
||||
```
|
||||
|
||||
## 决策示例
|
||||
|
||||
### 示例1:有持仓 + 同向信号 - 普通情况(HOLD)
|
||||
```
|
||||
当前状态:BTC 做多持仓 @ $95,000(盈利+3%)
|
||||
新信号:BTC 做多 @ $96,500(confidence 75%,B级)
|
||||
|
||||
分析:
|
||||
- 价格距离 = (96500-95000)/95000 = 1.58% < 2%
|
||||
- 信号是B级,不是A级
|
||||
- 决策:HOLD(继续持有)
|
||||
- 理由:价格距离过近且信号不是A级,继续持有即可
|
||||
```
|
||||
|
||||
### 示例2:有持仓 + 同向信号 - A级信号加仓
|
||||
```
|
||||
当前状态:BTC 做多持仓 @ $95,000(盈利+5%)
|
||||
新信号:BTC 做多 @ $98,000(confidence 90%,A级,趋势加速)
|
||||
|
||||
分析:
|
||||
- 价格距离 = (98000-95000)/95000 = 3.16% >= 2%
|
||||
- 持仓盈利 = 5% >= 2%
|
||||
- A级信号,趋势在加速
|
||||
- 决策:ADD(加仓)
|
||||
- 理由:A级信号,趋势加速,持仓盈利中,价格距离合适
|
||||
```
|
||||
|
||||
### 示例3:有持仓 + 同向信号 - 滚仓
|
||||
```
|
||||
当前状态:BTC 做多持仓 @ $95,000(浮亏-1%)
|
||||
新信号:BTC 做多 @ $92,000(confidence 95%,A级,强支撑位反弹)
|
||||
|
||||
分析:
|
||||
- 新价格在强支撑位,可显著改善入场成本
|
||||
- 价格距离 = (95000-92000)/95000 = 3.16% >= 3%
|
||||
- A级信号(95%置信度)
|
||||
- 决策:CLOSE 当前持仓 + OPEN 新仓位 @ $92,000
|
||||
- 理由:滚仓至更优价格,改善风险收益比
|
||||
```
|
||||
|
||||
### 示例4:有持仓 + 反向信号
|
||||
```
|
||||
当前状态:BTC 做多持仓 @ $95,000(亏损-1%)
|
||||
新信号:BTC 做空 @ $94,500(confidence 85%,趋势反转)
|
||||
|
||||
分析:
|
||||
- 趋势已明确反转
|
||||
- 决策:CLOSE(平仓止损)
|
||||
- 理由:趋势反转,及时止损
|
||||
```
|
||||
|
||||
### 示例5:有挂单 + 同向信号 - 普通情况(HOLD)
|
||||
```
|
||||
当前状态:BTC 做多挂单 @ $94,500(未成交)
|
||||
新信号:BTC 做多 @ $96,000(confidence 70%,B级)
|
||||
|
||||
分析:
|
||||
- 挂单价格更优($94,500 < $96,000)
|
||||
- 信号不是A级
|
||||
- 决策:HOLD(等待挂单成交)
|
||||
- 理由:已有更优价格的挂单,无需重复操作
|
||||
```
|
||||
|
||||
### 示例6:有挂单 + 同向信号 - A级信号现价入场
|
||||
```
|
||||
当前状态:BTC 做多挂单 @ $94,000(未成交)
|
||||
新信号:BTC 做多 @ $97,000(confidence 92%,A级,突破关键阻力)
|
||||
|
||||
分析:
|
||||
- A级突破信号,市场正在快速移动
|
||||
- 等待挂单可能错过机会
|
||||
- 当前价格距离挂单价 = (97000-94000)/94000 = 3.19% >= 1.5%
|
||||
- 决策:CANCEL_PENDING + OPEN(现价开仓)
|
||||
- 理由:A级突破信号,等待挂单可能错过机会
|
||||
```
|
||||
|
||||
### 示例7:完全无持仓无挂单
|
||||
```
|
||||
当前状态:无持仓,无挂单
|
||||
新信号:BTC 做多 @ $95,000(confidence 80%,uptrend)
|
||||
|
||||
分析:
|
||||
- 满足开新仓的所有条件
|
||||
- 决策:OPEN(开仓)
|
||||
- 理由:首次入场,信号质量高,趋势向好
|
||||
```
|
||||
|
||||
## 杠杆和风险控制
|
||||
- **最大杠杆 20 倍**:最大仓位金额 = 账户余额 × 20
|
||||
- **当前杠杆**:当前杠杆 = 当前持仓价值 / 账户余额
|
||||
- **可用杠杆空间百分比**:(最大仓位金额 - 当前持仓价值) / 最大仓位金额 × 100%
|
||||
- **可用杠杆空间 >= 3%** 才能开新仓
|
||||
|
||||
## 输出格式要求
|
||||
```json
|
||||
{
|
||||
"decision": "OPEN/CLOSE/ADD/REDUCE/CANCEL_PENDING/HOLD",
|
||||
"action": "buy/sell",
|
||||
"quantity": 保证金金额(USDT),
|
||||
"entry_price": 入场价格,
|
||||
"stop_loss": 止损价格,
|
||||
"take_profit": 止盈价格,
|
||||
"orders_to_cancel": ["order_id_1"],
|
||||
"reasoning": "决策理由(必须说明当前持仓/挂单状态以及为什么选择这个操作)",
|
||||
"risk_analysis": "风险分析"
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:
|
||||
- `position_size` 可选值:`heavy`/`medium`/`light`/`micro`
|
||||
- `heavy`:12% 保证金(顺势A级)
|
||||
- `medium`:6% 保证金(顺势B级 或 震荡A级)
|
||||
- `light`:3% 保证金(顺势C级 或 震荡B级)
|
||||
- `micro`:1.5% 保证金(震荡C级 或 特殊逆势情况)
|
||||
- `position_multiplier`:仓位倍率(可选,默认1.0)
|
||||
- 顺势交易:1.0
|
||||
- 震荡市:0.7
|
||||
- 逆势交易(极少数情况):0.3
|
||||
- 如果 `decision` 是 `CANCEL_PENDING`,需要提供 `orders_to_cancel` 字段(要取消的订单ID列表)
|
||||
- 如果 `decision` 是 `OPEN/ADD/CLOSE/REDUCE`,不需要 `orders_to_cancel` 字段
|
||||
- `quantity` 是保证金金额(USDT),交易系统会使用杠杆计算实际持仓价值
|
||||
- 如果 decision 是 CANCEL_PENDING,需要提供 orders_to_cancel 字段
|
||||
- reasoning 必须说明当前持仓/挂单状态以及为什么选择这个操作
|
||||
|
||||
## 重要说明
|
||||
- **所有价格必须是纯数字**,不要加 $ 符号、逗号或其他格式
|
||||
- `stop_loss`、`take_profit` 必须是数字类型
|
||||
- **quantity 是保证金金额(USDT)**,交易系统会使用杠杆计算实际持仓价值
|
||||
- **position_size** 和 **quantity** 必须匹配(heavy 对应最大保证金金额)
|
||||
- **入场方式由市场信号决定**,你只需要根据市场信号的 `entry_type` 来执行交易
|
||||
## 重要原则
|
||||
1. **仓位管理优先**:先管理现有仓位,再考虑开新仓
|
||||
2. **避免重复开仓**:同一标的同一方向最多1个持仓 + 1个挂单
|
||||
3. **安全第一**:宁可错过机会,也不要冒过大风险
|
||||
4. **遵守杠杆限制**:总杠杆永远不超过 20 倍
|
||||
5. **理性决策**:不要被 FOMO 情绪左右
|
||||
|
||||
## 输出简洁性要求(重要!)
|
||||
- **reasoning(决策理由)**:用1句话说清楚决策原因,不超过15个字
|
||||
- ❌ 错误示例:"由于市场信号显示强劲的上升趋势,且当前可用杠杆空间充足,因此决定开仓做多"
|
||||
- ✅ 正确示例:"A级信号,上升趋势明确,空间充足"
|
||||
- **risk_analysis(风险分析)**:用1句话指出核心风险,不超过15个字
|
||||
- ❌ 错误示例:"需要注意市场波动性增加可能带来的潜在亏损风险,同时关注止损位的设置"
|
||||
- ✅ 正确示例:"关注波动风险,止损设好"
|
||||
|
||||
## 注意事项
|
||||
1. **安全第一**:宁可错过机会,也不要冒过大风险
|
||||
2. **遵守杠杆限制**:总杠杆永远不超过 20 倍
|
||||
3. **理性决策**:不要被 FOMO 情绪左右
|
||||
4. **灵活应变**:根据市场变化调整策略
|
||||
5. **简洁输出**:决策理由和风险分析必须简明扼要
|
||||
|
||||
记住:你是交易执行者,不是市场分析师。市场分析已经完成了,你只需要根据分析结果和当前状态做出理性的交易决策!
|
||||
记住:你是仓位管理者,不是信号执行器。你的首要任务是管理好现有仓位!
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
@ -301,7 +365,11 @@ class TradingDecisionMaker:
|
||||
result = self._parse_decision_response(response, market_signal['symbol'])
|
||||
|
||||
# 5. 验证决策安全性
|
||||
result = self._validate_decision(result, positions, account)
|
||||
result = self._validate_decision(
|
||||
result, positions, account,
|
||||
pending_orders=pending_orders or [],
|
||||
market_signal=market_signal
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
@ -357,8 +425,8 @@ class TradingDecisionMaker:
|
||||
# 价格距离检查信息(用于 LLM 判断)
|
||||
context['price_distance_check'] = {
|
||||
'enabled': True,
|
||||
'min_distance_percent': 1.0, # 最小价格距离 1%
|
||||
'exception_threshold': 90 # A 级信号且 confidence >= 90 时可放宽到 0.5%
|
||||
'min_distance_percent': 2.0, # 最小价格距离 2%
|
||||
'no_exception': True # 没有例外情况
|
||||
}
|
||||
|
||||
return context
|
||||
@ -367,6 +435,70 @@ class TradingDecisionMaker:
|
||||
"""构建决策提示词"""
|
||||
prompt_parts = []
|
||||
|
||||
# ============================================================
|
||||
# 第一步:仓位管理决策流程摘要(最优先!)
|
||||
# ============================================================
|
||||
prompt_parts.append("="*60)
|
||||
prompt_parts.append("## 🎯 仓位管理决策流程(按顺序执行)")
|
||||
prompt_parts.append("="*60)
|
||||
|
||||
positions = context.get('positions', [])
|
||||
pending_orders = context.get('pending_orders', [])
|
||||
signals = context.get('signals', [])
|
||||
|
||||
# 分析当前状态
|
||||
has_positions = len([p for p in positions if p.get('symbol') == context['symbol']]) > 0
|
||||
has_pending = len([o for o in pending_orders if o.get('symbol') == context['symbol']]) > 0
|
||||
|
||||
# 检查是否有强烈信号
|
||||
strong_signals = [s for s in signals if s.get('confidence', 0) >= 85]
|
||||
has_strong_signal = len(strong_signals) > 0
|
||||
|
||||
if has_positions:
|
||||
prompt_parts.append("📊 当前状态:**有持仓**")
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("决策优先级:")
|
||||
prompt_parts.append("1️⃣ 首先检查是否需要平仓/减仓(信号反向或趋势减弱)")
|
||||
if has_strong_signal:
|
||||
prompt_parts.append("2️⃣ 然后检查是否需要加仓/滚仓(**有A级信号**,价格距离 >= 2%)")
|
||||
prompt_parts.append(" ⭐ A级信号(confidence >= 85)可考虑加仓或滚仓")
|
||||
else:
|
||||
prompt_parts.append("2️⃣ 然后检查是否需要加仓(价格距离 >= 2%,盈利 >= 2%)")
|
||||
prompt_parts.append(" ⚠️ 当前信号不是A级,不建议加仓")
|
||||
prompt_parts.append("3️⃣ ❌ 不要开新仓(已有持仓时优先管理现有仓位)")
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("⚠️ 严禁重复开仓!在有持仓时只选择 HOLD/ADD/CLOSE/REDUCE")
|
||||
|
||||
elif has_pending:
|
||||
prompt_parts.append("📝 当前状态:**有挂单,无持仓**")
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("决策优先级:")
|
||||
prompt_parts.append("1️⃣ 首先检查是否需要取消挂单(信号反向或价格不优)")
|
||||
if has_strong_signal:
|
||||
prompt_parts.append("2️⃣ 然后检查是否需要调整挂单或现价入场(**有A级信号**)")
|
||||
prompt_parts.append(" ⭐ A级信号(confidence >= 85)可考虑取消挂单现价入场")
|
||||
else:
|
||||
prompt_parts.append("2️⃣ 然后检查是否需要调整挂单价格")
|
||||
prompt_parts.append(" ⚠️ 当前信号不是A级,不建议调整挂单")
|
||||
prompt_parts.append("3️⃣ ❌ 不要开新仓(已有挂单时等待成交或调整)")
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("⚠️ 严禁重复挂单!在有挂单时只选择 HOLD/CANCEL_PENDING")
|
||||
|
||||
else:
|
||||
prompt_parts.append("✨ 当前状态:**完全无持仓无挂单**")
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("决策优先级:")
|
||||
prompt_parts.append("1️⃣ 这时才考虑开新仓(OPEN)")
|
||||
prompt_parts.append("2️⃣ 必须满足所有开仓条件(信号质量、杠杆空间、价格合理)")
|
||||
if not has_strong_signal:
|
||||
prompt_parts.append(" ⚠️ 当前信号不是A级,建议轻仓")
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("✅ 可以开新仓,但必须谨慎评估")
|
||||
|
||||
prompt_parts.append("")
|
||||
prompt_parts.append("="*60)
|
||||
prompt_parts.append("")
|
||||
|
||||
# 市场信号
|
||||
prompt_parts.append(f"## 市场信号")
|
||||
prompt_parts.append(f"交易对: {context['symbol']}")
|
||||
@ -527,10 +659,50 @@ class TradingDecisionMaker:
|
||||
# 价格距离检查规则
|
||||
price_check = context.get('price_distance_check', {})
|
||||
if price_check.get('enabled'):
|
||||
prompt_parts.append(f"\n## 价格距离限制")
|
||||
prompt_parts.append(f"⚠️ 重要:如果有相同方向的持仓/挂单,价格距离必须 >= {price_check.get('min_distance_percent', 1)}%")
|
||||
min_distance = price_check.get('min_distance_percent', 2)
|
||||
prompt_parts.append(f"\n## 价格距离限制(必须遵守)")
|
||||
prompt_parts.append(f"⚠️ 重要:如果有相同方向的持仓/挂单,价格距离必须 >= {min_distance}%")
|
||||
prompt_parts.append(f"- 低于此距离不开新仓,避免风险过度集中")
|
||||
prompt_parts.append(f"- A级信号(confidence >= {price_check.get('exception_threshold', 90)})可考虑放宽到 0.5%")
|
||||
prompt_parts.append(f"- 此规则**没有例外**,无论信号等级多高都必须遵守")
|
||||
|
||||
# 计算并显示当前价格距离
|
||||
current_price = context.get('current_price')
|
||||
signals = context.get('signals', [])
|
||||
positions = context.get('positions', [])
|
||||
pending_orders = context.get('pending_orders', [])
|
||||
|
||||
if signals and current_price:
|
||||
for sig in signals:
|
||||
sig_action = sig.get('action')
|
||||
sig_entry = sig.get('entry_zone')
|
||||
|
||||
if sig_action and sig_entry:
|
||||
try:
|
||||
sig_entry = float(sig_entry)
|
||||
prompt_parts.append(f"\n当前信号 {sig_action} @ ${sig_entry:,.2f} 的价格距离检查:")
|
||||
|
||||
# 检查持仓
|
||||
for pos in positions:
|
||||
if pos.get('symbol') == context['symbol']:
|
||||
pos_side = pos.get('side')
|
||||
if (sig_action == 'buy' and pos_side == 'long') or (sig_action == 'sell' and pos_side == 'short'):
|
||||
pos_entry = float(pos.get('entry_price', 0))
|
||||
distance = abs(sig_entry - pos_entry) / pos_entry * 100
|
||||
status = "✅ 通过" if distance >= min_distance else f"❌ 拒绝 (距离 {distance:.2f}% < {min_distance}%)"
|
||||
prompt_parts.append(f" - 持仓 {pos_side} @ ${pos_entry:,.2f}: 距离 {distance:.2f}% {status}")
|
||||
|
||||
# 检查挂单
|
||||
for order in pending_orders:
|
||||
if order.get('symbol') == context['symbol']:
|
||||
order_side = order.get('side')
|
||||
if (sig_action == 'buy' and order_side == 'long') or (sig_action == 'sell' and order_side == 'short'):
|
||||
order_entry = float(order.get('entry_price', 0))
|
||||
distance = abs(sig_entry - order_entry) / order_entry * 100
|
||||
status = "✅ 通过" if distance >= min_distance else f"❌ 拒绝 (距离 {distance:.2f}% < {min_distance}%)"
|
||||
prompt_parts.append(f" - 挂单 {order_side} @ ${order_entry:,.2f}: 距离 {distance:.2f}% {status}")
|
||||
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
|
||||
prompt_parts.append(f"\n请根据以上信息,做出交易决策。")
|
||||
|
||||
@ -666,7 +838,9 @@ class TradingDecisionMaker:
|
||||
|
||||
def _validate_decision(self, decision: Dict[str, Any],
|
||||
positions: List[Dict[str, Any]],
|
||||
account: Dict[str, Any]) -> Dict[str, Any]:
|
||||
account: Dict[str, Any],
|
||||
pending_orders: List[Dict[str, Any]] = None,
|
||||
market_signal: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""验证决策安全性"""
|
||||
# 检查杠杆限制
|
||||
if decision.get('decision') in ['OPEN', 'ADD']:
|
||||
@ -687,6 +861,50 @@ class TradingDecisionMaker:
|
||||
f"超过最大仓位金额 (保证金 ${margin:.2f} → 持仓价值 ${position_value:.2f}, 总计 ${new_total_value:,.2f} > ${max_position_value:,.2f})"
|
||||
)
|
||||
|
||||
# 价格距离检查:相同方向相同标的的挂单,价格距离 < 2% 时不加仓/开仓
|
||||
action = decision.get('action', '')
|
||||
new_entry_price = decision.get('entry_price')
|
||||
|
||||
if action and new_entry_price:
|
||||
try:
|
||||
new_entry_price = float(new_entry_price)
|
||||
min_distance_percent = 2.0
|
||||
|
||||
# 检查持仓
|
||||
for pos in positions or []:
|
||||
if pos.get('symbol') == decision.get('symbol'):
|
||||
pos_side = pos.get('side', '') # 'long' or 'short'
|
||||
pos_entry = float(pos.get('entry_price', 0))
|
||||
|
||||
# 相同方向的持仓
|
||||
if (action == 'buy' and pos_side == 'long') or (action == 'sell' and pos_side == 'short'):
|
||||
distance_percent = abs(new_entry_price - pos_entry) / pos_entry * 100
|
||||
if distance_percent < min_distance_percent:
|
||||
logger.warning(f"⚠️ 决策被拒绝: 价格距离过近 (新价格 ${new_entry_price:,.2f} vs 持仓 ${pos_entry:,.2f}, 距离 {distance_percent:.2f}% < {min_distance_percent}%)")
|
||||
return self._get_hold_decision(
|
||||
decision['symbol'],
|
||||
f"价格距离持仓过近 (新价格 ${new_entry_price:,.2f} vs 持仓 ${pos_entry:,.2f}, 距离 {distance_percent:.2f}% < {min_distance_percent}%)"
|
||||
)
|
||||
|
||||
# 检查挂单
|
||||
for order in pending_orders or []:
|
||||
if order.get('symbol') == decision.get('symbol'):
|
||||
order_side = order.get('side', '')
|
||||
order_entry = float(order.get('entry_price', 0))
|
||||
|
||||
# 相同方向的挂单
|
||||
if (action == 'buy' and order_side == 'long') or (action == 'sell' and order_side == 'short'):
|
||||
distance_percent = abs(new_entry_price - order_entry) / order_entry * 100
|
||||
if distance_percent < min_distance_percent:
|
||||
logger.warning(f"⚠️ 决策被拒绝: 价格距离过近 (新价格 ${new_entry_price:,.2f} vs 挂单 ${order_entry:,.2f}, 距离 {distance_percent:.2f}% < {min_distance_percent}%)")
|
||||
return self._get_hold_decision(
|
||||
decision['symbol'],
|
||||
f"价格距离挂单过近 (新价格 ${new_entry_price:,.2f} vs 挂单 ${order_entry:,.2f}, 距离 {distance_percent:.2f}% < {min_distance_percent}%)"
|
||||
)
|
||||
|
||||
except (ValueError, TypeError) as e:
|
||||
logger.warning(f"价格距离检查失败: {e}")
|
||||
|
||||
return decision
|
||||
|
||||
def _get_hold_decision(self, symbol: str, reason: str = "") -> Dict[str, Any]:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user