handleStrategyTestRun AI test run (does not execute trades, only returns AI analysis results)
(c *gin.Context)
| 548 | |
| 549 | // handleStrategyTestRun AI test run (does not execute trades, only returns AI analysis results) |
| 550 | func (s *Server) handleStrategyTestRun(c *gin.Context) { |
| 551 | userID := c.GetString("user_id") |
| 552 | if userID == "" { |
| 553 | c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"}) |
| 554 | return |
| 555 | } |
| 556 | |
| 557 | var req struct { |
| 558 | Config store.StrategyConfig `json:"config" binding:"required"` |
| 559 | PromptVariant string `json:"prompt_variant"` |
| 560 | AIModelID string `json:"ai_model_id"` |
| 561 | RunRealAI bool `json:"run_real_ai"` |
| 562 | } |
| 563 | |
| 564 | if err := c.ShouldBindJSON(&req); err != nil { |
| 565 | SafeBadRequest(c, "Invalid request parameters") |
| 566 | return |
| 567 | } |
| 568 | |
| 569 | if req.PromptVariant == "" { |
| 570 | req.PromptVariant = "balanced" |
| 571 | } |
| 572 | |
| 573 | claw402WalletKey, err := s.resolveStrategyDataWalletKey(userID, req.AIModelID) |
| 574 | if err != nil { |
| 575 | c.JSON(http.StatusBadRequest, gin.H{ |
| 576 | "error": err.Error(), |
| 577 | "ai_response": "", |
| 578 | }) |
| 579 | return |
| 580 | } |
| 581 | |
| 582 | // Create strategy engine to build prompt |
| 583 | engine := kernel.NewStrategyEngine(&req.Config, claw402WalletKey) |
| 584 | |
| 585 | // Get candidate coins |
| 586 | candidates, err := engine.GetCandidateCoins() |
| 587 | if err != nil { |
| 588 | logger.Errorf("[API Error] Failed to get candidate coins: %v", err) |
| 589 | c.JSON(http.StatusInternalServerError, gin.H{ |
| 590 | "error": "Failed to get candidate coins", |
| 591 | "ai_response": "", |
| 592 | }) |
| 593 | return |
| 594 | } |
| 595 | |
| 596 | // Get timeframe configuration |
| 597 | timeframes := req.Config.Indicators.Klines.SelectedTimeframes |
| 598 | primaryTimeframe := req.Config.Indicators.Klines.PrimaryTimeframe |
| 599 | klineCount := req.Config.Indicators.Klines.PrimaryCount |
| 600 | |
| 601 | // If no timeframes selected, use default values |
| 602 | if len(timeframes) == 0 { |
| 603 | // Backward compatibility: use primary and longer timeframes |
| 604 | if primaryTimeframe != "" { |
| 605 | timeframes = append(timeframes, primaryTimeframe) |
| 606 | } else { |
| 607 | timeframes = append(timeframes, "3m") |
nothing calls this directly
no test coverage detected