diff --git a/decision/engine.go b/decision/engine.go index 14a6101b..21967df9 100644 --- a/decision/engine.go +++ b/decision/engine.go @@ -55,15 +55,17 @@ type OITopData struct { // Context 交易上下文(传递给AI的完整信息) type Context struct { - CurrentTime string `json:"current_time"` - RuntimeMinutes int `json:"runtime_minutes"` - CallCount int `json:"call_count"` - Account AccountInfo `json:"account"` - Positions []PositionInfo `json:"positions"` - CandidateCoins []CandidateCoin `json:"candidate_coins"` - MarketDataMap map[string]*market.Data `json:"-"` // 不序列化,但内部使用 - OITopDataMap map[string]*OITopData `json:"-"` // OI Top数据映射 - Performance interface{} `json:"-"` // 历史表现分析(logger.PerformanceAnalysis) + CurrentTime string `json:"current_time"` + RuntimeMinutes int `json:"runtime_minutes"` + CallCount int `json:"call_count"` + Account AccountInfo `json:"account"` + Positions []PositionInfo `json:"positions"` + CandidateCoins []CandidateCoin `json:"candidate_coins"` + MarketDataMap map[string]*market.Data `json:"-"` // 不序列化,但内部使用 + OITopDataMap map[string]*OITopData `json:"-"` // OI Top数据映射 + Performance interface{} `json:"-"` // 历史表现分析(logger.PerformanceAnalysis) + BTCETHLeverage int `json:"-"` // BTC/ETH杠杆倍数(从配置读取) + AltcoinLeverage int `json:"-"` // 山寨币杠杆倍数(从配置读取) } // Decision AI的交易决策 @@ -105,7 +107,7 @@ func GetFullDecision(ctx *Context) (*FullDecision, error) { } // 4. 解析AI响应 - decision, err := parseFullDecisionResponse(aiResponse, ctx.Account.TotalEquity) + decision, err := parseFullDecisionResponse(aiResponse, ctx.Account.TotalEquity, ctx.BTCETHLeverage, ctx.AltcoinLeverage) if err != nil { return nil, fmt.Errorf("解析AI响应失败: %w", err) } @@ -415,7 +417,7 @@ func buildUserPrompt(ctx *Context) string { } // parseFullDecisionResponse 解析AI的完整决策响应 -func parseFullDecisionResponse(aiResponse string, accountEquity float64) (*FullDecision, error) { +func parseFullDecisionResponse(aiResponse string, accountEquity float64, btcEthLeverage, altcoinLeverage int) (*FullDecision, error) { // 1. 提取思维链 cotTrace := extractCoTTrace(aiResponse) @@ -429,7 +431,7 @@ func parseFullDecisionResponse(aiResponse string, accountEquity float64) (*FullD } // 3. 验证决策 - if err := validateDecisions(decisions, accountEquity); err != nil { + if err := validateDecisions(decisions, accountEquity, btcEthLeverage, altcoinLeverage); err != nil { return &FullDecision{ CoTTrace: cotTrace, Decisions: decisions, @@ -496,10 +498,10 @@ func fixMissingQuotes(jsonStr string) string { return jsonStr } -// validateDecisions 验证所有决策(需要账户信息) -func validateDecisions(decisions []Decision, accountEquity float64) error { +// validateDecisions 验证所有决策(需要账户信息和杠杆配置) +func validateDecisions(decisions []Decision, accountEquity float64, btcEthLeverage, altcoinLeverage int) error { for i, decision := range decisions { - if err := validateDecision(&decision, accountEquity); err != nil { + if err := validateDecision(&decision, accountEquity, btcEthLeverage, altcoinLeverage); err != nil { return fmt.Errorf("决策 #%d 验证失败: %w", i+1, err) } } @@ -529,7 +531,7 @@ func findMatchingBracket(s string, start int) int { } // validateDecision 验证单个决策的有效性 -func validateDecision(d *Decision, accountEquity float64) error { +func validateDecision(d *Decision, accountEquity float64, btcEthLeverage, altcoinLeverage int) error { // 验证action validActions := map[string]bool{ "open_long": true, @@ -546,16 +548,16 @@ func validateDecision(d *Decision, accountEquity float64) error { // 开仓操作必须提供完整参数 if d.Action == "open_long" || d.Action == "open_short" { - // 根据币种判断杠杆上限和仓位价值上限 - maxLeverage := 20 // 山寨币固定20倍 + // 根据币种使用配置的杠杆上限 + maxLeverage := altcoinLeverage // 山寨币使用配置的杠杆 maxPositionValue := accountEquity * 1.5 // 山寨币最多1.5倍账户净值 if d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT" { - maxLeverage = 50 // BTC和ETH固定50倍 + maxLeverage = btcEthLeverage // BTC和ETH使用配置的杠杆 maxPositionValue = accountEquity * 10 // BTC/ETH最多10倍账户净值 } if d.Leverage <= 0 || d.Leverage > maxLeverage { - return fmt.Errorf("杠杆必须在1-%d之间(%s): %d", maxLeverage, d.Symbol, d.Leverage) + return fmt.Errorf("杠杆必须在1-%d之间(%s,当前配置上限%d倍): %d", maxLeverage, d.Symbol, maxLeverage, d.Leverage) } if d.PositionSizeUSD <= 0 { return fmt.Errorf("仓位大小必须大于0: %.2f", d.PositionSizeUSD) diff --git a/main.go b/main.go index b956209b..d1347535 100644 --- a/main.go +++ b/main.go @@ -64,6 +64,7 @@ func main() { cfg.MaxDailyLoss, cfg.MaxDrawdown, cfg.StopTradingMinutes, + cfg.Leverage, // 传递杠杆配置 ) if err != nil { log.Fatalf("❌ 初始化trader失败: %v", err) @@ -79,7 +80,8 @@ func main() { fmt.Println() fmt.Println("🤖 AI全权决策模式:") - fmt.Println(" • AI将自主决定每笔交易的杠杆倍数(山寨币1-20倍,BTC/ETH最高50倍)") + fmt.Printf(" • AI将自主决定每笔交易的杠杆倍数(山寨币最高%d倍,BTC/ETH最高%d倍)\n", + cfg.Leverage.AltcoinLeverage, cfg.Leverage.BTCETHLeverage) fmt.Println(" • AI将自主决定每笔交易的仓位大小") fmt.Println(" • AI将自主设置止损和止盈价格") fmt.Println(" • AI将基于市场数据、技术指标、账户状态做出全面分析") diff --git a/manager/trader_manager.go b/manager/trader_manager.go index 6c44c93b..b62f3fb9 100644 --- a/manager/trader_manager.go +++ b/manager/trader_manager.go @@ -23,7 +23,7 @@ func NewTraderManager() *TraderManager { } // AddTrader 添加一个trader -func (tm *TraderManager) AddTrader(cfg config.TraderConfig, coinPoolURL string, maxDailyLoss, maxDrawdown float64, stopTradingMinutes int) error { +func (tm *TraderManager) AddTrader(cfg config.TraderConfig, coinPoolURL string, maxDailyLoss, maxDrawdown float64, stopTradingMinutes int, leverage config.LeverageConfig) error { tm.mu.Lock() defer tm.mu.Unlock() @@ -44,6 +44,8 @@ func (tm *TraderManager) AddTrader(cfg config.TraderConfig, coinPoolURL string, QwenKey: cfg.QwenKey, ScanInterval: cfg.GetScanInterval(), InitialBalance: cfg.InitialBalance, + BTCETHLeverage: leverage.BTCETHLeverage, // 使用配置的杠杆倍数 + AltcoinLeverage: leverage.AltcoinLeverage, // 使用配置的杠杆倍数 MaxDailyLoss: maxDailyLoss, MaxDrawdown: maxDrawdown, StopTradingTime: time.Duration(stopTradingMinutes) * time.Minute, diff --git a/trader/auto_trader.go b/trader/auto_trader.go index 34f49475..a1e81edc 100644 --- a/trader/auto_trader.go +++ b/trader/auto_trader.go @@ -36,6 +36,10 @@ type AutoTraderConfig struct { // 账户配置 InitialBalance float64 // 初始金额(用于计算盈亏,需手动设置) + // 杠杆配置 + BTCETHLeverage int // BTC和ETH的杠杆倍数 + AltcoinLeverage int // 山寨币的杠杆倍数 + // 风险控制(仅作为提示,AI可自主决定) MaxDailyLoss float64 // 最大日亏损百分比(提示) MaxDrawdown float64 // 最大回撤百分比(提示) @@ -459,9 +463,11 @@ func (at *AutoTrader) buildTradingContext() (*decision.Context, error) { // 6. 构建上下文 ctx := &decision.Context{ - CurrentTime: time.Now().Format("2006-01-02 15:04:05"), - RuntimeMinutes: int(time.Since(at.startTime).Minutes()), - CallCount: at.callCount, + CurrentTime: time.Now().Format("2006-01-02 15:04:05"), + RuntimeMinutes: int(time.Since(at.startTime).Minutes()), + CallCount: at.callCount, + BTCETHLeverage: at.config.BTCETHLeverage, // 使用配置的杠杆倍数 + AltcoinLeverage: at.config.AltcoinLeverage, // 使用配置的杠杆倍数 Account: decision.AccountInfo{ TotalEquity: totalEquity, AvailableBalance: availableBalance,