mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 01:06:59 +08:00
Feat: Integrate leverage configuration across trading system
- Pass leverage config through TraderManager to AutoTrader - Add BTCETHLeverage and AltcoinLeverage fields to Context and AutoTraderConfig - Update decision validation to use configured leverage limits - Display configured leverage in startup message - Update error messages to show current leverage limits Changes: - main.go: Pass leverage config to AddTrader, update startup message - manager/trader_manager.go: Accept and forward leverage config - trader/auto_trader.go: Store leverage config, pass to Context - decision/engine.go: Use dynamic leverage limits in validation This completes the leverage configuration feature implementation. Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
@@ -55,15 +55,17 @@ type OITopData struct {
|
|||||||
|
|
||||||
// Context 交易上下文(传递给AI的完整信息)
|
// Context 交易上下文(传递给AI的完整信息)
|
||||||
type Context struct {
|
type Context struct {
|
||||||
CurrentTime string `json:"current_time"`
|
CurrentTime string `json:"current_time"`
|
||||||
RuntimeMinutes int `json:"runtime_minutes"`
|
RuntimeMinutes int `json:"runtime_minutes"`
|
||||||
CallCount int `json:"call_count"`
|
CallCount int `json:"call_count"`
|
||||||
Account AccountInfo `json:"account"`
|
Account AccountInfo `json:"account"`
|
||||||
Positions []PositionInfo `json:"positions"`
|
Positions []PositionInfo `json:"positions"`
|
||||||
CandidateCoins []CandidateCoin `json:"candidate_coins"`
|
CandidateCoins []CandidateCoin `json:"candidate_coins"`
|
||||||
MarketDataMap map[string]*market.Data `json:"-"` // 不序列化,但内部使用
|
MarketDataMap map[string]*market.Data `json:"-"` // 不序列化,但内部使用
|
||||||
OITopDataMap map[string]*OITopData `json:"-"` // OI Top数据映射
|
OITopDataMap map[string]*OITopData `json:"-"` // OI Top数据映射
|
||||||
Performance interface{} `json:"-"` // 历史表现分析(logger.PerformanceAnalysis)
|
Performance interface{} `json:"-"` // 历史表现分析(logger.PerformanceAnalysis)
|
||||||
|
BTCETHLeverage int `json:"-"` // BTC/ETH杠杆倍数(从配置读取)
|
||||||
|
AltcoinLeverage int `json:"-"` // 山寨币杠杆倍数(从配置读取)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decision AI的交易决策
|
// Decision AI的交易决策
|
||||||
@@ -105,7 +107,7 @@ func GetFullDecision(ctx *Context) (*FullDecision, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. 解析AI响应
|
// 4. 解析AI响应
|
||||||
decision, err := parseFullDecisionResponse(aiResponse, ctx.Account.TotalEquity)
|
decision, err := parseFullDecisionResponse(aiResponse, ctx.Account.TotalEquity, ctx.BTCETHLeverage, ctx.AltcoinLeverage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("解析AI响应失败: %w", err)
|
return nil, fmt.Errorf("解析AI响应失败: %w", err)
|
||||||
}
|
}
|
||||||
@@ -415,7 +417,7 @@ func buildUserPrompt(ctx *Context) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parseFullDecisionResponse 解析AI的完整决策响应
|
// parseFullDecisionResponse 解析AI的完整决策响应
|
||||||
func parseFullDecisionResponse(aiResponse string, accountEquity float64) (*FullDecision, error) {
|
func parseFullDecisionResponse(aiResponse string, accountEquity float64, btcEthLeverage, altcoinLeverage int) (*FullDecision, error) {
|
||||||
// 1. 提取思维链
|
// 1. 提取思维链
|
||||||
cotTrace := extractCoTTrace(aiResponse)
|
cotTrace := extractCoTTrace(aiResponse)
|
||||||
|
|
||||||
@@ -429,7 +431,7 @@ func parseFullDecisionResponse(aiResponse string, accountEquity float64) (*FullD
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 验证决策
|
// 3. 验证决策
|
||||||
if err := validateDecisions(decisions, accountEquity); err != nil {
|
if err := validateDecisions(decisions, accountEquity, btcEthLeverage, altcoinLeverage); err != nil {
|
||||||
return &FullDecision{
|
return &FullDecision{
|
||||||
CoTTrace: cotTrace,
|
CoTTrace: cotTrace,
|
||||||
Decisions: decisions,
|
Decisions: decisions,
|
||||||
@@ -496,10 +498,10 @@ func fixMissingQuotes(jsonStr string) string {
|
|||||||
return jsonStr
|
return jsonStr
|
||||||
}
|
}
|
||||||
|
|
||||||
// validateDecisions 验证所有决策(需要账户信息)
|
// validateDecisions 验证所有决策(需要账户信息和杠杆配置)
|
||||||
func validateDecisions(decisions []Decision, accountEquity float64) error {
|
func validateDecisions(decisions []Decision, accountEquity float64, btcEthLeverage, altcoinLeverage int) error {
|
||||||
for i, decision := range decisions {
|
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)
|
return fmt.Errorf("决策 #%d 验证失败: %w", i+1, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,7 +531,7 @@ func findMatchingBracket(s string, start int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validateDecision 验证单个决策的有效性
|
// validateDecision 验证单个决策的有效性
|
||||||
func validateDecision(d *Decision, accountEquity float64) error {
|
func validateDecision(d *Decision, accountEquity float64, btcEthLeverage, altcoinLeverage int) error {
|
||||||
// 验证action
|
// 验证action
|
||||||
validActions := map[string]bool{
|
validActions := map[string]bool{
|
||||||
"open_long": true,
|
"open_long": true,
|
||||||
@@ -546,16 +548,16 @@ func validateDecision(d *Decision, accountEquity float64) error {
|
|||||||
|
|
||||||
// 开仓操作必须提供完整参数
|
// 开仓操作必须提供完整参数
|
||||||
if d.Action == "open_long" || d.Action == "open_short" {
|
if d.Action == "open_long" || d.Action == "open_short" {
|
||||||
// 根据币种判断杠杆上限和仓位价值上限
|
// 根据币种使用配置的杠杆上限
|
||||||
maxLeverage := 20 // 山寨币固定20倍
|
maxLeverage := altcoinLeverage // 山寨币使用配置的杠杆
|
||||||
maxPositionValue := accountEquity * 1.5 // 山寨币最多1.5倍账户净值
|
maxPositionValue := accountEquity * 1.5 // 山寨币最多1.5倍账户净值
|
||||||
if d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT" {
|
if d.Symbol == "BTCUSDT" || d.Symbol == "ETHUSDT" {
|
||||||
maxLeverage = 50 // BTC和ETH固定50倍
|
maxLeverage = btcEthLeverage // BTC和ETH使用配置的杠杆
|
||||||
maxPositionValue = accountEquity * 10 // BTC/ETH最多10倍账户净值
|
maxPositionValue = accountEquity * 10 // BTC/ETH最多10倍账户净值
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.Leverage <= 0 || d.Leverage > maxLeverage {
|
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 {
|
if d.PositionSizeUSD <= 0 {
|
||||||
return fmt.Errorf("仓位大小必须大于0: %.2f", d.PositionSizeUSD)
|
return fmt.Errorf("仓位大小必须大于0: %.2f", d.PositionSizeUSD)
|
||||||
|
|||||||
4
main.go
4
main.go
@@ -64,6 +64,7 @@ func main() {
|
|||||||
cfg.MaxDailyLoss,
|
cfg.MaxDailyLoss,
|
||||||
cfg.MaxDrawdown,
|
cfg.MaxDrawdown,
|
||||||
cfg.StopTradingMinutes,
|
cfg.StopTradingMinutes,
|
||||||
|
cfg.Leverage, // 传递杠杆配置
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("❌ 初始化trader失败: %v", err)
|
log.Fatalf("❌ 初始化trader失败: %v", err)
|
||||||
@@ -79,7 +80,8 @@ func main() {
|
|||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("🤖 AI全权决策模式:")
|
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将自主设置止损和止盈价格")
|
fmt.Println(" • AI将自主设置止损和止盈价格")
|
||||||
fmt.Println(" • AI将基于市场数据、技术指标、账户状态做出全面分析")
|
fmt.Println(" • AI将基于市场数据、技术指标、账户状态做出全面分析")
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func NewTraderManager() *TraderManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddTrader 添加一个trader
|
// 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()
|
tm.mu.Lock()
|
||||||
defer tm.mu.Unlock()
|
defer tm.mu.Unlock()
|
||||||
|
|
||||||
@@ -44,6 +44,8 @@ func (tm *TraderManager) AddTrader(cfg config.TraderConfig, coinPoolURL string,
|
|||||||
QwenKey: cfg.QwenKey,
|
QwenKey: cfg.QwenKey,
|
||||||
ScanInterval: cfg.GetScanInterval(),
|
ScanInterval: cfg.GetScanInterval(),
|
||||||
InitialBalance: cfg.InitialBalance,
|
InitialBalance: cfg.InitialBalance,
|
||||||
|
BTCETHLeverage: leverage.BTCETHLeverage, // 使用配置的杠杆倍数
|
||||||
|
AltcoinLeverage: leverage.AltcoinLeverage, // 使用配置的杠杆倍数
|
||||||
MaxDailyLoss: maxDailyLoss,
|
MaxDailyLoss: maxDailyLoss,
|
||||||
MaxDrawdown: maxDrawdown,
|
MaxDrawdown: maxDrawdown,
|
||||||
StopTradingTime: time.Duration(stopTradingMinutes) * time.Minute,
|
StopTradingTime: time.Duration(stopTradingMinutes) * time.Minute,
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ type AutoTraderConfig struct {
|
|||||||
// 账户配置
|
// 账户配置
|
||||||
InitialBalance float64 // 初始金额(用于计算盈亏,需手动设置)
|
InitialBalance float64 // 初始金额(用于计算盈亏,需手动设置)
|
||||||
|
|
||||||
|
// 杠杆配置
|
||||||
|
BTCETHLeverage int // BTC和ETH的杠杆倍数
|
||||||
|
AltcoinLeverage int // 山寨币的杠杆倍数
|
||||||
|
|
||||||
// 风险控制(仅作为提示,AI可自主决定)
|
// 风险控制(仅作为提示,AI可自主决定)
|
||||||
MaxDailyLoss float64 // 最大日亏损百分比(提示)
|
MaxDailyLoss float64 // 最大日亏损百分比(提示)
|
||||||
MaxDrawdown float64 // 最大回撤百分比(提示)
|
MaxDrawdown float64 // 最大回撤百分比(提示)
|
||||||
@@ -459,9 +463,11 @@ func (at *AutoTrader) buildTradingContext() (*decision.Context, error) {
|
|||||||
|
|
||||||
// 6. 构建上下文
|
// 6. 构建上下文
|
||||||
ctx := &decision.Context{
|
ctx := &decision.Context{
|
||||||
CurrentTime: time.Now().Format("2006-01-02 15:04:05"),
|
CurrentTime: time.Now().Format("2006-01-02 15:04:05"),
|
||||||
RuntimeMinutes: int(time.Since(at.startTime).Minutes()),
|
RuntimeMinutes: int(time.Since(at.startTime).Minutes()),
|
||||||
CallCount: at.callCount,
|
CallCount: at.callCount,
|
||||||
|
BTCETHLeverage: at.config.BTCETHLeverage, // 使用配置的杠杆倍数
|
||||||
|
AltcoinLeverage: at.config.AltcoinLeverage, // 使用配置的杠杆倍数
|
||||||
Account: decision.AccountInfo{
|
Account: decision.AccountInfo{
|
||||||
TotalEquity: totalEquity,
|
TotalEquity: totalEquity,
|
||||||
AvailableBalance: availableBalance,
|
AvailableBalance: availableBalance,
|
||||||
|
|||||||
Reference in New Issue
Block a user