refactor: standardize code comments

This commit is contained in:
tinkle-community
2025-12-08 01:40:48 +08:00
parent 0636ced476
commit a12c0ae8c9
103 changed files with 5466 additions and 5468 deletions

View File

@@ -14,21 +14,21 @@ import (
"github.com/google/uuid"
)
// handleGetStrategies 获取策略列表
// handleGetStrategies Get strategy list
func (s *Server) handleGetStrategies(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
strategies, err := s.store.Strategy().List(userID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取策略列表失败: " + err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get strategy list: " + err.Error()})
return
}
// 转换为前端格式
// Convert to frontend format
result := make([]gin.H, 0, len(strategies))
for _, st := range strategies {
var config store.StrategyConfig
@@ -51,19 +51,19 @@ func (s *Server) handleGetStrategies(c *gin.Context) {
})
}
// handleGetStrategy 获取单个策略
// handleGetStrategy Get single strategy
func (s *Server) handleGetStrategy(c *gin.Context) {
userID := c.GetString("user_id")
strategyID := c.Param("id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
strategy, err := s.store.Strategy().Get(userID, strategyID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "策略不存在"})
c.JSON(http.StatusNotFound, gin.H{"error": "Strategy not found"})
return
}
@@ -82,11 +82,11 @@ func (s *Server) handleGetStrategy(c *gin.Context) {
})
}
// handleCreateStrategy 创建策略
// handleCreateStrategy Create strategy
func (s *Server) handleCreateStrategy(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
@@ -97,14 +97,14 @@ func (s *Server) handleCreateStrategy(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数: " + err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request parameters: " + err.Error()})
return
}
// 序列化配置
// Serialize configuration
configJSON, err := json.Marshal(req.Config)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "序列化配置失败"})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to serialize configuration"})
return
}
@@ -119,34 +119,34 @@ func (s *Server) handleCreateStrategy(c *gin.Context) {
}
if err := s.store.Strategy().Create(strategy); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "创建策略失败: " + err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create strategy: " + err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"id": strategy.ID,
"message": "策略创建成功",
"message": "Strategy created successfully",
})
}
// handleUpdateStrategy 更新策略
// handleUpdateStrategy Update strategy
func (s *Server) handleUpdateStrategy(c *gin.Context) {
userID := c.GetString("user_id")
strategyID := c.Param("id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
// 检查是否是系统默认策略
// Check if it's a system default strategy
existing, err := s.store.Strategy().Get(userID, strategyID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "策略不存在"})
c.JSON(http.StatusNotFound, gin.H{"error": "Strategy not found"})
return
}
if existing.IsDefault {
c.JSON(http.StatusForbidden, gin.H{"error": "不能修改系统默认策略"})
c.JSON(http.StatusForbidden, gin.H{"error": "Cannot modify system default strategy"})
return
}
@@ -157,14 +157,14 @@ func (s *Server) handleUpdateStrategy(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数: " + err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request parameters: " + err.Error()})
return
}
// 序列化配置
// Serialize configuration
configJSON, err := json.Marshal(req.Config)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "序列化配置失败"})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to serialize configuration"})
return
}
@@ -177,56 +177,56 @@ func (s *Server) handleUpdateStrategy(c *gin.Context) {
}
if err := s.store.Strategy().Update(strategy); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "更新策略失败: " + err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update strategy: " + err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "策略更新成功"})
c.JSON(http.StatusOK, gin.H{"message": "Strategy updated successfully"})
}
// handleDeleteStrategy 删除策略
// handleDeleteStrategy Delete strategy
func (s *Server) handleDeleteStrategy(c *gin.Context) {
userID := c.GetString("user_id")
strategyID := c.Param("id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
if err := s.store.Strategy().Delete(userID, strategyID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "删除策略失败: " + err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete strategy: " + err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "策略删除成功"})
c.JSON(http.StatusOK, gin.H{"message": "Strategy deleted successfully"})
}
// handleActivateStrategy 激活策略
// handleActivateStrategy Activate strategy
func (s *Server) handleActivateStrategy(c *gin.Context) {
userID := c.GetString("user_id")
strategyID := c.Param("id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
if err := s.store.Strategy().SetActive(userID, strategyID); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "激活策略失败: " + err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to activate strategy: " + err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "策略激活成功"})
c.JSON(http.StatusOK, gin.H{"message": "Strategy activated successfully"})
}
// handleDuplicateStrategy 复制策略
// handleDuplicateStrategy Duplicate strategy
func (s *Server) handleDuplicateStrategy(c *gin.Context) {
userID := c.GetString("user_id")
sourceID := c.Param("id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
@@ -235,34 +235,34 @@ func (s *Server) handleDuplicateStrategy(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数: " + err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request parameters: " + err.Error()})
return
}
newID := uuid.New().String()
if err := s.store.Strategy().Duplicate(userID, sourceID, newID, req.Name); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "复制策略失败: " + err.Error()})
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to duplicate strategy: " + err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"id": newID,
"message": "策略复制成功",
"message": "Strategy duplicated successfully",
})
}
// handleGetActiveStrategy 获取当前激活的策略
// handleGetActiveStrategy Get currently active strategy
func (s *Server) handleGetActiveStrategy(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
strategy, err := s.store.Strategy().GetActive(userID)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "没有激活的策略"})
c.JSON(http.StatusNotFound, gin.H{"error": "No active strategy"})
return
}
@@ -281,9 +281,9 @@ func (s *Server) handleGetActiveStrategy(c *gin.Context) {
})
}
// handleGetDefaultStrategyConfig 获取默认策略配置模板
// handleGetDefaultStrategyConfig Get default strategy configuration template
func (s *Server) handleGetDefaultStrategyConfig(c *gin.Context) {
// 返回默认配置结构,供前端创建新策略时使用
// Return default configuration structure for frontend to use when creating new strategies
defaultConfig := store.StrategyConfig{
CoinSource: store.CoinSourceConfig{
SourceType: "coinpool",
@@ -324,42 +324,42 @@ func (s *Server) handleGetDefaultStrategyConfig(c *gin.Context) {
MinConfidence: 75,
},
PromptSections: store.PromptSectionsConfig{
RoleDefinition: `# 你是专业的加密货币交易AI
RoleDefinition: `# You are a professional cryptocurrency trading AI
你专注于技术分析和风险管理,基于市场数据做出理性的交易决策。
你的目标是在控制风险的前提下,捕捉高概率的交易机会。`,
TradingFrequency: `# ⏱️ 交易频率认知
You focus on technical analysis and risk management, making rational trading decisions based on market data.
Your goal is to capture high-probability trading opportunities while controlling risk.`,
TradingFrequency: `# ⏱️ Trading Frequency Awareness
- 优秀交易员每天2-4笔 ≈ 每小时0.1-0.2笔
- 每小时>2笔 = 过度交易
- 单笔持仓时间≥30-60分钟
如果你发现自己每个周期都在交易 → 标准过低;若持仓<30分钟就平仓 → 过于急躁。`,
EntryStandards: `# 🎯 开仓标准(严格)
- Excellent traders: 2-4 trades per day ≈ 0.1-0.2 trades per hour
- >2 trades per hour = overtrading
- Single position holding time ≥30-60 minutes
If you find yourself trading every cycle → standards too low; if closing positions <30 minutes → too impatient.`,
EntryStandards: `# 🎯 Entry Standards (Strict)
只在多重信号共振时开仓:
- 趋势方向明确EMA排列、价格位置
- 动量确认(MACDRSI协同)
- 波动率适中ATR合理范围
- 量价配合(成交量支持方向)
Only enter when multiple signals align:
- Clear trend direction (EMA alignment, price position)
- Momentum confirmation (MACD, RSI cooperation)
- Moderate volatility (ATR reasonable range)
- Volume-price coordination (volume supports direction)
避免:单一指标、信号矛盾、横盘震荡、刚平仓即重启。`,
DecisionProcess: `# 📋 决策流程
Avoid: single indicator, conflicting signals, sideways consolidation, reopening immediately after closing.`,
DecisionProcess: `# 📋 Decision Process
1. 检查持仓 → 是否该止盈/止损
2. 扫描候选币 + 多时间框 → 是否存在强信号
3. 评估风险回报比 → 是否满足最小要求
4. 先写思维链,再输出结构化JSON`,
1. Check positions → Should take profit/stop loss
2. Scan candidate coins + multiple timeframes → Are there strong signals
3. Evaluate risk-reward ratio → Does it meet minimum requirements
4. Write chain of thought first, then output structured JSON`,
},
}
c.JSON(http.StatusOK, defaultConfig)
}
// handlePreviewPrompt 预览策略生成的 Prompt
// handlePreviewPrompt Preview prompt generated by strategy
func (s *Server) handlePreviewPrompt(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
@@ -370,28 +370,28 @@ func (s *Server) handlePreviewPrompt(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数: " + err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request parameters: " + err.Error()})
return
}
// 使用默认值
// Use default values
if req.AccountEquity <= 0 {
req.AccountEquity = 1000.0 // 默认模拟账户净值
req.AccountEquity = 1000.0 // Default simulated account equity
}
if req.PromptVariant == "" {
req.PromptVariant = "balanced"
}
// 创建策略引擎来构建 prompt
// Create strategy engine to build prompt
engine := decision.NewStrategyEngine(&req.Config)
// 构建系统 prompt使用策略引擎内置的方法
// Build system prompt (using built-in method from strategy engine)
systemPrompt := engine.BuildSystemPrompt(
req.AccountEquity,
req.PromptVariant,
)
// 获取可用的 prompt 模板列表
// Get list of available prompt templates
templateNames := decision.GetAllPromptTemplateNames()
c.JSON(http.StatusOK, gin.H{
@@ -408,11 +408,11 @@ func (s *Server) handlePreviewPrompt(c *gin.Context) {
})
}
// handleStrategyTestRun AI 测试运行(不执行交易,只返回 AI 分析结果)
// handleStrategyTestRun AI test run (does not execute trades, only returns AI analysis results)
func (s *Server) handleStrategyTestRun(c *gin.Context) {
userID := c.GetString("user_id")
if userID == "" {
c.JSON(http.StatusUnauthorized, gin.H{"error": "未授权"})
c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
@@ -424,7 +424,7 @@ func (s *Server) handleStrategyTestRun(c *gin.Context) {
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求参数: " + err.Error()})
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request parameters: " + err.Error()})
return
}
@@ -432,27 +432,27 @@ func (s *Server) handleStrategyTestRun(c *gin.Context) {
req.PromptVariant = "balanced"
}
// 创建策略引擎来构建 prompt
// Create strategy engine to build prompt
engine := decision.NewStrategyEngine(&req.Config)
// 获取候选币种
// Get candidate coins
candidates, err := engine.GetCandidateCoins()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"error": "获取候选币种失败: " + err.Error(),
"error": "Failed to get candidate coins: " + err.Error(),
"ai_response": "",
})
return
}
// 获取时间周期配置
// Get timeframe configuration
timeframes := req.Config.Indicators.Klines.SelectedTimeframes
primaryTimeframe := req.Config.Indicators.Klines.PrimaryTimeframe
klineCount := req.Config.Indicators.Klines.PrimaryCount
// 如果没有选择时间周期,使用默认值
// If no timeframes selected, use default values
if len(timeframes) == 0 {
// 兼容旧配置:使用主周期和长周期
// Backward compatibility: use primary and longer timeframes
if primaryTimeframe != "" {
timeframes = append(timeframes, primaryTimeframe)
} else {
@@ -469,21 +469,21 @@ func (s *Server) handleStrategyTestRun(c *gin.Context) {
klineCount = 30
}
fmt.Printf("📊 使用时间周期: %v, 主周期: %s, K线数量: %d\n", timeframes, primaryTimeframe, klineCount)
fmt.Printf("📊 Using timeframes: %v, primary: %s, kline count: %d\n", timeframes, primaryTimeframe, klineCount)
// 获取真实市场数据(使用多时间周期)
// Get real market data (using multiple timeframes)
marketDataMap := make(map[string]*market.Data)
for _, coin := range candidates {
data, err := market.GetWithTimeframes(coin.Symbol, timeframes, primaryTimeframe, klineCount)
if err != nil {
// 如果获取某个币种数据失败,记录日志但继续
fmt.Printf("⚠️ 获取 %s 市场数据失败: %v\n", coin.Symbol, err)
// If getting data for a coin fails, log but continue
fmt.Printf("⚠️ Failed to get market data for %s: %v\n", coin.Symbol, err)
continue
}
marketDataMap[coin.Symbol] = data
}
// 构建真实的上下文(用于生成 User Prompt
// Build real context (for generating User Prompt)
testContext := &decision.Context{
CurrentTime: time.Now().Format("2006-01-02 15:04:05"),
RuntimeMinutes: 0,
@@ -504,13 +504,13 @@ func (s *Server) handleStrategyTestRun(c *gin.Context) {
MarketDataMap: marketDataMap,
}
// 构建 System Prompt
// Build System Prompt
systemPrompt := engine.BuildSystemPrompt(1000.0, req.PromptVariant)
// 构建 User Prompt(使用真实市场数据)
// Build User Prompt (using real market data)
userPrompt := engine.BuildUserPrompt(testContext)
// 如果请求真实 AI 调用
// If requesting real AI call
if req.RunRealAI && req.AIModelID != "" {
aiResponse, aiErr := s.runRealAITest(userID, req.AIModelID, systemPrompt, userPrompt)
if aiErr != nil {
@@ -520,9 +520,9 @@ func (s *Server) handleStrategyTestRun(c *gin.Context) {
"candidate_count": len(candidates),
"candidates": candidates,
"prompt_variant": req.PromptVariant,
"ai_response": fmt.Sprintf("❌ AI 调用失败: %s", aiErr.Error()),
"ai_response": fmt.Sprintf("❌ AI call failed: %s", aiErr.Error()),
"ai_error": aiErr.Error(),
"note": "AI 调用出错",
"note": "AI call error",
})
return
}
@@ -534,40 +534,40 @@ func (s *Server) handleStrategyTestRun(c *gin.Context) {
"candidates": candidates,
"prompt_variant": req.PromptVariant,
"ai_response": aiResponse,
"note": "✅ 真实 AI 测试运行成功",
"note": "✅ Real AI test run successful",
})
return
}
// 返回结果(不实际调用 AI只返回构建的 prompt
// Return result (without actually calling AI, only return built prompt)
c.JSON(http.StatusOK, gin.H{
"system_prompt": systemPrompt,
"user_prompt": userPrompt,
"candidate_count": len(candidates),
"candidates": candidates,
"prompt_variant": req.PromptVariant,
"ai_response": "请选择 AI 模型并点击「运行测试」来执行真实的 AI 分析。",
"note": "未选择 AI 模型或未启用真实 AI 调用",
"ai_response": "Please select an AI model and click 'Run Test' to perform real AI analysis.",
"note": "AI model not selected or real AI call not enabled",
})
}
// runRealAITest 执行真实的 AI 测试调用
// runRealAITest Execute real AI test call
func (s *Server) runRealAITest(userID, modelID, systemPrompt, userPrompt string) (string, error) {
// 获取 AI 模型配置
// Get AI model configuration
model, err := s.store.AIModel().Get(userID, modelID)
if err != nil {
return "", fmt.Errorf("获取 AI 模型失败: %w", err)
return "", fmt.Errorf("failed to get AI model: %w", err)
}
if !model.Enabled {
return "", fmt.Errorf("AI 模型 %s 尚未启用", model.Name)
return "", fmt.Errorf("AI model %s is not enabled", model.Name)
}
if model.APIKey == "" {
return "", fmt.Errorf("AI 模型 %s 缺少 API Key", model.Name)
return "", fmt.Errorf("AI model %s is missing API Key", model.Name)
}
// 创建 AI 客户端
// Create AI client
var aiClient mcp.AIClient
provider := model.Provider
@@ -579,15 +579,15 @@ func (s *Server) runRealAITest(userID, modelID, systemPrompt, userPrompt string)
aiClient = mcp.NewDeepSeekClient()
aiClient.SetAPIKey(model.APIKey, model.CustomAPIURL, model.CustomModelName)
default:
// 使用通用客户端
// Use generic client
aiClient = mcp.NewClient()
aiClient.SetAPIKey(model.APIKey, model.CustomAPIURL, model.CustomModelName)
}
// 调用 AI API
// Call AI API
response, err := aiClient.CallWithMessages(systemPrompt, userPrompt)
if err != nil {
return "", fmt.Errorf("AI API 调用失败: %w", err)
return "", fmt.Errorf("AI API call failed: %w", err)
}
return response, nil