From 399513cf148325897436f7a8bebb3e30eed912b3 Mon Sep 17 00:00:00 2001 From: spark Date: Wed, 22 Jan 2025 15:15:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(backend):=20=E6=B7=BB=E5=8A=A0=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E4=BF=A1=E6=81=AF=E6=90=9C=E7=B4=A2=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=20OpenAI=20API=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SearchStockInfo 函数,用于搜索指定股票的相关信息 - 优化 OpenAI API 调用,使用搜索到的股票信息作为上下文- 更新 go.mod 和 go.sum 文件,添加 chromedp 等依赖 --- backend/data/openai_api.go | 62 ++++++++++++++--------------- backend/data/stock_data_api.go | 37 +++++++++++++++++ backend/data/stock_data_api_test.go | 13 +++++- go.mod | 8 ++++ go.sum | 20 ++++++++++ 5 files changed, 106 insertions(+), 34 deletions(-) diff --git a/backend/data/openai_api.go b/backend/data/openai_api.go index 67a234e..f981530 100644 --- a/backend/data/openai_api.go +++ b/backend/data/openai_api.go @@ -117,6 +117,34 @@ func (o OpenAi) NewChatStream(stock string) <-chan string { client.SetHeader("Authorization", "Bearer "+o.ApiKey) client.SetHeader("Content-Type", "application/json") + msg := []map[string]interface{}{ + { + "role": "system", + "content": "作为一位专业的A股市场分析师和投资顾问,请你根据以下信息提供详细的技术分析和投资策略建议:", + }, + } + + messages := SearchStockInfo(stock, "depth") + for _, message := range *messages { + msg = append(msg, map[string]interface{}{ + "role": "assistant", + "content": message, + }) + } + + messages = SearchStockInfo(stock, "telegram") + for _, message := range *messages { + msg = append(msg, map[string]interface{}{ + "role": "assistant", + "content": message, + }) + } + + msg = append(msg, map[string]interface{}{ + "role": "user", + "content": stock + "分析和总结", + }) + resp, err := client.R(). SetDoNotParseResponse(true). SetBody(map[string]interface{}{ @@ -124,39 +152,7 @@ func (o OpenAi) NewChatStream(stock string) <-chan string { "max_tokens": o.MaxTokens, "temperature": o.Temperature, "stream": true, - "messages": []map[string]interface{}{ - { - "role": "system", - "content": "作为一位专业的A股市场分析师和投资顾问,请你根据以下信息提供详细的技术分析和投资策略建议:" + - "1. 市场背景:\n" + - "- 当前A股市场整体走势(如:牛市、熊市、震荡市)\n " + - "- 近期影响市场的主要宏观经济因素\n " + - "- 市场情绪指标(如:融资融券余额、成交量变化) " + - "2. 技术指标分析: " + - "- 当前股价水平" + - "- 所在boll区间" + - "- 上证指数的MA(移动平均线)、MACD、KDJ指标分析\n " + - "- 行业板块轮动情况\n " + - "- 近期市场热点和龙头股票的技术形态 " + - "3. 风险评估:\n " + - "- 当前市场主要风险因素\n " + - "- 如何设置止损和止盈位\n " + - "- 资金管理建议(如:仓位控制) " + - "4. 投资策略:\n " + - "- 短期(1-2周)、中期(1-3月)和长期(3-6月)的市场预期\n " + - "- 不同风险偏好投资者的策略建议\n " + - "- 值得关注的行业板块和个股推荐(请给出2-3个具体例子,包括股票代码和名称) " + - "5. 技术面和基本面结合:\n " + - "- 如何将技术分析与公司基本面分析相结合\n " + - "- 识别高质量股票的关键指标 " + - "请提供详细的分析和具体的操作建议,包括入场时机、持仓周期和退出策略。同时,请强调风险控制的重要性,并提醒投资者需要根据自身情况做出决策。 " + - "你的分析和建议应当客观、全面,并基于当前可获得的市场数据。如果某些信息无法确定,请明确指出并解释原因。", - }, - { - "role": "user", - "content": "点评一下" + stock, - }, - }, + "messages": msg, }). Post("/chat/completions") diff --git a/backend/data/stock_data_api.go b/backend/data/stock_data_api.go index 7fbe395..4109fc5 100644 --- a/backend/data/stock_data_api.go +++ b/backend/data/stock_data_api.go @@ -6,8 +6,11 @@ package data //----------------------------------------------------------------------------------- import ( "bytes" + "context" "encoding/json" "fmt" + "github.com/PuerkitoBio/goquery" + "github.com/chromedp/chromedp" "github.com/duke-git/lancet/v2/convertor" "github.com/duke-git/lancet/v2/slice" "github.com/duke-git/lancet/v2/strutil" @@ -506,3 +509,37 @@ type IndexBasic struct { func (IndexBasic) TableName() string { return "tushare_index_basic" } + +func SearchStockInfo(stock, msgType string) *[]string { + // 创建一个 chromedp 上下文 + ctx, cancel := chromedp.NewContext( + context.Background(), + ) + defer cancel() + var htmlContent string + url := fmt.Sprintf("https://www.cls.cn/searchPage?keyword=%s&type=%s", stock, msgType) + err := chromedp.Run(ctx, + chromedp.Navigate(url), + // 等待页面加载完成,可以根据需要调整等待时间 + chromedp.Sleep(3*time.Second), + chromedp.OuterHTML("html", &htmlContent, chromedp.ByQuery), + ) + if err != nil { + logger.SugaredLogger.Error(err.Error()) + return &[]string{} + } + document, err := goquery.NewDocumentFromReader(strings.NewReader(htmlContent)) + if err != nil { + logger.SugaredLogger.Error(err.Error()) + return &[]string{} + } + var messages []string + document.Find("div.search-telegraph-list,a.search-content").Each(func(i int, selection *goquery.Selection) { + text := strutil.RemoveNonPrintable(selection.Text()) + if strings.Contains(text, stock) { + messages = append(messages, text) + logger.SugaredLogger.Infof("搜索到消息: %s", text) + } + }) + return &messages +} diff --git a/backend/data/stock_data_api_test.go b/backend/data/stock_data_api_test.go index 46bf564..c0923a4 100644 --- a/backend/data/stock_data_api_test.go +++ b/backend/data/stock_data_api_test.go @@ -35,8 +35,19 @@ func TestGetTelegraph(t *testing.T) { return } document.Find("div.telegraph-content-box").Each(func(i int, selection *goquery.Selection) { - logger.SugaredLogger.Info(selection.Text()) + text := selection.Text() + if strings.Contains(text, "【公告】") { + logger.SugaredLogger.Info(text) + } }) +} + +func TestGetTelegraphSearch(t *testing.T) { + //url := "https://www.cls.cn/searchPage?keyword=%E9%97%BB%E6%B3%B0%E7%A7%91%E6%8A%80&type=telegram" + messages := SearchStockInfo("闻泰科技", "depth") + for _, message := range *messages { + logger.SugaredLogger.Info(message) + } } diff --git a/go.mod b/go.mod index de69f9c..9fdb640 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.23.0 require ( github.com/PuerkitoBio/goquery v1.10.1 + github.com/chromedp/chromedp v0.11.2 github.com/coocood/freecache v1.2.4 github.com/duke-git/lancet/v2 v2.3.4 github.com/getlantern/systray v1.2.2 @@ -25,6 +26,8 @@ require ( github.com/andybalholm/cascadia v1.3.3 // indirect github.com/bep/debounce v1.2.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb // indirect + github.com/chromedp/sysutil v1.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 // indirect @@ -35,17 +38,22 @@ require ( github.com/glebarez/go-sqlite v1.21.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.0 // indirect + github.com/gobwas/httphead v0.1.0 // indirect + github.com/gobwas/pool v0.2.1 // indirect + github.com/gobwas/ws v1.4.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/labstack/echo/v4 v4.10.2 // indirect github.com/labstack/gommon v0.4.0 // indirect github.com/leaanthony/go-ansi-parser v1.6.0 // indirect github.com/leaanthony/gosod v1.0.3 // indirect github.com/leaanthony/slicer v1.6.0 // indirect github.com/leaanthony/u v1.1.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect diff --git a/go.sum b/go.sum index b91ceb2..5a6b347 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,12 @@ github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb h1:noKVm2SsG4v0Yd0lHNtFYc9EUxIVvrr4kJ6hM8wvIYU= +github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb/go.mod h1:4XqMl3iIW08jtieURWL6Tt5924w21pxirC6th662XUM= +github.com/chromedp/chromedp v0.11.2 h1:ZRHTh7DjbNTlfIv3NFTbB7eVeu5XCNkgrpcGSpn2oX0= +github.com/chromedp/chromedp v0.11.2/go.mod h1:lr8dFRLKsdTTWb75C/Ttol2vnBKOSnt0BW8R9Xaupi8= +github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM= +github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8= github.com/coocood/freecache v1.2.4 h1:UdR6Yz/X1HW4fZOuH0Z94KwG851GWOSknua5VUbb/5M= github.com/coocood/freecache v1.2.4/go.mod h1:RBUWa/Cy+OHdfTGFEhEuE1pMCMX51Ncizj7rthiQ3vk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -43,6 +49,12 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE= github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= +github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -58,6 +70,8 @@ github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= @@ -73,8 +87,12 @@ github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/ github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8= github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI= github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= @@ -89,6 +107,8 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ= github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=