mirror of
https://github.com/laoxong/nofx.git
synced 2026-06-04 09:58:22 +08:00
6a66913194
* fix(decision): 添加槓桿超限 fallback 機制並澄清盈虧計算說明 1. AI 決策輸出超限槓桿時(如 20x),驗證直接拒絕導致整個交易週期失敗 2. Prompt 未明確說明盈虧百分比已包含槓桿效應,導致 AI 思維鏈中誤用價格變動% - **Before**: 超限直接報錯 → 決策失敗 - **After**: 自動降級為配置上限 → 決策繼續執行 - **效果**: SOLUSDT 20x → 自動修正為 5x(配置上限) - 明確告知 AI:系統提供的「盈虧%」已包含槓桿效應 - 公式: 盈虧% = (未實現盈虧 / 保證金) × 100 - 示例: 5x 槓桿,價格漲 2% = 實際盈利 10% - 測試山寨幣超限修正(20x → 5x) - 測試 BTC/ETH 超限修正(20x → 10x) - 測試正常範圍不修正 - 測試無效槓桿拒絕 ``` PASS: TestLeverageFallback/山寨币杠杆超限_自动修正为上限 PASS: TestLeverageFallback/BTC杠杆超限_自动修正为上限 PASS: TestLeverageFallback/杠杆在上限内_不修正 PASS: TestLeverageFallback/杠杆为0_应该报错 ``` - ✅ 向後兼容:正常槓桿範圍不受影響 - ✅ 容錯性增強:AI 輸出超限時系統自動修正 - ✅ 決策質量提升:AI 對槓桿收益有正確認知 Co-Authored-By: tinkle-community <tinklefund@gmail.com> * style: apply go fmt after rebase Co-Authored-By: tinkle-community <tinklefund@gmail.com> --------- Co-authored-by: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Co-authored-by: tinkle-community <tinklefund@gmail.com>
101 lines
2.5 KiB
Go
101 lines
2.5 KiB
Go
package decision
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
// TestLeverageFallback 测试杠杆超限时的自动修正功能
|
|
func TestLeverageFallback(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
decision Decision
|
|
accountEquity float64
|
|
btcEthLeverage int
|
|
altcoinLeverage int
|
|
wantLeverage int // 期望修正后的杠杆值
|
|
wantError bool
|
|
}{
|
|
{
|
|
name: "山寨币杠杆超限_自动修正为上限",
|
|
decision: Decision{
|
|
Symbol: "SOLUSDT",
|
|
Action: "open_long",
|
|
Leverage: 20, // 超过上限
|
|
PositionSizeUSD: 100,
|
|
StopLoss: 50,
|
|
TakeProfit: 200,
|
|
},
|
|
accountEquity: 100,
|
|
btcEthLeverage: 10,
|
|
altcoinLeverage: 5, // 上限 5x
|
|
wantLeverage: 5, // 应该修正为 5
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "BTC杠杆超限_自动修正为上限",
|
|
decision: Decision{
|
|
Symbol: "BTCUSDT",
|
|
Action: "open_long",
|
|
Leverage: 20, // 超过上限
|
|
PositionSizeUSD: 1000,
|
|
StopLoss: 90000,
|
|
TakeProfit: 110000,
|
|
},
|
|
accountEquity: 100,
|
|
btcEthLeverage: 10, // 上限 10x
|
|
altcoinLeverage: 5,
|
|
wantLeverage: 10, // 应该修正为 10
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "杠杆在上限内_不修正",
|
|
decision: Decision{
|
|
Symbol: "ETHUSDT",
|
|
Action: "open_short",
|
|
Leverage: 5, // 未超限
|
|
PositionSizeUSD: 500,
|
|
StopLoss: 4000,
|
|
TakeProfit: 3000,
|
|
},
|
|
accountEquity: 100,
|
|
btcEthLeverage: 10,
|
|
altcoinLeverage: 5,
|
|
wantLeverage: 5, // 保持不变
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "杠杆为0_应该报错",
|
|
decision: Decision{
|
|
Symbol: "SOLUSDT",
|
|
Action: "open_long",
|
|
Leverage: 0, // 无效
|
|
PositionSizeUSD: 100,
|
|
StopLoss: 50,
|
|
TakeProfit: 200,
|
|
},
|
|
accountEquity: 100,
|
|
btcEthLeverage: 10,
|
|
altcoinLeverage: 5,
|
|
wantLeverage: 0,
|
|
wantError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validateDecision(&tt.decision, tt.accountEquity, tt.btcEthLeverage, tt.altcoinLeverage)
|
|
|
|
// 检查错误状态
|
|
if (err != nil) != tt.wantError {
|
|
t.Errorf("validateDecision() error = %v, wantError %v", err, tt.wantError)
|
|
return
|
|
}
|
|
|
|
// 如果不应该报错,检查杠杆是否被正确修正
|
|
if !tt.wantError && tt.decision.Leverage != tt.wantLeverage {
|
|
t.Errorf("Leverage not corrected: got %d, want %d", tt.decision.Leverage, tt.wantLeverage)
|
|
}
|
|
})
|
|
}
|
|
}
|