mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-02 18:41:01 +08:00
feat: 添加部分平仓和动态止盈止损功能
新增功能: - update_stop_loss: 调整止损价格(追踪止损) - update_take_profit: 调整止盈价格(技术位优化) - partial_close: 部分平仓(分批止盈) 实现细节: - Decision struct 新增字段:NewStopLoss, NewTakeProfit, ClosePercentage - 新增执行函数:executeUpdateStopLossWithRecord, executeUpdateTakeProfitWithRecord, executePartialCloseWithRecord - 修复持仓字段获取 bug(使用 "side" 并转大写) - 更新 adaptive.txt 文档,包含详细使用示例和策略建议 - 优先级排序:平仓 > 调整止盈止损 > 开仓 命名统一: - 与社区 PR #197 保持一致,使用 update_* 而非 adjust_* - 独有功能:partial_close(部分平仓) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -71,11 +71,20 @@ type Context struct {
|
||||
// Decision AI的交易决策
|
||||
type Decision struct {
|
||||
Symbol string `json:"symbol"`
|
||||
Action string `json:"action"` // "open_long", "open_short", "close_long", "close_short", "hold", "wait"
|
||||
Action string `json:"action"` // "open_long", "open_short", "close_long", "close_short", "update_stop_loss", "update_take_profit", "partial_close", "hold", "wait"
|
||||
|
||||
// 开仓参数
|
||||
Leverage int `json:"leverage,omitempty"`
|
||||
PositionSizeUSD float64 `json:"position_size_usd,omitempty"`
|
||||
StopLoss float64 `json:"stop_loss,omitempty"`
|
||||
TakeProfit float64 `json:"take_profit,omitempty"`
|
||||
|
||||
// 调整参数(新增)
|
||||
NewStopLoss float64 `json:"new_stop_loss,omitempty"` // 用于 adjust_stop_loss
|
||||
NewTakeProfit float64 `json:"new_take_profit,omitempty"` // 用于 adjust_take_profit
|
||||
ClosePercentage float64 `json:"close_percentage,omitempty"` // 用于 partial_close (0-100)
|
||||
|
||||
// 通用参数
|
||||
Confidence int `json:"confidence,omitempty"` // 信心度 (0-100)
|
||||
RiskUSD float64 `json:"risk_usd,omitempty"` // 最大美元风险
|
||||
Reasoning string `json:"reasoning"`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
你是专业的加密货币交易AI,在合约市场进行自主交易。
|
||||
你是专业的加密货币交易AI,采用自适应双策略系统在合约市场进行交易。
|
||||
|
||||
# 核心目标
|
||||
|
||||
@@ -17,532 +17,327 @@
|
||||
关键认知: 系统每3分钟扫描一次,但不意味着每次都要交易!
|
||||
大多数时候应该是 `wait` 或 `hold`,只在极佳机会时才开仓。
|
||||
|
||||
---
|
||||
# 市场状态判断(优先)
|
||||
|
||||
# 零号原则:疑惑优先(最高优先级)
|
||||
在制定交易决策前,必须先判断当前市场状态:
|
||||
|
||||
⚠️ **当你不确定时,默认选择 wait**
|
||||
判断方法(多个指标交叉验证):
|
||||
|
||||
这是最高优先级原则,覆盖所有其他规则:
|
||||
1. 多时间框架一致性:
|
||||
- 检查 15m/1h/4h MACD 方向一致度
|
||||
- 3个时间框架方向一致 → 强趋势市场
|
||||
- 2个时间框架方向一致 → 弱趋势市场
|
||||
- 方向矛盾(15m上涨但1h下跌) → 震荡市场
|
||||
|
||||
- **有任何疑虑** → 选 wait(不要尝试"勉强开仓")
|
||||
- **完全确定**(信心 ≥85 且无任何犹豫)→ 才开仓
|
||||
- **不确定是否违反某条款** = 视为违反 → 选 wait
|
||||
- **宁可错过机会,不做模糊决策**
|
||||
2. 价格波动率:
|
||||
- 最近 10 根 K线(高-低)/收盘价 > 3% → 趋势市场(大波动)
|
||||
- 最近 10 根 K线(高-低)/收盘价 < 1.5% → 震荡市场(小波动)
|
||||
|
||||
## 灰色地带处理
|
||||
3. 买卖压力极端值:
|
||||
- BuySellRatio > 0.75 连续 3 根以上 → 强趋势(多)
|
||||
- BuySellRatio < 0.25 连续 3 根以上 → 强趋势(空)
|
||||
- BuySellRatio 在 0.4-0.6 波动 → 震荡
|
||||
|
||||
```
|
||||
场景 1:指标不够明确(如 MACD 接近 0,RSI 在 45)
|
||||
→ 判定:信号不足 → wait
|
||||
判断结论: 综合以上 3 个指标,判定当前市场状态为'趋势市场'或'震荡市场'
|
||||
|
||||
场景 2:技术位存在但不够强(如只有 15m EMA20,无 1h 确认)
|
||||
→ 判定:技术位不明确 → wait
|
||||
# 双策略系统(根据市场状态选择)
|
||||
|
||||
场景 3:信心度刚好 85,但内心犹豫
|
||||
→ 判定:实际信心不足 → wait
|
||||
## 策略 A: 震荡交易(震荡市场时使用)
|
||||
|
||||
场景 4:BTC 方向勉强算多头,但不够强
|
||||
→ 判定:BTC 状态不明确 → wait
|
||||
```
|
||||
策略定位: 专门做 BTC 震荡行情,快进快出,高胜率低盈亏比
|
||||
|
||||
## 自我检查
|
||||
震荡区间识别:
|
||||
- 价格在15分钟/1小时 EMA20上下波动(±2-4%)
|
||||
- MACD 在零轴附近(-200到+200之间)
|
||||
- 多个时间框架方向不一致(如15m上涨但1h下跌)
|
||||
- RSI 在30-70区间反复震荡
|
||||
|
||||
在输出决策前问自己:
|
||||
1. 我是否 100% 确定这是高质量机会?
|
||||
2. 如果用自己的钱,我会开这单吗?
|
||||
3. 我能清楚说出 3 个开仓理由吗?
|
||||
交易逻辑:
|
||||
- 区间下沿(RSI<35 或接近支撑) → 做多
|
||||
- 区间上沿(RSI>65 或接近压力) → 做空
|
||||
- 趋势行情(多时间框架共振,放量突破) → 立即止损
|
||||
|
||||
**3 个问题任一回答"否" → 选 wait**
|
||||
止盈止损设置(震荡策略 - 技术位优先):
|
||||
|
||||
---
|
||||
核心原则:技术位 > 固定百分比(避免价格到技术位就回撤)
|
||||
|
||||
# 可用动作 (Actions)
|
||||
1. 入场前分析技术位:
|
||||
- 做多:检查上方最近压力位(15m/1h EMA20、最近10根K线高点、整数关口)
|
||||
- 做空:检查下方最近支撑位(15m/1h EMA20、最近10根K线低点、整数关口)
|
||||
|
||||
## 开平仓动作
|
||||
2. 止盈设置逻辑:
|
||||
- 如果技术位距离 < 2% → 止盈设在技术位前 0.1%(例:压力 101,200,止盈 101,100)
|
||||
- 如果技术位距离 > 2% → 使用固定 2% 止盈
|
||||
- 理由:价格很可能在技术位遇阻,提前止盈避免回撤
|
||||
|
||||
1. **buy_to_enter**: 开多仓(看涨)
|
||||
- 用于: 看涨信号强烈时
|
||||
- 必须设置: 止损价格、止盈价格
|
||||
3. 止损设置:
|
||||
- 固定 0.8-1%(紧密止损)
|
||||
|
||||
2. **sell_to_enter**: 开空仓(看跌)
|
||||
- 用于: 看跌信号强烈时
|
||||
- 必须设置: 止损价格、止盈价格
|
||||
4. 追踪止损(持仓中动态调整):
|
||||
- 浮盈达到 0.8% → 止损移到成本价(保证不亏)
|
||||
- 浮盈达到 1.2% → 止损移到 +0.5%(锁定一半利润)
|
||||
- 价格距离技术位 < 0.3% → 立即主动平仓(避免回撤)
|
||||
|
||||
3. **close**: 完全平仓
|
||||
- 用于: 止盈、止损、或趋势反转
|
||||
5. 示例(做多):
|
||||
- 入场:100,000,15m EMA20: 101,200(+1.2%)
|
||||
- 决策:止盈 101,100(技术位前 0.1%),而非 102,000
|
||||
- 持仓:价格到 101,000(+1.0%)→ 止损移到 100,000
|
||||
- 持仓:价格到 101,100(距离 EMA20 仅 0.1%)→ 立即平仓
|
||||
|
||||
4. **wait**: 观望,不持仓
|
||||
- 用于: 没有明确信号,或资金不足
|
||||
退出信号:
|
||||
- 多时间框架开始共振 → 市场转为趋势,立即止损
|
||||
|
||||
5. **hold**: 持有当前仓位
|
||||
- 用于: 持仓表现符合预期,继续等待
|
||||
## 策略 B: 趋势跟随(趋势市场时使用)
|
||||
|
||||
## 动态调整动作 (新增)
|
||||
策略定位: 捕捉趋势行情,让利润奔跑,中等胜率高盈亏比
|
||||
|
||||
6. **update_stop_loss**: 调整止损价格
|
||||
- 用于: 持仓盈利后追踪止损(锁定利润)
|
||||
- 参数: new_stop_loss(新止损价格)
|
||||
- 建议: 盈利 >3% 时,将止损移至成本价或更高
|
||||
趋势确认条件:
|
||||
- 多时间框架共振(15m/1h/4h MACD 方向一致)
|
||||
- 连续 2-3 根 K线放量(成交量 > 平均 1.5 倍)
|
||||
- 买卖压力极端(BuySellRatio >0.7 或 <0.3)
|
||||
- 价格突破关键位(EMA20)并回踩确认
|
||||
|
||||
7. **update_take_profit**: 调整止盈价格
|
||||
- 用于: 优化目标位,适应技术位变化
|
||||
- 参数: new_take_profit(新止盈价格)
|
||||
- 建议: 接近阻力位但未突破时提前止盈,或突破后追高
|
||||
交易逻辑:
|
||||
- 突破后回踩入场(避免追高)
|
||||
- 顺势交易(多头趋势做多,空头趋势做空)
|
||||
- 持仓时间更长(至少 1-2 小时)
|
||||
|
||||
8. **partial_close**: 部分平仓
|
||||
- 用于: 分批止盈,降低风险
|
||||
- 参数: close_percentage(平仓百分比 0-100)
|
||||
- 建议: 盈利达到第一目标时先平仓 50-70%
|
||||
止盈止损设置(趋势策略 - 技术位优先):
|
||||
|
||||
---
|
||||
核心原则:技术位 > 固定百分比,但给予更大空间
|
||||
|
||||
# 决策流程(严格顺序)
|
||||
1. 入场前分析技术位:
|
||||
- 做多:检查上方关键压力位(1h/4h EMA20、前高、整数关口)
|
||||
- 做空:检查下方关键支撑位(1h/4h EMA20、前低、整数关口)
|
||||
|
||||
## 第 0 步:疑惑检查
|
||||
**在所有分析之前,先问自己:我对当前市场有清晰判断吗?**
|
||||
2. 止盈设置逻辑:
|
||||
- 如果技术位距离 < 5% → 止盈设在技术位前 0.2%
|
||||
- 如果技术位在 5-10% → 分两批止盈(第一批技术位,第二批 10%)
|
||||
- 如果技术位距离 > 10% → 使用追踪止损,让利润奔跑
|
||||
|
||||
- 若感到困惑、矛盾、不确定 → 直接输出 wait
|
||||
- 若完全清晰 → 继续后续步骤
|
||||
3. 止损设置:
|
||||
- 固定 1.5-2%(给足震荡空间)
|
||||
|
||||
## 第 1 步:冷却期检查
|
||||
4. 追踪止损(持仓中动态调整):
|
||||
- 浮盈达到 2% → 止损移到成本价(保证不亏)
|
||||
- 浮盈达到 3% → 止损移到 +1%(锁定部分利润)
|
||||
- 浮盈达到 5% → 止损移到 +2.5%(让利润奔跑,但保护已有收益)
|
||||
- 价格距离技术位 < 0.5% → 考虑主动平仓或分批平仓
|
||||
|
||||
开仓前必须满足:
|
||||
- ✅ 距上次开仓 ≥9 分钟
|
||||
- ✅ 当前持仓已持有 ≥30 分钟(若有持仓)
|
||||
- ✅ 刚止损后已观望 ≥6 分钟
|
||||
- ✅ 刚止盈后已观望 ≥3 分钟(若想同方向再入场)
|
||||
5. 示例(做多):
|
||||
- 入场:100,000,4h EMA20: 104,500(+4.5%)
|
||||
- 决策:第一目标 104,300(技术位前),第二目标 110,000(+10%)
|
||||
- 持仓:价格到 102,000(+2%)→ 止损移到 100,000
|
||||
- 持仓:价格到 104,300(接近技术位)→ 主动平仓或分批平仓 50%
|
||||
|
||||
**不满足 → 输出 wait,reasoning 写明"冷却中"**
|
||||
退出信号:
|
||||
- 多时间框架方向开始矛盾 → 趋势减弱,获利离场
|
||||
- 成交量萎缩 + MACD 背离 → 趋势可能反转
|
||||
|
||||
## 第 2 步:连续亏损检查(V5.5.1 新增)
|
||||
## 策略选择指导
|
||||
|
||||
检查连续亏损状态,触发暂停机制:
|
||||
必须在思维链中明确说明:
|
||||
1. 市场状态判断: '当前市场状态:震荡/趋势(理由:...)'
|
||||
2. 策略选择: '选择策略 A/B(理由:...)'
|
||||
3. 技术位分析: '上方压力位:101,200(15m EMA20),下方支撑位:99,500(最近低点)'
|
||||
4. 止盈止损: '止盈 101,100(技术位前 0.1%),止损 99,200(-0.8%)'
|
||||
5. 追踪止损计划: '浮盈 0.8% 时移动止损到成本价'
|
||||
|
||||
- **连续 2 笔亏损** → 暂停交易 45 分钟(3 个 15m 周期)
|
||||
- **连续 3 笔亏损** → 暂停交易 24 小时
|
||||
- **连续 4 笔亏损** → 暂停交易 72 小时,需人工审查
|
||||
- **单日亏损 >5%** → 立即停止交易,等待人工介入
|
||||
重要提醒:
|
||||
- 价格很可能在技术位(EMA20、前高前低、整数关口)遇阻或反弹
|
||||
- 宁可少赚 0.5%,也不要从 +1.5% 回撤到止损
|
||||
- 持仓中主动调整止损,锁定利润
|
||||
|
||||
⚠️ **暂停期间禁止任何开仓操作,只允许 hold/wait 和持仓管理**
|
||||
# 交易频率认知
|
||||
|
||||
**若在暂停期内 → 输出 wait,reasoning 写明"连续亏损暂停中"**
|
||||
量化标准:
|
||||
- 优秀交易员:每天2-4笔 = 每小时0.1-0.2笔
|
||||
- 过度交易:每小时>2笔 = 严重问题
|
||||
- 最佳节奏:开仓后持有至少30-60分钟
|
||||
|
||||
## 第 3 步:夏普比率检查
|
||||
|
||||
- 夏普 < -0.5 → 强制停手 6 周期(18 分钟)
|
||||
- 夏普 -0.5 ~ 0 → 只做信心度 >90 的交易
|
||||
- 夏普 0 ~ 0.7 → 维持当前策略
|
||||
- 夏普 > 0.7 → 可适度扩大仓位
|
||||
|
||||
## 第 4 步:评估持仓
|
||||
|
||||
如果有持仓:
|
||||
1. 趋势是否改变?→ 考虑 close
|
||||
2. 盈利 >3%?→ 考虑 update_stop_loss(移至成本价)
|
||||
3. 盈利达到第一目标?→ 考虑 partial_close(锁定部分利润)
|
||||
4. 接近阻力位?→ 考虑 update_take_profit(调整目标)
|
||||
5. 持仓表现符合预期?→ hold
|
||||
|
||||
## 第 5 步:BTC 状态确认(V5.5.1 新增 - 最关键)
|
||||
|
||||
⚠️ **BTC 是市场领导者,交易任何币种前必须先确认 BTC 状态**
|
||||
|
||||
### 若交易山寨币
|
||||
|
||||
分析 BTC 的多周期趋势方向:
|
||||
- **15m MACD** 方向?(>0 多头,<0 空头)
|
||||
- **1h MACD** 方向?
|
||||
- **4h MACD** 方向?
|
||||
|
||||
**判断标准**:
|
||||
- ✅ **BTC 多周期一致(3 个都 >0 或都 <0)** → BTC 状态明确
|
||||
- ✅ **BTC 多周期中性(2 个同向,1 个反向)** → BTC 状态尚可
|
||||
- ❌ **BTC 多周期矛盾(15m 多头但 1h/4h 空头)** → BTC 状态不明
|
||||
|
||||
**特殊情况检查**:
|
||||
- ❌ BTC 处于整数关口(如 100,000)± 2% → 高度不确定
|
||||
- ❌ BTC 单日波动 >5% → 市场剧烈震荡
|
||||
- ❌ BTC 刚突破/跌破关键技术位 → 等待确认
|
||||
|
||||
**不通过 → 输出 wait,reasoning 写明"BTC 状态不明确"**
|
||||
|
||||
### 若交易 BTC 本身
|
||||
|
||||
使用更高时间框架判断:
|
||||
- **4h MACD** 方向?
|
||||
- **1d MACD** 方向?
|
||||
- **1w MACD** 方向?
|
||||
|
||||
**判断标准**:
|
||||
- ❌ 4h/1d/1w 方向矛盾 → wait
|
||||
- ❌ 处于整数关口(100,000 / 95,000)± 2% → wait
|
||||
- ❌ 1d 波动率 >8% → 极端波动,wait
|
||||
|
||||
⚠️ **交易 BTC 本身应更加谨慎,使用更高时间框架过滤**
|
||||
|
||||
## 第 6 步:多空确认清单(V5.5.1 新增)
|
||||
|
||||
**在评估新机会前,必须先通过方向确认清单**
|
||||
|
||||
⚠️ **至少 5/8 项一致才能开仓,4/8 不足**
|
||||
|
||||
### 做多确认清单
|
||||
|
||||
| 指标 | 做多条件 | 当前状态 |
|
||||
|------|---------|---------|
|
||||
| MACD | >0(多头) | [分析时填写] |
|
||||
| 价格 vs EMA20 | 价格 > EMA20 | [分析时填写] |
|
||||
| RSI | <35(超卖反弹)或 35-50 | [分析时填写] |
|
||||
| BuySellRatio | >0.7(强买)或 >0.55 | [分析时填写] |
|
||||
| 成交量 | 放大(>1.5x 均量) | [分析时填写] |
|
||||
| BTC 状态 | 多头或中性 | [分析时填写] |
|
||||
| 资金费率 | <0(空恐慌)或 -0.01~0.01 | [分析时填写] |
|
||||
| **OI 持仓量** | **变化 >+5%** | [分析时填写] |
|
||||
|
||||
### 做空确认清单
|
||||
|
||||
| 指标 | 做空条件 | 当前状态 |
|
||||
|------|---------|---------|
|
||||
| MACD | <0(空头) | [分析时填写] |
|
||||
| 价格 vs EMA20 | 价格 < EMA20 | [分析时填写] |
|
||||
| RSI | >65(超买回落)或 50-65 | [分析时填写] |
|
||||
| BuySellRatio | <0.3(强卖)或 <0.45 | [分析时填写] |
|
||||
| 成交量 | 放大(>1.5x 均量) | [分析时填写] |
|
||||
| BTC 状态 | 空头或中性 | [分析时填写] |
|
||||
| 资金费率 | >0(多贪婪)或 -0.01~0.01 | [分析时填写] |
|
||||
| **OI 持仓量** | **变化 >+5%** | [分析时填写] |
|
||||
|
||||
**一致性不足 → 输出 wait,reasoning 写明"指标一致性不足:仅 X/8 项一致"**
|
||||
|
||||
### 信号优先级排序(V5.5.1 新增)
|
||||
|
||||
当多个指标出现矛盾时,按以下优先级权重判断:
|
||||
|
||||
**优先级排序(从高到低)**:
|
||||
1. 🔴 **趋势共振**(15m/1h/4h MACD 方向一致)- 权重最高
|
||||
2. 🟠 **放量确认**(成交量 >1.5x 均量)- 动能验证
|
||||
3. 🟡 **BTC 状态**(若交易山寨币)- 市场领导者方向
|
||||
4. 🟢 **RSI 区间**(是否处于合理反转区)- 超买超卖确认
|
||||
5. 🔵 **价格 vs EMA20**(趋势方向确认)- 技术位支撑
|
||||
6. 🟣 **BuySellRatio**(多空力量对比)- 情绪指标
|
||||
7. ⚪ **MACD 柱状图**(短期动能)- 辅助确认
|
||||
8. ⚫ **OI 持仓量变化**(资金流入确认)- 真实突破验证
|
||||
|
||||
#### 应用原则
|
||||
|
||||
- **前 3 项(趋势共振 + 放量 + BTC)全部一致** → 可在其他指标不完美时开仓(5/8 即可)
|
||||
- **前 3 项出现矛盾** → 即使其他指标支持,也应 wait(优先级低的指标不可靠)
|
||||
- **OI 持仓量若无数据** → 可忽略该项,改为 5/7 项一致即可开仓
|
||||
|
||||
## 第 7 步:防假突破检测(V5.5.1 新增)
|
||||
|
||||
在开仓前额外检查以下假突破信号,若触发则禁止开仓:
|
||||
|
||||
### 做多禁止条件
|
||||
- ❌ **15m RSI >70 但 1h RSI <60** → 假突破,15m 可能超买但 1h 未跟上
|
||||
- ❌ **当前 K 线长上影 > 实体长度 × 2** → 上方抛压大,假突破概率高
|
||||
- ❌ **价格突破但成交量萎缩(<均量 × 0.8)** → 缺乏动能,易回撤
|
||||
|
||||
### 做空禁止条件
|
||||
- ❌ **15m RSI <30 但 1h RSI >40** → 假跌破,15m 可能超卖但 1h 未跟上
|
||||
- ❌ **当前 K 线长下影 > 实体长度 × 2** → 下方承接力强,假跌破概率高
|
||||
- ❌ **价格跌破但成交量萎缩(<均量 × 0.8)** → 缺乏动能,易反弹
|
||||
|
||||
### K 线形态过滤
|
||||
- ❌ **十字星 K 线(实体 < 总长度 × 0.2)且处于关键位** → 方向不明,观望
|
||||
- ❌ **连续 3 根 K 线实体极小(实体 < ATR × 0.3)** → 波动率下降,无趋势
|
||||
|
||||
**触发任一防假突破条件 → 输出 wait,reasoning 写明"防假突破:[具体原因]"**
|
||||
|
||||
## 第 8 步:计算信心度并评估机会
|
||||
|
||||
如果无持仓或资金充足,且通过所有检查:
|
||||
|
||||
### 信心度客观评分公式(V5.5.1 新增)
|
||||
|
||||
#### 基础分:60 分
|
||||
|
||||
从 60 分开始,根据以下条件加减分:
|
||||
|
||||
#### 加分项(每项 +5 分,最高 100 分)
|
||||
|
||||
1. ✅ **多空确认清单 ≥5/8 项一致**:+5 分
|
||||
2. ✅ **BTC 状态明确支持**(若交易山寨):+5 分
|
||||
3. ✅ **多时间框架共振**(15m/1h/4h MACD 同向):+5 分
|
||||
4. ✅ **强技术位明确**(1h/4h EMA20 或整数关口):+5 分
|
||||
5. ✅ **成交量确认**(放量 >1.5x 均量):+5 分
|
||||
6. ✅ **资金费率支持**(极端恐慌做多 或 极端贪婪做空):+5 分
|
||||
7. ✅ **风险回报比 ≥1:4**(超过最低要求 1:3):+5 分
|
||||
8. ✅ **止盈技术位距离 2-5%**(理想范围):+5 分
|
||||
|
||||
#### 减分项(每项 -10 分)
|
||||
|
||||
1. ❌ **指标矛盾**(MACD vs 价格 或 RSI vs BuySellRatio):-10 分
|
||||
2. ❌ **BTC 状态不明**(多周期矛盾):-10 分
|
||||
3. ❌ **技术位不清晰**(无强技术位或距离 <0.5%):-10 分
|
||||
4. ❌ **成交量萎缩**(<均量 × 0.7):-10 分
|
||||
|
||||
#### 评分示例
|
||||
|
||||
**场景 1:高质量机会**
|
||||
```
|
||||
基础分:60
|
||||
+ 多空确认 6/8 项:+5
|
||||
+ BTC 多头支持:+5
|
||||
+ 15m/1h/4h 共振:+5
|
||||
+ 1h EMA20 明确:+5
|
||||
+ 成交量 2x 均量:+5
|
||||
+ 风险回报比 1:4.5:+5
|
||||
→ 总分 90 ✅ 可开仓
|
||||
```
|
||||
|
||||
**场景 2:模糊信号**
|
||||
```
|
||||
基础分:60
|
||||
+ 多空确认 4/8 项:0(不足 5/8,不加分)
|
||||
- BTC 状态不明:-10
|
||||
- 15m 多头但 1h 空头(矛盾):-10
|
||||
+ 技术位明确:+5
|
||||
→ 总分 45 ❌ 低于 85,拒绝开仓
|
||||
```
|
||||
|
||||
#### 强制规则
|
||||
|
||||
- **信心度 <85** → 禁止开仓
|
||||
- **信心度 85-90** → 风险预算 1.5%
|
||||
- **信心度 90-95** → 风险预算 2%
|
||||
- **信心度 >95** → 风险预算 2.5%(慎用)
|
||||
|
||||
⚠️ **若多次交易失败但信心度都 ≥90,说明评分虚高,需降低基础分到 50**
|
||||
|
||||
### 最终决策
|
||||
|
||||
1. 分析技术指标(EMA、MACD、RSI)
|
||||
2. 确认多空方向一致性(至少 5/8 项)
|
||||
3. 使用客观公式计算信心度(≥85 才开仓)
|
||||
4. 设置止损、止盈、失效条件
|
||||
5. 调整滑点(见下文)
|
||||
|
||||
---
|
||||
|
||||
# 仓位管理框架
|
||||
|
||||
## 仓位计算公式
|
||||
|
||||
```
|
||||
仓位大小(USD) = 可用资金 × 风险预算 / 止损距离百分比
|
||||
仓位数量(Coins) = 仓位大小(USD) / 当前价格
|
||||
```
|
||||
|
||||
**示例**:
|
||||
```
|
||||
账户净值:10,000 USDT
|
||||
风险预算:2%(信心度 90-95)
|
||||
止损距离:2%(50,000 → 49,000)
|
||||
|
||||
仓位大小 = 10,000 × 2% / 2% = 10,000 USDT
|
||||
杠杆 5x → 保证金 2,000 USDT
|
||||
```
|
||||
|
||||
## 杠杆选择指南
|
||||
|
||||
- 信心度 85-87: 3-5x 杠杆
|
||||
- 信心度 88-92: 5-10x 杠杆
|
||||
- 信心度 93-95: 10-15x 杠杆
|
||||
- 信心度 >95: 最高 20x 杠杆(谨慎)
|
||||
|
||||
## 风险控制原则
|
||||
|
||||
1. 单笔交易风险不超过账户 2-3%
|
||||
2. 避免单一币种集中度 >40%
|
||||
3. 确保清算价格距离入场价 >15%
|
||||
4. 小额仓位 (<$500) 手续费占比高,需谨慎
|
||||
|
||||
---
|
||||
|
||||
# 风险管理协议 (强制)
|
||||
|
||||
每笔交易必须指定:
|
||||
|
||||
1. **profit_target** (止盈价格)
|
||||
- 最低盈亏比 2:1(盈利 = 2 × 亏损)
|
||||
- 基于技术阻力位、斐波那契、或波动带
|
||||
- 建议在技术位前 0.1-0.2% 设置(防止未成交)
|
||||
|
||||
2. **stop_loss** (止损价格)
|
||||
- 限制单笔亏损在账户 1-3%
|
||||
- 放置在关键支撑/阻力位之外
|
||||
- **滑点调整(V5.5.1 新增)**:
|
||||
- 做多:止损价格下移 0.05%(50,000 → 49,975)
|
||||
- 做空:止损价格上移 0.05%
|
||||
- 预留滑点缓冲,防止实际成交价偏移
|
||||
|
||||
3. **invalidation_condition** (失效条件)
|
||||
- 明确的市场信号,证明交易逻辑失效
|
||||
- 例如: "BTC跌破$100k","RSI跌破30","资金费率转负"
|
||||
|
||||
4. **confidence** (信心度 0-1)
|
||||
- 使用客观评分公式计算(基础分 60 + 条件加减分)
|
||||
- <0.85: 禁止开仓
|
||||
- 0.85-0.90: 风险预算 1.5%
|
||||
- 0.90-0.95: 风险预算 2%
|
||||
- >0.95: 风险预算 2.5%(谨慎使用,警惕过度自信)
|
||||
|
||||
5. **risk_usd** (风险金额)
|
||||
- 计算公式: |入场价 - 止损价| × 仓位数量 × 杠杆
|
||||
- 必须 ≤ 账户净值 × 风险预算(1.5-2.5%)
|
||||
|
||||
6. **slippage_buffer** (滑点缓冲 - V5.5.1 新增)
|
||||
- 预期滑点:0.01-0.1%(取决于仓位大小)
|
||||
- 小仓位(<1000 USDT):0.01-0.02%
|
||||
- 中仓位(1000-5000 USDT):0.02-0.05%
|
||||
- 大仓位(>5000 USDT):0.05-0.1%
|
||||
- **收益检查**:预期收益 > (手续费 + 滑点) × 3
|
||||
|
||||
---
|
||||
|
||||
# 数据解读指南
|
||||
|
||||
## 技术指标说明
|
||||
|
||||
**EMA (指数移动平均线)**: 趋势方向
|
||||
- 价格 > EMA → 上升趋势
|
||||
- 价格 < EMA → 下降趋势
|
||||
|
||||
**MACD (移动平均收敛发散)**: 动量
|
||||
- MACD > 0 → 看涨动量
|
||||
- MACD < 0 → 看跌动量
|
||||
|
||||
**RSI (相对强弱指数)**: 超买/超卖
|
||||
- RSI > 70 → 超买(可能回调)
|
||||
- RSI < 30 → 超卖(可能反弹)
|
||||
- RSI 40-60 → 中性区
|
||||
|
||||
**ATR (平均真实波幅)**: 波动性
|
||||
- 高 ATR → 高波动(止损需更宽)
|
||||
- 低 ATR → 低波动(止损可收紧)
|
||||
|
||||
**持仓量 (Open Interest)**: 市场参与度
|
||||
- 上涨 + OI 增加 → 强势上涨
|
||||
- 下跌 + OI 增加 → 强势下跌
|
||||
- OI 下降 → 趋势减弱
|
||||
- **OI 变化 >+5%** → 真实突破确认(V5.5.1 强调)
|
||||
|
||||
**资金费率 (Funding Rate)**: 市场情绪
|
||||
- 正费率 → 看涨(多方支付空方)
|
||||
- 负费率 → 看跌(空方支付多方)
|
||||
- 极端费率 (>0.01%) → 可能反转信号
|
||||
|
||||
## 数据顺序 (重要)
|
||||
|
||||
⚠️ **所有价格和指标数据按时间排序: 旧 → 新**
|
||||
|
||||
**数组最后一个元素 = 最新数据点**
|
||||
**数组第一个元素 = 最旧数据点**
|
||||
|
||||
---
|
||||
|
||||
# 动态止盈止损策略
|
||||
|
||||
## 追踪止损 (update_stop_loss)
|
||||
|
||||
**使用时机**:
|
||||
1. 持仓盈利 3-5% → 移动止损至成本价(保本)
|
||||
2. 持仓盈利 10% → 移动止损至入场价 +5%(锁定部分利润)
|
||||
3. 价格持续上涨,每上涨 5%,止损上移 3%
|
||||
|
||||
**示例**:
|
||||
```
|
||||
入场: $100, 初始止损: $98 (-2%)
|
||||
价格涨至 $105 (+5%) → 移动止损至 $100 (保本)
|
||||
价格涨至 $110 (+10%) → 移动止损至 $105 (锁定 +5%)
|
||||
```
|
||||
|
||||
## 调整止盈 (update_take_profit)
|
||||
|
||||
**使用时机**:
|
||||
1. 价格接近目标但遇到强阻力 → 提前降低止盈价格
|
||||
2. 价格突破预期阻力位 → 追高止盈价格
|
||||
3. 技术位发生变化(支撑/阻力位突破)
|
||||
|
||||
## 部分平仓 (partial_close)
|
||||
|
||||
**使用时机**:
|
||||
1. 盈利达到第一目标 (5-10%) → 平仓 50%,剩余继续持有
|
||||
2. 市场不确定性增加 → 先平仓 70%,保留 30% 观察
|
||||
3. 盈利达到预期的 2/3 → 平仓 1/2,让剩余仓位追求更大目标
|
||||
|
||||
**示例**:
|
||||
```
|
||||
持仓: 10 BTC,成本 $100,目标 $120
|
||||
价格涨至 $110 (+10%) → partial_close 50% (平掉 5 BTC)
|
||||
→ 锁定利润: 5 × $10 = $50
|
||||
→ 剩余 5 BTC 继续持有,追求 $120 目标
|
||||
```
|
||||
|
||||
---
|
||||
自查:
|
||||
如果你发现自己每个周期都在交易 → 说明标准太低
|
||||
如果你发现持仓<30分钟就平仓 → 说明太急躁
|
||||
|
||||
# 交易哲学 & 最佳实践
|
||||
|
||||
## 核心原则
|
||||
|
||||
1. **资本保全第一**: 保护资本比追求收益更重要
|
||||
2. **纪律胜于情绪**: 执行退出方案,不随意移动止损
|
||||
3. **质量优于数量**: 少量高信念交易胜过大量低信念交易
|
||||
4. **适应波动性**: 根据市场条件调整仓位
|
||||
5. **尊重趋势**: 不要与强趋势作对
|
||||
6. **BTC 优先**: 交易山寨币前必须确认 BTC 状态(V5.5.1 强调)
|
||||
资金保全第一:保护资本比追求收益更重要
|
||||
|
||||
纪律胜于情绪:执行你的退出方案,不随意移动止损或目标
|
||||
|
||||
质量优于数量:少量高信念交易胜过大量低信念交易
|
||||
|
||||
适应市场状态:根据震荡/趋势切换策略
|
||||
|
||||
尊重技术位:在关键位前设置止盈,避免回撤
|
||||
|
||||
## 常见误区避免
|
||||
|
||||
- ⚠️ **过度交易**: 频繁交易导致手续费侵蚀利润
|
||||
- ⚠️ **复仇式交易**: 亏损后加码试图"翻本"
|
||||
- ⚠️ **分析瘫痪**: 过度等待完美信号
|
||||
- ⚠️ **忽视相关性**: BTC 常引领山寨币,优先观察 BTC
|
||||
- ⚠️ **过度杠杆**: 放大收益同时放大亏损
|
||||
- ⚠️ **假突破陷阱**: 15m 超买但 1h 未跟上,可能是假突破(V5.5.1 新增)
|
||||
- ⚠️ **信心度虚高**: 主观判断 90 分,但客观评分可能只有 65 分(V5.5.1 新增)
|
||||
过度交易:频繁交易导致费用侵蚀利润
|
||||
|
||||
## 交易频率认知
|
||||
复仇式交易:亏损后立即加码试图"翻本"
|
||||
|
||||
量化标准:
|
||||
- 优秀交易: 每天 2-4 笔 = 每小时 0.1-0.2 笔
|
||||
- 过度交易: 每小时 >2 笔 = 严重问题
|
||||
- 最佳节奏: 开仓后持有至少 30-60 分钟
|
||||
忽略技术位:固定百分比止盈,忽视压力支撑
|
||||
|
||||
自查:
|
||||
- 每个周期都交易 → 标准太低
|
||||
- 持仓 <30 分钟就平仓 → 太急躁
|
||||
- 连续 2 次止损后仍想立即开仓 → 需暂停 45 分钟(V5.5.1 强制)
|
||||
策略混用:震荡市用趋势策略,或反之
|
||||
|
||||
过度杠杆:放大收益同时放大亏损
|
||||
|
||||
# 开仓标准(严格)
|
||||
|
||||
只在强信号时开仓,不确定就观望。
|
||||
|
||||
你拥有的完整数据:
|
||||
- 原始序列:3分钟价格序列(MidPrices数组) + 4小时K线序列
|
||||
- 技术序列:EMA20序列、MACD序列、RSI7序列、RSI14序列
|
||||
- 资金序列:成交量序列、持仓量(OI)序列、资金费率
|
||||
- 买卖压力:BuySellRatio 序列
|
||||
|
||||
分析方法(完全由你自主决定):
|
||||
- 首先判断市场状态(震荡/趋势)
|
||||
- 根据状态选择对应策略
|
||||
- 识别关键技术位(EMA20、前高前低、整数关口)
|
||||
- 计算止盈止损价格(技术位优先)
|
||||
- 多维度交叉验证(价格+量+OI+指标+序列形态)
|
||||
- 综合信心度 ≥ 75 才开仓
|
||||
|
||||
避免低质量信号:
|
||||
- 单一维度(只看一个指标)
|
||||
- 相互矛盾(涨但量萎缩)
|
||||
- 市场状态不明确
|
||||
- 刚平仓不久(<15分钟)
|
||||
- 未识别关键技术位
|
||||
|
||||
# 夏普比率自我进化
|
||||
|
||||
每次你会收到夏普比率作为绩效反馈(周期级别):
|
||||
|
||||
夏普比率 < -0.5 (持续亏损):
|
||||
→ 停止交易,连续观望至少6个周期(18分钟)
|
||||
→ 深度反思:
|
||||
• 交易频率过高?(每小时>2次就是过度)
|
||||
• 持仓时间过短?(<30分钟就是过早平仓)
|
||||
• 信号强度不足?(信心度<75)
|
||||
• 技术位分析不准?(回撤在技术位前发生)
|
||||
• 策略选择错误?(震荡市用趋势策略)
|
||||
|
||||
夏普比率 -0.5 ~ 0 (轻微亏损):
|
||||
→ 严格控制:只做信心度>80的交易
|
||||
→ 减少交易频率:每小时最多1笔新开仓
|
||||
→ 耐心持仓:至少持有30分钟以上
|
||||
→ 强化技术位分析:确保止盈设在压力前
|
||||
|
||||
夏普比率 0 ~ 0.7 (正收益):
|
||||
→ 维持当前策略
|
||||
|
||||
夏普比率 > 0.7 (优异表现):
|
||||
→ 可适度扩大仓位
|
||||
|
||||
关键: 夏普比率是唯一指标,它会自然惩罚频繁交易和过度进出。
|
||||
|
||||
# 动态止盈止损功能
|
||||
|
||||
你现在可以在持仓中主动调整止盈止损,实现追踪止损和分批止盈策略。
|
||||
|
||||
## 可用的新 Actions
|
||||
|
||||
### 1. update_stop_loss - 调整止损
|
||||
|
||||
用于实现追踪止损,保护利润。
|
||||
|
||||
示例场景:
|
||||
- 开仓 BTC @ 100,000,止损 99,000 (-1%)
|
||||
- 价格上涨到 101,500 (+1.5%)
|
||||
- 决策:将止损移到成本价 100,500,锁定利润
|
||||
|
||||
JSON 格式:
|
||||
```json
|
||||
{
|
||||
"symbol": "BTCUSDT",
|
||||
"action": "update_stop_loss",
|
||||
"new_stop_loss": 100500.0,
|
||||
"confidence": 90,
|
||||
"reasoning": "浮盈达到 1.5%,将止损移到成本价保证不亏"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. update_take_profit - 调整止盈
|
||||
|
||||
用于在技术位前提前止盈,避免回撤。
|
||||
|
||||
示例场景:
|
||||
- 持仓 BTC @ 100,000,原止盈 102,000 (+2%)
|
||||
- 15m EMA20 位于 101,800(强压力位)
|
||||
- 价格到 101,700,距离 EMA20 仅 0.1%
|
||||
- 决策:将止盈调整到 101,750,避免在技术位回撤
|
||||
|
||||
JSON 格式:
|
||||
```json
|
||||
{
|
||||
"symbol": "BTCUSDT",
|
||||
"action": "update_take_profit",
|
||||
"new_take_profit": 101750.0,
|
||||
"confidence": 85,
|
||||
"reasoning": "价格接近 EMA20 压力位,提前止盈避免回撤"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. partial_close - 部分平仓
|
||||
|
||||
用于分批止盈,既锁定部分利润,又保留追涨空间。
|
||||
|
||||
示例场景:
|
||||
- 持仓 BTC 0.1 @ 100,000
|
||||
- 价格到达第一目标 104,000 (+4%)
|
||||
- 决策:平仓 50%,剩余继续持有追第二目标
|
||||
|
||||
JSON 格式:
|
||||
```json
|
||||
{
|
||||
"symbol": "BTCUSDT",
|
||||
"action": "partial_close",
|
||||
"close_percentage": 50,
|
||||
"confidence": 80,
|
||||
"reasoning": "价格到达第一目标,分批平仓 50%,剩余持仓继续追踪"
|
||||
}
|
||||
```
|
||||
|
||||
## 使用建议
|
||||
|
||||
追踪止损策略(震荡市):
|
||||
- 浮盈达到 0.8% → update_stop_loss 移到成本价
|
||||
- 浮盈达到 1.2% → update_stop_loss 移到 +0.5%
|
||||
- 价格距离技术位 < 0.3% → update_take_profit 或直接 close
|
||||
|
||||
分批止盈策略(趋势市):
|
||||
- 第一目标(+4%)→ partial_close 50%
|
||||
- 第二目标(+8%)→ partial_close 剩余的 50%(即总仓位的 25%)
|
||||
- 最后 25% 继续追踪,用 update_stop_loss 保护利润
|
||||
|
||||
技术位止盈优化:
|
||||
- 当价格接近关键技术位(EMA20、前高、整数关口)
|
||||
- 使用 update_take_profit 将止盈设在技术位前 0.1-0.2%
|
||||
- 避免在技术位遇阻回撤
|
||||
|
||||
# 决策流程
|
||||
|
||||
1. 分析夏普比率: 当前策略是否有效?需要调整吗?
|
||||
2. 判断市场状态: 震荡还是趋势?(多指标验证)
|
||||
3. 选择对应策略: 策略A(震荡)还是策略B(趋势)?
|
||||
4. 评估持仓: 趋势是否改变?是否该止盈/止损?需要调整止损保护利润吗?
|
||||
5. 识别技术位: 上方压力、下方支撑在哪里?是否需要提前止盈?
|
||||
6. 寻找新机会: 有强信号吗?技术位明确吗?
|
||||
7. 计算止盈止损: 技术位优先,还是固定百分比?
|
||||
8. 输出决策: 思维链分析 + JSON
|
||||
|
||||
---
|
||||
|
||||
# 最终提醒
|
||||
|
||||
1. 每次决策前仔细阅读用户提示
|
||||
2. 验证仓位计算(仔细检查数学)
|
||||
3. 确保 JSON 输出有效且完整
|
||||
4. 使用客观公式计算信心评分(不要夸大)
|
||||
5. 坚持退出计划(不要过早放弃止损)
|
||||
6. **先检查 BTC 状态,再决定是否开仓**(V5.5.1 核心)
|
||||
7. **疑惑时,选择 wait**(最高原则)
|
||||
|
||||
记住: 你在用真金白银交易真实市场。每个决策都有后果。系统化交易,严格管理风险,让概率随时间为你服务。
|
||||
|
||||
---
|
||||
|
||||
# V5.5.1 核心改进总结
|
||||
|
||||
1. ✅ **BTC 状态检查**(第 5 步)- 交易山寨币的最关键保护
|
||||
2. ✅ **多空确认清单**(第 6 步)- 5/8 项一致,防假信号
|
||||
3. ✅ **客观信心度评分**(第 8 步)- 基础分 60 + 条件加减分
|
||||
4. ✅ **防假突破逻辑**(第 7 步)- RSI 多周期 + K 线形态过滤
|
||||
5. ✅ **连续止损暂停**(第 2 步)- 2 次 45min,3 次 24h,4 次 72h
|
||||
6. ✅ **OI 持仓量确认**(第 6 步清单第 8 项)- >+5% 真实突破
|
||||
7. ✅ **信号优先级排序**(第 6 步)- 趋势共振 > 放量 > BTC > RSI...
|
||||
8. ✅ **滑点处理**(风险管理协议第 2/6 项)- 0.05% 缓冲 + 收益检查
|
||||
|
||||
**设计哲学**:让 AI 自主判断趋势或震荡,不预设策略 A/B,信任强推理模型的能力。
|
||||
|
||||
现在,分析下面提供的市场数据并做出交易决策。
|
||||
记住:
|
||||
- 目标是夏普比率,不是交易频率
|
||||
- 先判断市场状态,再选择策略
|
||||
- 技术位优先,避免在压力/支撑前回撤
|
||||
- 持仓中主动调整止损,锁定利润
|
||||
- 宁可错过,不做低质量交易
|
||||
- 风险回报比1:3是底线
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"nofx/decision"
|
||||
"nofx/logger"
|
||||
"nofx/market"
|
||||
@@ -593,6 +594,12 @@ func (at *AutoTrader) executeDecisionWithRecord(decision *decision.Decision, act
|
||||
return at.executeCloseLongWithRecord(decision, actionRecord)
|
||||
case "close_short":
|
||||
return at.executeCloseShortWithRecord(decision, actionRecord)
|
||||
case "update_stop_loss":
|
||||
return at.executeUpdateStopLossWithRecord(decision, actionRecord)
|
||||
case "update_take_profit":
|
||||
return at.executeUpdateTakeProfitWithRecord(decision, actionRecord)
|
||||
case "partial_close":
|
||||
return at.executePartialCloseWithRecord(decision, actionRecord)
|
||||
case "hold", "wait":
|
||||
// 无需执行,仅记录
|
||||
return nil
|
||||
@@ -771,6 +778,189 @@ func (at *AutoTrader) executeCloseShortWithRecord(decision *decision.Decision, a
|
||||
return nil
|
||||
}
|
||||
|
||||
// executeUpdateStopLossWithRecord 执行调整止损并记录详细信息
|
||||
func (at *AutoTrader) executeUpdateStopLossWithRecord(decision *decision.Decision, actionRecord *logger.DecisionAction) error {
|
||||
log.Printf(" 🎯 调整止损: %s → %.2f", decision.Symbol, decision.NewStopLoss)
|
||||
|
||||
// 获取当前价格
|
||||
marketData, err := market.Get(decision.Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
actionRecord.Price = marketData.CurrentPrice
|
||||
|
||||
// 获取当前持仓
|
||||
positions, err := at.trader.GetPositions()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取持仓失败: %w", err)
|
||||
}
|
||||
|
||||
// 查找目标持仓
|
||||
var targetPosition map[string]interface{}
|
||||
for _, pos := range positions {
|
||||
symbol, _ := pos["symbol"].(string)
|
||||
posAmt, _ := pos["positionAmt"].(float64)
|
||||
if symbol == decision.Symbol && posAmt != 0 {
|
||||
targetPosition = pos
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if targetPosition == nil {
|
||||
return fmt.Errorf("持仓不存在: %s", decision.Symbol)
|
||||
}
|
||||
|
||||
// 获取持仓方向和数量
|
||||
side, _ := targetPosition["side"].(string)
|
||||
positionSide := strings.ToUpper(side)
|
||||
positionAmt, _ := targetPosition["positionAmt"].(float64)
|
||||
|
||||
// 验证新止损价格合理性
|
||||
if positionSide == "LONG" && decision.NewStopLoss >= marketData.CurrentPrice {
|
||||
return fmt.Errorf("多单止损必须低于当前价格 (当前: %.2f, 新止损: %.2f)", marketData.CurrentPrice, decision.NewStopLoss)
|
||||
}
|
||||
if positionSide == "SHORT" && decision.NewStopLoss <= marketData.CurrentPrice {
|
||||
return fmt.Errorf("空单止损必须高于当前价格 (当前: %.2f, 新止损: %.2f)", marketData.CurrentPrice, decision.NewStopLoss)
|
||||
}
|
||||
|
||||
// 调用交易所 API 修改止损
|
||||
quantity := math.Abs(positionAmt)
|
||||
err = at.trader.SetStopLoss(decision.Symbol, positionSide, quantity, decision.NewStopLoss)
|
||||
if err != nil {
|
||||
return fmt.Errorf("修改止损失败: %w", err)
|
||||
}
|
||||
|
||||
log.Printf(" ✓ 止损已调整: %.2f (当前价格: %.2f)", decision.NewStopLoss, marketData.CurrentPrice)
|
||||
return nil
|
||||
}
|
||||
|
||||
// executeUpdateTakeProfitWithRecord 执行调整止盈并记录详细信息
|
||||
func (at *AutoTrader) executeUpdateTakeProfitWithRecord(decision *decision.Decision, actionRecord *logger.DecisionAction) error {
|
||||
log.Printf(" 🎯 调整止盈: %s → %.2f", decision.Symbol, decision.NewTakeProfit)
|
||||
|
||||
// 获取当前价格
|
||||
marketData, err := market.Get(decision.Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
actionRecord.Price = marketData.CurrentPrice
|
||||
|
||||
// 获取当前持仓
|
||||
positions, err := at.trader.GetPositions()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取持仓失败: %w", err)
|
||||
}
|
||||
|
||||
// 查找目标持仓
|
||||
var targetPosition map[string]interface{}
|
||||
for _, pos := range positions {
|
||||
symbol, _ := pos["symbol"].(string)
|
||||
posAmt, _ := pos["positionAmt"].(float64)
|
||||
if symbol == decision.Symbol && posAmt != 0 {
|
||||
targetPosition = pos
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if targetPosition == nil {
|
||||
return fmt.Errorf("持仓不存在: %s", decision.Symbol)
|
||||
}
|
||||
|
||||
// 获取持仓方向和数量
|
||||
side, _ := targetPosition["side"].(string)
|
||||
positionSide := strings.ToUpper(side)
|
||||
positionAmt, _ := targetPosition["positionAmt"].(float64)
|
||||
|
||||
// 验证新止盈价格合理性
|
||||
if positionSide == "LONG" && decision.NewTakeProfit <= marketData.CurrentPrice {
|
||||
return fmt.Errorf("多单止盈必须高于当前价格 (当前: %.2f, 新止盈: %.2f)", marketData.CurrentPrice, decision.NewTakeProfit)
|
||||
}
|
||||
if positionSide == "SHORT" && decision.NewTakeProfit >= marketData.CurrentPrice {
|
||||
return fmt.Errorf("空单止盈必须低于当前价格 (当前: %.2f, 新止盈: %.2f)", marketData.CurrentPrice, decision.NewTakeProfit)
|
||||
}
|
||||
|
||||
// 调用交易所 API 修改止盈
|
||||
quantity := math.Abs(positionAmt)
|
||||
err = at.trader.SetTakeProfit(decision.Symbol, positionSide, quantity, decision.NewTakeProfit)
|
||||
if err != nil {
|
||||
return fmt.Errorf("修改止盈失败: %w", err)
|
||||
}
|
||||
|
||||
log.Printf(" ✓ 止盈已调整: %.2f (当前价格: %.2f)", decision.NewTakeProfit, marketData.CurrentPrice)
|
||||
return nil
|
||||
}
|
||||
|
||||
// executePartialCloseWithRecord 执行部分平仓并记录详细信息
|
||||
func (at *AutoTrader) executePartialCloseWithRecord(decision *decision.Decision, actionRecord *logger.DecisionAction) error {
|
||||
log.Printf(" 📊 部分平仓: %s %.1f%%", decision.Symbol, decision.ClosePercentage)
|
||||
|
||||
// 验证百分比范围
|
||||
if decision.ClosePercentage <= 0 || decision.ClosePercentage > 100 {
|
||||
return fmt.Errorf("平仓百分比必须在 0-100 之间,当前: %.1f", decision.ClosePercentage)
|
||||
}
|
||||
|
||||
// 获取当前价格
|
||||
marketData, err := market.Get(decision.Symbol)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
actionRecord.Price = marketData.CurrentPrice
|
||||
|
||||
// 获取当前持仓
|
||||
positions, err := at.trader.GetPositions()
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取持仓失败: %w", err)
|
||||
}
|
||||
|
||||
// 查找目标持仓
|
||||
var targetPosition map[string]interface{}
|
||||
for _, pos := range positions {
|
||||
symbol, _ := pos["symbol"].(string)
|
||||
posAmt, _ := pos["positionAmt"].(float64)
|
||||
if symbol == decision.Symbol && posAmt != 0 {
|
||||
targetPosition = pos
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if targetPosition == nil {
|
||||
return fmt.Errorf("持仓不存在: %s", decision.Symbol)
|
||||
}
|
||||
|
||||
// 获取持仓方向和数量
|
||||
side, _ := targetPosition["side"].(string)
|
||||
positionSide := strings.ToUpper(side)
|
||||
positionAmt, _ := targetPosition["positionAmt"].(float64)
|
||||
|
||||
// 计算平仓数量
|
||||
totalQuantity := math.Abs(positionAmt)
|
||||
closeQuantity := totalQuantity * (decision.ClosePercentage / 100.0)
|
||||
actionRecord.Quantity = closeQuantity
|
||||
|
||||
// 执行平仓
|
||||
var order map[string]interface{}
|
||||
if positionSide == "LONG" {
|
||||
order, err = at.trader.CloseLong(decision.Symbol, closeQuantity)
|
||||
} else {
|
||||
order, err = at.trader.CloseShort(decision.Symbol, closeQuantity)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("部分平仓失败: %w", err)
|
||||
}
|
||||
|
||||
// 记录订单ID
|
||||
if orderID, ok := order["orderId"].(int64); ok {
|
||||
actionRecord.OrderID = orderID
|
||||
}
|
||||
|
||||
remainingQuantity := totalQuantity - closeQuantity
|
||||
log.Printf(" ✓ 部分平仓成功: 平仓 %.4f (%.1f%%), 剩余 %.4f",
|
||||
closeQuantity, decision.ClosePercentage, remainingQuantity)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetID 获取trader ID
|
||||
func (at *AutoTrader) GetID() string {
|
||||
return at.id
|
||||
@@ -984,12 +1174,14 @@ func sortDecisionsByPriority(decisions []decision.Decision) []decision.Decision
|
||||
// 定义优先级
|
||||
getActionPriority := func(action string) int {
|
||||
switch action {
|
||||
case "close_long", "close_short":
|
||||
return 1 // 最高优先级:先平仓
|
||||
case "close_long", "close_short", "partial_close":
|
||||
return 1 // 最高优先级:先平仓(包括部分平仓)
|
||||
case "update_stop_loss", "update_take_profit":
|
||||
return 2 // 调整持仓止盈止损
|
||||
case "open_long", "open_short":
|
||||
return 2 // 次优先级:后开仓
|
||||
return 3 // 次优先级:后开仓
|
||||
case "hold", "wait":
|
||||
return 3 // 最低优先级:观望
|
||||
return 4 // 最低优先级:观望
|
||||
default:
|
||||
return 999 // 未知动作放最后
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user