2026-02-02 19:04:32 +08:00
|
|
|
|
package rule
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2026-02-03 14:40:20 +08:00
|
|
|
|
"context"
|
|
|
|
|
|
"encoding/json"
|
2026-02-02 19:04:32 +08:00
|
|
|
|
"fmt"
|
2026-02-03 14:40:20 +08:00
|
|
|
|
"os"
|
|
|
|
|
|
"strings"
|
2026-02-02 19:04:32 +08:00
|
|
|
|
|
|
|
|
|
|
"git.apinb.com/bsm-sdk/core/utils"
|
|
|
|
|
|
"git.apinb.com/quant/gostock/internal/config"
|
2026-02-03 14:40:20 +08:00
|
|
|
|
"github.com/go-deepseek/deepseek"
|
|
|
|
|
|
"github.com/go-deepseek/deepseek/request"
|
2026-02-02 19:04:32 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
|
MarkdataPath = "./markdata/"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
func (r *RuleFactory) RunAi(code string) {
|
|
|
|
|
|
mdPath := MarkdataPath + code + ".md"
|
|
|
|
|
|
if !utils.PathExists(mdPath) {
|
|
|
|
|
|
r.Model.AiScrore = -1
|
|
|
|
|
|
r.Model.AddDesc(fmt.Sprintf("%s markdown 文件未找友", mdPath))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-03 14:40:20 +08:00
|
|
|
|
content, err := os.ReadFile(mdPath)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
r.Model.AiScrore = -1
|
|
|
|
|
|
r.Model.AddDesc(fmt.Sprintf("%s markdown 读取错误,%v", mdPath, err))
|
|
|
|
|
|
return
|
2026-02-02 19:04:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-03 14:40:20 +08:00
|
|
|
|
client, _ := deepseek.NewClient(config.Spec.DeepSeekApiKey)
|
|
|
|
|
|
//prompt := "你是一名资深量化投研分析师,分析" + code + "这个股票,该股票的详细数据在https://markdata.apinb.com/" + code + ".md 读取这个markdown格式的内容,根据内容中的行情,财报,技术指标等数据(倒序,最新在最前面),给出基本面总结,技术面总结,舆论总结等更多方面的总结,并输出买入评分(0-10)整数,输出JSON,字段:summary(500字内中文总结)、score(0-10数字)、action(买入/谨慎/观望)、risk(一句风险提示)。"
|
|
|
|
|
|
prompt := "你是一名资深量化投研分析师,分析" + code + "这个股票,根据内容中的行情,财报,技术指标等数据,给出基本面总结,技术面总结,舆论总结等更多方面的总结,并输出买入评分(0-10)整数,输出JSON,字段:summary(中文总结)、summary_2025(2025年财报总结)、summary_base(基本面分析总结)、summary_tech(技术面分析总结)、score(0-10数字)、support_level(支撑位价格)、resis_level(阻力位价格)、action(买入/谨慎/观望)、risk(一句风险提示)。\r\n"
|
|
|
|
|
|
prompt += "内容如下:\r\n"
|
|
|
|
|
|
prompt += string(content)
|
|
|
|
|
|
|
|
|
|
|
|
chatReq := &request.ChatCompletionsRequest{
|
|
|
|
|
|
Model: deepseek.DEEPSEEK_CHAT_MODEL,
|
|
|
|
|
|
Stream: false,
|
|
|
|
|
|
Messages: []*request.Message{
|
|
|
|
|
|
{
|
|
|
|
|
|
Role: "system",
|
|
|
|
|
|
Content: prompt, // set your input message
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
chatResp, err := client.CallChatCompletionsChat(context.Background(), chatReq)
|
2026-02-02 19:04:32 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
|
r.Model.AiScrore = -1
|
|
|
|
|
|
r.Model.AddDesc(fmt.Sprintf("处理失败: %v", err))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 输出JSON格式的结果
|
2026-02-03 14:40:20 +08:00
|
|
|
|
jsonBodys := strings.ReplaceAll(chatResp.Choices[0].Message.Content, "```json", "")
|
|
|
|
|
|
jsonBodys = strings.ReplaceAll(jsonBodys, "```", "")
|
|
|
|
|
|
|
|
|
|
|
|
var result map[string]any
|
|
|
|
|
|
err = json.Unmarshal([]byte(jsonBodys), &result)
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
r.Model.AiScrore = -1
|
|
|
|
|
|
r.Model.AddDesc(fmt.Sprintf("Unmarshal: %v", err))
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
r.Model.AiSummary = result["summary"].(string)
|
|
|
|
|
|
r.Model.AiSummary2025 = result["summary_2025"].(string)
|
|
|
|
|
|
r.Model.AiSummaryBase = result["summary_base"].(string)
|
|
|
|
|
|
r.Model.AiSummaryTech = result["summary_tech"].(string)
|
|
|
|
|
|
r.Model.AiScrore = int(result["score"].(float64))
|
|
|
|
|
|
r.Model.AiSupportLevel = result["support_level"].(float64)
|
|
|
|
|
|
r.Model.AiResisLevel = result["resis_level"].(float64)
|
|
|
|
|
|
r.Model.AiAction = result["action"].(string)
|
|
|
|
|
|
r.Model.AiRisk = result["risk"].(string)
|
|
|
|
|
|
|
|
|
|
|
|
return
|
2026-02-02 19:04:32 +08:00
|
|
|
|
|
|
|
|
|
|
}
|