Files
nofx/DYNAMIC_TP_SL_PROPOSAL.md
ZhouYongyou bac5744039 refactor: 移除 engine.go 冗餘硬編碼策略,優化模板系統
## 問題
用戶反饋:「怎麼 engine.go 還寫入了這些?... 有必要嗎?」

**根本原因**:
- prompts/ 目錄下已有 default.txt (114行) 和 adaptive.txt (259行)
- engine.go 卻硬編碼了 183 行 adaptive 策略作為 fallback
- 這導致:
  1. 重複維護兩份相同的策略內容
  2. templateLoaded 標記多餘(模板系統本身已有 fallback)
  3. 如果 default.txt 都加載失敗,說明文件系統有嚴重問題,不應繼續交易

## 解決方案

### 1. 移除冗餘硬編碼
- 刪除 183 行硬編碼 adaptive 策略(271-453 行)
- 移除 templateLoaded 標記及其邏輯

### 2. 簡化模板加載邏輯
```go
// 之前(複雜)
templateLoaded := false
if 模板加載成功 {
    templateLoaded = true
}
if !templateLoaded {
    追加 183 行硬編碼策略  //  冗餘
}

// 現在(簡潔)
if 用戶模板加載失敗 {
    嘗試 default.txt  //  已經是 fallback
}
if default.txt 也失敗 {
    返回空字符串,上層應停止交易  //  安全
}
```

### 3. 新增動態止盈止損設計文檔
創建 `DYNAMIC_TP_SL_PROPOSAL.md`,記錄:
- 用戶反饋:「建议加个 adjust tp sl 或者给 close 加个 quantity」
- 問題分析:策略提到追蹤止損,但 AI 無法執行
- 解決方案:添加 `adjust_stop_loss`, `adjust_take_profit`, `partial_close` actions
- 實施步驟:修改 Decision 結構、執行邏輯、模板說明

## 測試驗證
-  Go 編譯成功
-  Docker build 成功
-  模板系統邏輯清晰(用戶模板 → default → 報錯)
-  代碼減少 183 行(更易維護)

## 檔案變更
- `decision/engine.go`: -183 行硬編碼策略
- `DYNAMIC_TP_SL_PROPOSAL.md`: +300 行設計文檔

## 後續工作
- [ ] 實現 adjust_stop_loss action
- [ ] 實現 partial_close action
- [ ] 更新模板文件說明新 actions

---

感謝 @user 指出這個設計缺陷!🙏

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 01:18:57 +08:00

8.8 KiB
Raw Blame History

動態止盈止損功能設計方案

🔴 問題描述

用戶反饋

还有动态止盈止损我建议你给ai decisions里加个adjust tp sl 或者给close加个quantity 不然应该是没有作用

根本原因

  • 策略模板adaptive.txt提到"追蹤止損"功能:
    • 浮盈達到 0.8% → 止損移到成本價(保證不虧)
    • 浮盈達到 1.2% → 止損移到 +0.5%(鎖定一半利潤)
  • 但 AI 無法執行這些操作,因為 Decision 結構不支持
    • 調整現有持倉的止盈/止損
    • 部分平倉(分批止盈)

📊 當前限制

Decision 結構decision/engine.go:72-82

type Decision struct {
    Symbol          string  `json:"symbol"`
    Action          string  `json:"action"` // "open_long", "open_short", "close_long", "close_short", "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"`    // ⚠️ 只在開倉時有效
    Confidence      int     `json:"confidence,omitempty"`
    RiskUSD         float64 `json:"risk_usd,omitempty"`
    Reasoning       string  `json:"reasoning"`
}

當前支持的 Actions

  • open_long - 開多倉(有 stop_loss, take_profit
  • open_short - 開空倉(有 stop_loss, take_profit
  • close_long - 全部平多倉
  • close_short - 全部平空倉
  • hold - 持倉不動
  • wait - 觀望

解決方案

方案 A添加新的 Action Types推薦

1. adjust_stop_loss - 調整止損

{
  "symbol": "BTCUSDT",
  "action": "adjust_stop_loss",
  "new_stop_loss": 100500.0,
  "reasoning": "浮盈達到 1.5%,將止損移到成本價 (100500) 保證不虧"
}

2. adjust_take_profit - 調整止盈

{
  "symbol": "BTCUSDT",
  "action": "adjust_take_profit",
  "new_take_profit": 102000.0,
  "reasoning": "價格距離 EMA20 僅 0.3%,將止盈提前到 102000 避免回撤"
}

3. partial_close - 部分平倉

{
  "symbol": "BTCUSDT",
  "action": "partial_close",
  "close_percentage": 50,
  "reasoning": "價格到達第一目標 104300分批平倉 50%,剩餘持倉繼續追蹤"
}

方案 B修改現有 close action次選

close_long / close_short 添加 quantity 參數:

{
  "symbol": "BTCUSDT",
  "action": "close_long",
  "quantity": 0.5,  // 0.5 = 50%, 1.0 = 100%(預設)
  "reasoning": "部分止盈"
}

🛠️ 實施步驟

步驟 1修改 Decision 結構

文件: decision/engine.go

type Decision struct {
    Symbol          string  `json:"symbol"`
    Action          string  `json:"action"`
    // Actions: "open_long", "open_short", "close_long", "close_short",
    //          "adjust_stop_loss", "adjust_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"`
    RiskUSD         float64 `json:"risk_usd,omitempty"`
    Reasoning       string  `json:"reasoning"`
}

步驟 2實現 Action 執行邏輯

文件: trader/auto_trader.go 或新建 trader/position_manager.go

// 處理調整止損
func (t *AutoTrader) adjustStopLoss(symbol string, newStopLoss float64) error {
    // 1. 獲取當前持倉
    position := t.getPosition(symbol)
    if position == nil {
        return fmt.Errorf("持倉不存在")
    }

    // 2. 調用交易所 API 修改止損單
    err := t.exchange.ModifyStopLoss(symbol, position.OrderID, newStopLoss)
    if err != nil {
        return err
    }

    // 3. 更新本地持倉記錄
    position.StopLoss = newStopLoss

    log.Printf("✓ %s 止損已調整到 %.2f", symbol, newStopLoss)
    return nil
}

// 處理部分平倉
func (t *AutoTrader) partialClose(symbol string, percentage float64) error {
    // 1. 獲取當前持倉
    position := t.getPosition(symbol)
    if position == nil {
        return fmt.Errorf("持倉不存在")
    }

    // 2. 計算平倉數量
    closeQty := position.Quantity * (percentage / 100.0)

    // 3. 執行市價平倉
    err := t.exchange.ClosePosition(symbol, closeQty)
    if err != nil {
        return err
    }

    // 4. 更新本地持倉記錄
    position.Quantity -= closeQty

    log.Printf("✓ %s 部分平倉 %.1f%% (%.4f)", symbol, percentage, closeQty)
    return nil
}

步驟 3更新模板說明

文件: prompts/adaptive.txt

在輸出格式部分添加:

## 可用的 Actions

### 開倉
- `open_long` / `open_short` - 開倉(必須指定 leverage, position_size_usd, stop_loss, take_profit

### 平倉
- `close_long` / `close_short` - 全部平倉
- `partial_close` - 部分平倉(指定 close_percentage: 0-100

### 調整持倉
- `adjust_stop_loss` - 調整止損(指定 new_stop_loss
- `adjust_take_profit` - 調整止盈(指定 new_take_profit

### 觀望
- `hold` - 持倉不動
- `wait` - 觀望

## 追蹤止損範例

```json
[
  {
    "symbol": "BTCUSDT",
    "action": "adjust_stop_loss",
    "new_stop_loss": 100500,
    "confidence": 85,
    "reasoning": "浮盈達到 1.5%(目前價格 101500將止損移到成本價 100500保證不虧"
  }
]

部分止盈範例

[
  {
    "symbol": "BTCUSDT",
    "action": "partial_close",
    "close_percentage": 50,
    "confidence": 80,
    "reasoning": "價格到達第一目標 1043004h EMA20 前 0.2%),分批止盈 50%,剩餘倉位繼續持有"
  }
]

### 步驟 4更新交易邏輯主循環

**文件**: `trader/auto_trader.go` - `executeTrades()` 函數

```go
func (t *AutoTrader) executeTrades(decisions []decision.Decision) {
    for _, d := range decisions {
        switch d.Action {
        case "open_long", "open_short":
            t.openPosition(d)

        case "close_long", "close_short":
            t.closePosition(d.Symbol)

        case "adjust_stop_loss":
            t.adjustStopLoss(d.Symbol, d.NewStopLoss)

        case "adjust_take_profit":
            t.adjustTakeProfit(d.Symbol, d.NewTakeProfit)

        case "partial_close":
            t.partialClose(d.Symbol, d.ClosePercentage)

        case "hold", "wait":
            // 不操作

        default:
            log.Printf("⚠️  未知的 action: %s", d.Action)
        }
    }
}

🧪 測試驗證

測試用例 1追蹤止損

  1. 開多倉 BTCUSDT @ 100000止損 99000止盈 102000
  2. 價格上漲到 101500浮盈 1.5%
  3. AI 決策:adjust_stop_loss → 100500成本價
  4. 驗證:止損單已更新,即使回撤到 100500 也不會虧損

測試用例 2部分止盈

  1. 持倉 BTCUSDT 多單 0.1 BTC
  2. 價格到達第一目標 104300
  3. AI 決策:partial_close 50%
  4. 驗證:平倉 0.05 BTC剩餘 0.05 BTC 繼續持有

測試用例 3錯誤處理

  1. AI 決策:adjust_stop_loss 但持倉不存在
  2. 驗證:記錄錯誤,不影響其他決策

📈 預期效果

優化前(當前狀態)

  • AI 只能在開倉時設定止盈止損
  • 無法根據行情變化動態調整
  • "追蹤止損"策略無法執行

優化後

  • AI 可以根據浮盈動態移動止損
  • 可以分批止盈(第一目標平 50%,第二目標平剩餘)
  • 真正實現"讓利潤奔跑,限制虧損"
  • 提升夏普比率(減少回撤,鎖定利潤)

🔗 相關文件

  • decision/engine.go - Decision 結構定義
  • trader/auto_trader.go - 交易執行邏輯
  • prompts/adaptive.txt - 策略模板(提到追蹤止損)
  • prompts/default.txt - 基礎策略模板

⚠️ 風險提示

  1. 交易所 API 支持:需要確認 Binance/Hyperliquid 是否支持修改止損單
  2. 訂單管理:需要追蹤止損單的 orderID才能修改
  3. 錯誤處理:如果修改失敗,需要回退或重試
  4. 日誌記錄:所有調整操作都應該記錄到 decision_logger

優先級: 🔴 High - 這是實現追蹤止損策略的必要功能

預估工作量:

  • 修改 Decision 結構: 30 分鐘
  • 實現執行邏輯: 2-3 小時
  • 更新模板說明: 30 分鐘
  • 測試驗證: 1-2 小時
  • 總計: 4-6 小時

下一步: 等待用戶確認方案後開始實施