Compare commits
6 Commits
v2025.11.2
...
v2025.11.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26e9753b94 | ||
|
|
b7f6dbd2da | ||
|
|
18dd01b613 | ||
|
|
81bb33a135 | ||
|
|
9926b61fac | ||
|
|
5e975b060c |
@@ -1,10 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"go-stock/backend/agent"
|
||||
"go-stock/backend/data"
|
||||
"go-stock/backend/models"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
)
|
||||
|
||||
// @Author spark
|
||||
@@ -26,48 +28,66 @@ func (a *App) StockNotice(stockCode string) []any {
|
||||
func (a *App) IndustryResearchReport(industryCode string) []any {
|
||||
return data.NewMarketNewsApi().IndustryResearchReport(industryCode, 7)
|
||||
}
|
||||
func (a App) EMDictCode(code string) []any {
|
||||
func (a *App) EMDictCode(code string) []any {
|
||||
return data.NewMarketNewsApi().EMDictCode(code, a.cache)
|
||||
}
|
||||
|
||||
func (a App) AnalyzeSentiment(text string) data.SentimentResult {
|
||||
func (a *App) AnalyzeSentiment(text string) data.SentimentResult {
|
||||
return data.AnalyzeSentiment(text)
|
||||
}
|
||||
|
||||
func (a App) HotStock(marketType string) *[]models.HotItem {
|
||||
func (a *App) HotStock(marketType string) *[]models.HotItem {
|
||||
return data.NewMarketNewsApi().XUEQIUHotStock(100, marketType)
|
||||
}
|
||||
|
||||
func (a App) HotEvent(size int) *[]models.HotEvent {
|
||||
func (a *App) HotEvent(size int) *[]models.HotEvent {
|
||||
if size <= 0 {
|
||||
size = 10
|
||||
}
|
||||
return data.NewMarketNewsApi().HotEvent(size)
|
||||
}
|
||||
func (a App) HotTopic(size int) []any {
|
||||
func (a *App) HotTopic(size int) []any {
|
||||
if size <= 0 {
|
||||
size = 10
|
||||
}
|
||||
return data.NewMarketNewsApi().HotTopic(size)
|
||||
}
|
||||
|
||||
func (a App) InvestCalendarTimeLine(yearMonth string) []any {
|
||||
func (a *App) InvestCalendarTimeLine(yearMonth string) []any {
|
||||
return data.NewMarketNewsApi().InvestCalendar(yearMonth)
|
||||
}
|
||||
func (a App) ClsCalendar() []any {
|
||||
func (a *App) ClsCalendar() []any {
|
||||
return data.NewMarketNewsApi().ClsCalendar()
|
||||
}
|
||||
|
||||
func (a App) SearchStock(words string) map[string]any {
|
||||
func (a *App) SearchStock(words string) map[string]any {
|
||||
return data.NewSearchStockApi(words).SearchStock(5000)
|
||||
}
|
||||
func (a App) GetHotStrategy() map[string]any {
|
||||
func (a *App) GetHotStrategy() map[string]any {
|
||||
return data.NewSearchStockApi("").HotStrategy()
|
||||
}
|
||||
|
||||
func (a App) ChatWithAgent(question string, aiConfigId int, sysPromptId *int) {
|
||||
func (a *App) ChatWithAgent(question string, aiConfigId int, sysPromptId *int) {
|
||||
ch := agent.NewStockAiAgentApi().Chat(question, aiConfigId, sysPromptId)
|
||||
for msg := range ch {
|
||||
runtime.EventsEmit(a.ctx, "agent-message", msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) AnalyzeSentimentWithFreqWeight(text string) map[string]any {
|
||||
if text == "" {
|
||||
telegraphs := data.NewMarketNewsApi().GetNews24HoursList("财联社电报", 1000)
|
||||
messageText := strings.Builder{}
|
||||
for _, telegraph := range *telegraphs {
|
||||
messageText.WriteString(telegraph.Content + "\n")
|
||||
}
|
||||
text = messageText.String()
|
||||
}
|
||||
result, frequencies := data.AnalyzeSentimentWithFreqWeight(text)
|
||||
// 过滤标点符号和分隔符
|
||||
cleanFrequencies := data.FilterAndSortWords(frequencies)
|
||||
return map[string]any{
|
||||
"result": result,
|
||||
"frequencies": cleanFrequencies,
|
||||
}
|
||||
}
|
||||
|
||||
1
backend/data/data/dict/README.md
Normal file
1
backend/data/data/dict/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Some dict/zh data is from [github.com/fxsjy/jieba](https://github.com/fxsjy/jieba)
|
||||
1027
backend/data/data/dict/base.txt
Normal file
1027
backend/data/data/dict/base.txt
Normal file
File diff suppressed because it is too large
Load Diff
0
backend/data/data/dict/en/dict.txt
Normal file
0
backend/data/data/dict/en/dict.txt
Normal file
1
backend/data/data/dict/jp/README.md
Normal file
1
backend/data/data/dict/jp/README.md
Normal file
@@ -0,0 +1 @@
|
||||
dict.txt 通过内部工具生成, Copyright 2017 ego authors. 商用和拷贝请注明来源和版权
|
||||
885298
backend/data/data/dict/jp/dict.txt
Normal file
885298
backend/data/data/dict/jp/dict.txt
Normal file
File diff suppressed because it is too large
Load Diff
270132
backend/data/data/dict/zh/idf.txt
Normal file
270132
backend/data/data/dict/zh/idf.txt
Normal file
File diff suppressed because it is too large
Load Diff
352279
backend/data/data/dict/zh/s_1.txt
Normal file
352279
backend/data/data/dict/zh/s_1.txt
Normal file
File diff suppressed because it is too large
Load Diff
1161
backend/data/data/dict/zh/stop_tokens.txt
Normal file
1161
backend/data/data/dict/zh/stop_tokens.txt
Normal file
File diff suppressed because it is too large
Load Diff
88
backend/data/data/dict/zh/stop_word.txt
Normal file
88
backend/data/data/dict/zh/stop_word.txt
Normal file
@@ -0,0 +1,88 @@
|
||||
,
|
||||
.
|
||||
?
|
||||
!
|
||||
"
|
||||
@
|
||||
,
|
||||
。
|
||||
、
|
||||
?
|
||||
!
|
||||
:
|
||||
“
|
||||
”
|
||||
;
|
||||
|
||||
(
|
||||
)
|
||||
《
|
||||
》
|
||||
~
|
||||
*
|
||||
<
|
||||
>
|
||||
/
|
||||
\
|
||||
|
|
||||
-
|
||||
_
|
||||
+
|
||||
=
|
||||
&
|
||||
^
|
||||
%
|
||||
#
|
||||
`
|
||||
;
|
||||
$
|
||||
¥
|
||||
‘
|
||||
’
|
||||
〉
|
||||
〈
|
||||
…
|
||||
>
|
||||
<
|
||||
@
|
||||
#
|
||||
$
|
||||
%
|
||||
︿
|
||||
&
|
||||
*
|
||||
+
|
||||
~
|
||||
|
|
||||
[
|
||||
]
|
||||
{
|
||||
}
|
||||
啊
|
||||
阿
|
||||
哎
|
||||
哎呀
|
||||
哎哟
|
||||
唉
|
||||
俺
|
||||
俺们
|
||||
按
|
||||
按照
|
||||
吧
|
||||
吧哒
|
||||
把
|
||||
罢了
|
||||
被
|
||||
本
|
||||
本着
|
||||
比
|
||||
比方
|
||||
比如
|
||||
鄙人
|
||||
彼
|
||||
彼此
|
||||
边
|
||||
别
|
||||
别的
|
||||
别说
|
||||
并
|
||||
236754
backend/data/data/dict/zh/t_1.txt
Normal file
236754
backend/data/data/dict/zh/t_1.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,9 @@ func (m MarketNewsApi) TelegraphList(crawlTimeOut int64) *[]models.Telegraph {
|
||||
var telegraphs []models.Telegraph
|
||||
|
||||
if v, _ := convertor.ToInt(res["error"]); v == 0 {
|
||||
if res["data"] == nil {
|
||||
return m.GetNewTelegraph(30)
|
||||
}
|
||||
data := res["data"].(map[string]any)
|
||||
rollData := data["roll_data"].([]any)
|
||||
for _, v := range rollData {
|
||||
@@ -94,7 +97,7 @@ func (m MarketNewsApi) TelegraphList(crawlTimeOut int64) *[]models.Telegraph {
|
||||
return &telegraphs
|
||||
}
|
||||
func GetLevel(s string) bool {
|
||||
return s >= "C"
|
||||
return s > "C"
|
||||
}
|
||||
|
||||
func (m MarketNewsApi) GetNewTelegraph(crawlTimeOut int64) *[]models.Telegraph {
|
||||
@@ -1024,3 +1027,33 @@ func (m MarketNewsApi) CailianpressWeb(searchWords string) *models.CailianpressW
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (m MarketNewsApi) GetNews24HoursList(source string, limit int) *[]*models.Telegraph {
|
||||
news := &[]*models.Telegraph{}
|
||||
if source != "" {
|
||||
db.Dao.Model(news).Preload("TelegraphTags").Where("source=? and created_at>?", source, time.Now().Add(-24*time.Hour)).Order("id desc,is_red desc").Limit(limit).Find(news)
|
||||
} else {
|
||||
db.Dao.Model(news).Preload("TelegraphTags").Where("created_at>?", time.Now().Add(-24*time.Hour)).Order("id desc,is_red desc").Limit(limit).Find(news)
|
||||
}
|
||||
// 内容去重
|
||||
uniqueNews := make([]*models.Telegraph, 0)
|
||||
seenContent := make(map[string]bool)
|
||||
for _, item := range *news {
|
||||
tags := &[]models.Tags{}
|
||||
db.Dao.Model(&models.Tags{}).Where("id in ?", lo.Map(item.TelegraphTags, func(item models.TelegraphTags, index int) uint {
|
||||
return item.TagId
|
||||
})).Find(&tags)
|
||||
tagNames := lo.Map(*tags, func(item models.Tags, index int) string {
|
||||
return item.Name
|
||||
})
|
||||
item.SubjectTags = tagNames
|
||||
//logger.SugaredLogger.Infof("tagNames %v ,SubjectTags:%s", tagNames, item.SubjectTags)
|
||||
// 使用内容作为去重键值,可以考虑只使用内容的前几个字符或哈希值
|
||||
contentKey := strings.TrimSpace(item.Content)
|
||||
if contentKey != "" && !seenContent[contentKey] {
|
||||
seenContent[contentKey] = true
|
||||
uniqueNews = append(uniqueNews, item)
|
||||
}
|
||||
}
|
||||
return &uniqueNews
|
||||
}
|
||||
|
||||
@@ -2,11 +2,19 @@ package data
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"go-stock/backend/models"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/duke-git/lancet/v2/fileutil"
|
||||
"github.com/duke-git/lancet/v2/strutil"
|
||||
"github.com/go-ego/gse"
|
||||
)
|
||||
|
||||
@@ -16,7 +24,7 @@ var (
|
||||
|
||||
// 正面金融词汇及其权重
|
||||
positiveFinanceWords = map[string]float64{
|
||||
"上涨": 2.0, "涨停": 3.0, "牛市": 3.0, "反弹": 2.0, "新高": 2.5,
|
||||
"涨": 1.0, "上涨": 2.0, "涨停": 3.0, "牛市": 3.0, "反弹": 2.0, "新高": 2.5,
|
||||
"利好": 2.5, "增持": 2.0, "买入": 2.0, "推荐": 1.5, "看多": 2.0,
|
||||
"盈利": 2.0, "增长": 2.0, "超预期": 2.5, "强劲": 1.5, "回升": 1.5,
|
||||
"复苏": 2.0, "突破": 2.0, "创新高": 3.0, "回暖": 1.5, "上扬": 1.5,
|
||||
@@ -27,13 +35,13 @@ var (
|
||||
|
||||
// 负面金融词汇及其权重
|
||||
negativeFinanceWords = map[string]float64{
|
||||
"下跌": 2.0, "跌停": 3.0, "熊市": 3.0, "回调": 1.5, "新低": 2.5,
|
||||
"跌": 1.0, "下跌": 2.0, "跌停": 3.0, "熊市": 3.0, "回调": 1.5, "新低": 2.5,
|
||||
"利空": 2.5, "减持": 2.0, "卖出": 2.0, "看空": 2.0, "亏损": 2.5,
|
||||
"下滑": 2.0, "萎缩": 2.0, "不及预期": 2.5, "疲软": 1.5, "恶化": 2.0,
|
||||
"衰退": 2.0, "跌破": 2.0, "创新低": 3.0, "走弱": 1.5, "下挫": 1.5,
|
||||
"利空消息": 3.0, "收益下降": 2.5, "利润下滑": 2.5, "业绩不佳": 2.5,
|
||||
"垃圾股": 2.0, "风险股": 2.0, "弱势": 1.5, "走低": 1.5, "缩量": 2.5,
|
||||
"大跌": 2.5, "暴跌": 3.0, "崩盘": 3.0, "跳水": 3.0, "重挫": 3.0,
|
||||
"大跌": 2.5, "暴跌": 3.0, "崩盘": 3.0, "跳水": 3.0, "重挫": 3.0, "跌超": 2.5, "跌逾": 2.5,
|
||||
}
|
||||
|
||||
// 否定词,用于反转情感极性
|
||||
@@ -45,7 +53,7 @@ var (
|
||||
degreeWords = map[string]float64{
|
||||
"非常": 1.8, "极其": 2.2, "太": 1.8, "很": 1.5,
|
||||
"比较": 0.8, "稍微": 0.6, "有点": 0.7, "显著": 1.5,
|
||||
"大幅": 1.8, "急剧": 2.0, "轻微": 0.6, "小幅": 0.7,
|
||||
"大幅": 1.8, "急剧": 2.0, "轻微": 0.6, "小幅": 0.7, "逾": 1.8,
|
||||
}
|
||||
|
||||
// 转折词,用于识别情感转折
|
||||
@@ -54,12 +62,194 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 加载默认词典
|
||||
err := seg.LoadDict()
|
||||
//go:embed data/dict/base.txt
|
||||
var baseDict string
|
||||
|
||||
//go:embed data/dict/zh/s_1.txt
|
||||
var zhDict string
|
||||
|
||||
func InitAnalyzeSentiment() {
|
||||
logger.SugaredLogger.Infof("初始化词典库路径:%s", fileutil.CurrentPath())
|
||||
//加载默认词典
|
||||
err := seg.LoadDictEmbed(zhDict)
|
||||
err = seg.LoadDictEmbed(baseDict)
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Error(err.Error())
|
||||
}
|
||||
stocks := &[]StockBasic{}
|
||||
db.Dao.Model(&StockBasic{}).Find(stocks)
|
||||
for _, stock := range *stocks {
|
||||
if strutil.Trim(stock.Name) == "" {
|
||||
continue
|
||||
}
|
||||
err := seg.AddToken(stock.Name, 188888, "n")
|
||||
if strutil.Trim(stock.BKName) != "" {
|
||||
err = seg.AddToken(stock.BKName, 188888, "n")
|
||||
}
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("添加%s失败:%s", stock.Name, err.Error())
|
||||
}
|
||||
}
|
||||
stockhks := &[]models.StockInfoHK{}
|
||||
db.Dao.Model(&models.StockInfoHK{}).Find(stockhks)
|
||||
for _, stock := range *stockhks {
|
||||
if strutil.Trim(stock.Name) == "" {
|
||||
continue
|
||||
}
|
||||
err := seg.AddToken(stock.Name, 188888, "n")
|
||||
if strutil.Trim(stock.BKName) != "" {
|
||||
err = seg.AddToken(stock.BKName, 188888, "n")
|
||||
}
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("添加%s失败:%s", stock.Name, err.Error())
|
||||
}
|
||||
}
|
||||
//stockus := &[]models.StockInfoUS{}
|
||||
//db.Dao.Model(&models.StockInfoUS{}).Where("trim(name) != ?", "").Find(stockus)
|
||||
//for _, stock := range *stockus {
|
||||
// err := seg.AddToken(stock.Name, 500)
|
||||
// if err != nil {
|
||||
// logger.SugaredLogger.Errorf("添加%s失败:%s", stock.Name, err.Error())
|
||||
// }
|
||||
//}
|
||||
tags := &[]models.Tags{}
|
||||
db.Dao.Model(&models.Tags{}).Find(tags)
|
||||
for _, tag := range *tags {
|
||||
err := seg.AddToken(tag.Name, 188888, "n")
|
||||
if err != nil {
|
||||
logger.SugaredLogger.Errorf("添加%s失败:%s", tag.Name, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
logger.SugaredLogger.Info("加载词典成功")
|
||||
}
|
||||
|
||||
// WordFreqWithWeight 词频统计结果,包含权重信息
|
||||
type WordFreqWithWeight struct {
|
||||
Word string
|
||||
Frequency int
|
||||
Weight float64
|
||||
}
|
||||
|
||||
// getWordWeight 获取词汇权重
|
||||
func getWordWeight(word string) float64 {
|
||||
// 从分词器获取词汇权重
|
||||
freq, pos, _ := seg.Find(word)
|
||||
if pos == "n" {
|
||||
return freq
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// SortByWeightAndFrequency 按权重和频次排序词频结果
|
||||
func SortByWeightAndFrequency(frequencies map[string]WordFreqWithWeight) []WordFreqWithWeight {
|
||||
// 将map转换为slice以便排序
|
||||
freqSlice := make([]WordFreqWithWeight, 0, len(frequencies))
|
||||
for _, freq := range frequencies {
|
||||
freqSlice = append(freqSlice, freq)
|
||||
}
|
||||
|
||||
// 按权重降序排列,如果权重相同则按频次降序排列
|
||||
sort.Slice(freqSlice, func(i, j int) bool {
|
||||
if freqSlice[i].Weight != freqSlice[j].Weight {
|
||||
return freqSlice[i].Weight > freqSlice[j].Weight // 权重高的排前面
|
||||
}
|
||||
return freqSlice[i].Frequency > freqSlice[j].Frequency // 权重相同时频次高的排前面
|
||||
})
|
||||
|
||||
return freqSlice
|
||||
}
|
||||
|
||||
// FilterAndSortWords 过滤标点符号并按权重频次排序
|
||||
func FilterAndSortWords(frequencies map[string]WordFreqWithWeight) []WordFreqWithWeight {
|
||||
// 先过滤标点符号和分隔符
|
||||
cleanFrequencies := FilterPunctuationAndSeparators(frequencies)
|
||||
|
||||
// 再按权重和频次排序
|
||||
sortedFrequencies := SortByWeightAndFrequency(cleanFrequencies)
|
||||
|
||||
return sortedFrequencies
|
||||
}
|
||||
func FilterPunctuationAndSeparators(frequencies map[string]WordFreqWithWeight) map[string]WordFreqWithWeight {
|
||||
filteredWords := make(map[string]WordFreqWithWeight)
|
||||
|
||||
for word, freqInfo := range frequencies {
|
||||
// 过滤纯标点符号和分隔符
|
||||
if !isPunctuationOrSeparator(word) {
|
||||
filteredWords[word] = freqInfo
|
||||
}
|
||||
}
|
||||
return filteredWords
|
||||
}
|
||||
|
||||
// isPunctuationOrSeparator 判断是否为标点符号或分隔符
|
||||
func isPunctuationOrSeparator(word string) bool {
|
||||
// 空字符串
|
||||
if strings.TrimSpace(word) == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// 检查是否全部由标点符号组成
|
||||
for _, r := range word {
|
||||
if !unicode.IsPunct(r) && !unicode.IsSymbol(r) && !unicode.IsSpace(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// FilterWithRegex 使用正则表达式过滤标点和特殊字符
|
||||
func FilterWithRegex(frequencies map[string]WordFreqWithWeight) map[string]WordFreqWithWeight {
|
||||
filteredWords := make(map[string]WordFreqWithWeight)
|
||||
|
||||
// 匹配标点符号、特殊字符的正则表达式
|
||||
punctuationRegex := regexp.MustCompile(`^[[:punct:][:space:]]+$`)
|
||||
|
||||
for word, freqInfo := range frequencies {
|
||||
// 过滤纯标点符号
|
||||
if !punctuationRegex.MatchString(word) && strings.TrimSpace(word) != "" {
|
||||
filteredWords[word] = freqInfo
|
||||
}
|
||||
}
|
||||
return filteredWords
|
||||
}
|
||||
|
||||
// countWordFrequencyWithWeight 统计词频并包含权重信息
|
||||
func countWordFrequencyWithWeight(text string) map[string]WordFreqWithWeight {
|
||||
words := splitWords(text)
|
||||
freqMap := make(map[string]WordFreqWithWeight)
|
||||
|
||||
// 统计词频
|
||||
wordCount := make(map[string]int)
|
||||
for _, word := range words {
|
||||
wordCount[word]++
|
||||
}
|
||||
|
||||
// 构建包含权重的结果
|
||||
for word, frequency := range wordCount {
|
||||
weight := getWordWeight(word)
|
||||
if weight > 100 {
|
||||
freqMap[word] = WordFreqWithWeight{
|
||||
Word: word,
|
||||
Frequency: frequency,
|
||||
Weight: weight,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return freqMap
|
||||
}
|
||||
|
||||
// AnalyzeSentimentWithFreqWeight 带权重词频统计的情感分析
|
||||
func AnalyzeSentimentWithFreqWeight(text string) (SentimentResult, map[string]WordFreqWithWeight) {
|
||||
// 原有情感分析逻辑
|
||||
result := AnalyzeSentiment(text)
|
||||
|
||||
// 带权重的词频统计
|
||||
frequencies := countWordFrequencyWithWeight(text)
|
||||
|
||||
return result, frequencies
|
||||
}
|
||||
|
||||
// SentimentResult 情感分析结果类型
|
||||
|
||||
@@ -2,6 +2,8 @@ package data
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go-stock/backend/db"
|
||||
"go-stock/backend/logger"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
@@ -12,25 +14,33 @@ import (
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
func TestAnalyzeSentiment(t *testing.T) {
|
||||
// 分析情感
|
||||
text := " 【调查:韩国近两成中小学生过度使用智能手机或互联网】财联社6月19日电,韩国女性家族部18日公布的一项年度调查结果显示,接受调查的韩国中小学生中,共计约17.3%、即超过21万人使用智能手机或互联网的程度达到了“危险水平”,这意味着他们因过度依赖智能手机或互联网而需要关注或干预,这一比例引人担忧。 (新华社)\n"
|
||||
text = "消息人士称,联合利华(Unilever)正在为Graze零食品牌寻找买家。\n"
|
||||
text = "【韩国未来5年将投入51万亿韩元发展文化产业】 据韩联社,韩国文化体育观光部(文体部)今后5年将投入51万亿韩元(约合人民币2667亿元)预算,落实总统李在明在竞选时期提出的“将韩国打造成全球五大文化强国之一”的承诺。\n"
|
||||
//text = "【油气股持续拉升 国际实业午后涨停】财联社6月19日电,油气股午后持续拉升,国际实业、宝莫股份午后涨停,准油股份、山东墨龙。茂化实华此前涨停,通源石油、海默科技、贝肯能源、中曼石油、科力股份等多股涨超5%。\n"
|
||||
//text = " 【三大指数均跌逾1% 下跌个股近4800只】财联社6月19日电,指数持续走弱,沪指下挫跌逾1.00%,深成指跌1.25%,创业板指跌1.39%。核聚变、风电、军工、食品消费等板块指数跌幅居前,沪深京三市下跌个股近4800只。\n"
|
||||
text = "【银行理财首单网下打新落地】财联社6月20日电,记者从多渠道获悉,光大理财以申报价格17元参与信通电子网下打新,并成功入围有效报价,成为行业内首家参与网下打新的银行理财公司。光大理财工作人员向证券时报记者表示,本次光大理财是以其管理的混合类产品“阳光橙增盈绝对收益策略”参与了此次网下打新,该产品为光大理财“固收+”银行理财产品。资料显示,信通电子成立于1996年,核心产品包括输电线路智能巡检系统、变电站智能辅控系统、移动智能终端及其他产品。根据其招股说明书,信通电子2023、2024年营业收入分别较上年增长19.08%和7.97%,净利润分别较上年增长5.6%和15.11%。 (证券时报)"
|
||||
text = " 【以军称拦截数枚伊朗导弹】财联社6月20日电,据央视新闻报道,以军在贝尔谢巴及周边区域拦截了数枚伊朗导弹,但仍有导弹或拦截残骸落地。以色列国防军发文表示,搜救队伍正在一处“空中物体落地”的所在区域开展工作,公众目前可以离开避难场所。伊朗方面对上述说法暂无回应。"
|
||||
|
||||
db.Init("../../data/stock.db")
|
||||
InitAnalyzeSentiment()
|
||||
|
||||
messageText := strings.Builder{}
|
||||
//news := NewMarketNewsApi().GetNewsList2("", random.RandInt(500, 1000))
|
||||
//for _, telegraph := range *news {
|
||||
// messageText.WriteString(telegraph.Content + "\n")
|
||||
//}
|
||||
|
||||
text := messageText.String()
|
||||
text = " 【周六你需要知道的隔夜全球要闻:美联储鸽声重振 美股走势回稳】 1、纽约联储行长威廉姆斯表示,随着劳动力市场走软,美联储近期内仍有再次降息的空间。 2、美联储理事斯蒂芬·米兰表示,自上次联邦公开市场委员会(FOMC)会议以来的经济数据应“促使人们偏向鸽派立场”。 3、波士顿联邦储备银行行长柯林斯表示,由于通胀可能在一段时间内保持高位,维持利率不变“目前合适”。 4、据CME“美联储观察”,截至北京时间11月22日6时30分,美联储12月降息25个基点的概率为69.4%,维持利率不变的概率为30.6%。 5、美国劳工统计局表示,11月CPI报告将于12月18日发布,同时取消了10月CPI报告发布,表示无法追溯采集政府停摆期间未能收集的部分数据。 6、俄罗斯总统普京表示,已收到美提出解决俄乌冲突的计划,俄罗斯愿意进行和平谈判。美国总统特朗普表示,他认为27日是乌克兰接受美国支持的和平计划的最后期限。 7、美联储高官鸽派言论提振市场情绪,美股三大指数收盘集体上涨,道琼斯指数涨1.08%,标普500指数涨0.98%,纳斯达克综合指数涨0.88%。甲骨文跌超5%,英伟达跌超1%。纳指本周累计跌2.74%,标普500指数累跌1.95%,道指累跌1.91%。英伟达本周累跌5.9%。 8、热门中概股多数上涨,纳斯达克中国金龙指数收涨1.23%。蔚来涨超3%,哔哩哔哩、理想汽车涨超2%,京东、小鹏汽车涨超1%。 9、国际油价下跌,交易员评估乌克兰与俄罗斯可能达成和平协议的前景。WTI 1月期货下跌1.6%,结算价报每桶58.06美元,为过去五个交易日中第四次下跌。布伦特1月期货下跌1.3%,结算价报每桶62.56美元。 10、美联储延长压力测试改进方案征询期,为银行反馈提供更多时间。 11、由于美国人对个人财务状况的看法恶化,美国消费者信心在11月跌至接近纪录最低水平;密歇根大学数据显示,11月消费者信心指数降至51,10月为53.6。 12、日本央行政策委员会委员Kazuyuki Masu表示,日本央行接近作出加息决定。 13、穆迪将意大利信用评级从BAA3上调至BAA2,展望稳定。\n"
|
||||
|
||||
// 分析情感
|
||||
words := splitWords(text)
|
||||
fmt.Println(strings.Join(words, " "))
|
||||
|
||||
result := AnalyzeSentiment(text)
|
||||
|
||||
result, frequencies := AnalyzeSentimentWithFreqWeight(text)
|
||||
// 过滤标点符号和分隔符
|
||||
cleanFrequencies := FilterPunctuationAndSeparators(frequencies)
|
||||
// 输出结果
|
||||
fmt.Printf("情感分析结果: %s (得分: %.2f, 正面词:%d, 负面词:%d)\n",
|
||||
logger.SugaredLogger.Infof("情感分析结果: %s (得分: %.2f, 正面词:%d, 负面词:%d)\n 词频统计结果: %v",
|
||||
result.Description,
|
||||
result.Score,
|
||||
result.PositiveCount,
|
||||
result.NegativeCount)
|
||||
result.NegativeCount,
|
||||
cleanFrequencies,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@@ -11,6 +11,7 @@ declare module 'vue' {
|
||||
About: typeof import('./src/components/about.vue')['default']
|
||||
AgentChat: typeof import('./src/components/agent-chat.vue')['default']
|
||||
AgentChat_bk: typeof import('./src/components/agent-chat_bk.vue')['default']
|
||||
AnalyzeMartket: typeof import('./src/components/AnalyzeMartket.vue')['default']
|
||||
ClsCalendarTimeLine: typeof import('./src/components/ClsCalendarTimeLine.vue')['default']
|
||||
EmbeddedUrl: typeof import('./src/components/EmbeddedUrl.vue')['default']
|
||||
Fund: typeof import('./src/components/fund.vue')['default']
|
||||
|
||||
11
frontend/src/components/AnalyzeMartket.vue
Normal file
11
frontend/src/components/AnalyzeMartket.vue
Normal file
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import {computed, h, onBeforeMount, onBeforeUnmount, onMounted, ref} from 'vue'
|
||||
import * as echarts from "echarts";
|
||||
import {computed, h, onBeforeMount, onBeforeUnmount, onMounted,onUnmounted, ref} from 'vue'
|
||||
import {
|
||||
GetAIResponseResult,
|
||||
GetConfig,
|
||||
@@ -12,7 +13,7 @@ import {
|
||||
SaveAsMarkdown,
|
||||
ShareAnalysis,
|
||||
SummaryStockNews,
|
||||
GetAiConfigs
|
||||
GetAiConfigs, AnalyzeSentimentWithFreqWeight
|
||||
} from "../../wailsjs/go/main/App";
|
||||
import {EventsOff, EventsOn} from "../../wailsjs/runtime";
|
||||
import NewsList from "./newsList.vue";
|
||||
@@ -75,6 +76,8 @@ const indexInterval = ref(null)
|
||||
const indexIndustryRank = ref(null)
|
||||
const stockCode= ref('')
|
||||
const enableTools= ref(true)
|
||||
const treemapRef = ref(null);
|
||||
let treemapchart =null;
|
||||
|
||||
function getIndex() {
|
||||
GlobalStockIndexes().then((res) => {
|
||||
@@ -120,7 +123,13 @@ onBeforeMount(() => {
|
||||
indexIndustryRank.value = setInterval(() => {
|
||||
industryRank()
|
||||
}, 1000 * 10)
|
||||
|
||||
|
||||
})
|
||||
onMounted(() => {
|
||||
Analyze() // 页面显示
|
||||
})
|
||||
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
EventsOff("changeMarketTab")
|
||||
@@ -131,8 +140,12 @@ onBeforeUnmount(() => {
|
||||
clearInterval(indexIndustryRank.value)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
||||
});
|
||||
EventsOn("changeMarketTab", async (msg) => {
|
||||
//message.info(msg.name)
|
||||
console.log(msg.name)
|
||||
updateTab(msg.name)
|
||||
})
|
||||
|
||||
@@ -142,6 +155,7 @@ EventsOn("newTelegraph", (data) => {
|
||||
telegraphList.value.pop()
|
||||
}
|
||||
telegraphList.value.unshift(...data)
|
||||
Analyze() // 页面显示
|
||||
}
|
||||
})
|
||||
EventsOn("newSinaNews", (data) => {
|
||||
@@ -150,6 +164,7 @@ EventsOn("newSinaNews", (data) => {
|
||||
sinaNewsList.value.pop()
|
||||
}
|
||||
sinaNewsList.value.unshift(...data)
|
||||
Analyze() // 页面显示
|
||||
}
|
||||
})
|
||||
|
||||
@@ -158,6 +173,32 @@ window.onresize = () => {
|
||||
panelHeight.value = window.innerHeight - 240
|
||||
}
|
||||
|
||||
function Analyze(){
|
||||
console.log("treemapchart:",treemapchart)
|
||||
console.log("treemapRef:",treemapRef.value)
|
||||
treemapchart = echarts.init(treemapRef.value);
|
||||
treemapchart.showLoading()
|
||||
AnalyzeSentimentWithFreqWeight("").then((res) => {
|
||||
|
||||
let option = {
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'treemap',
|
||||
data: res['frequencies'].slice(0, 20).map(item => ({
|
||||
name: item.Word,
|
||||
value: item.Frequency,
|
||||
}))
|
||||
}
|
||||
]
|
||||
};
|
||||
treemapchart.setOption(option);
|
||||
treemapchart.hideLoading()
|
||||
})
|
||||
}
|
||||
|
||||
function getAreaName(code) {
|
||||
switch (code) {
|
||||
case "america":
|
||||
@@ -232,6 +273,9 @@ function getAiSummary() {
|
||||
function updateTab(name) {
|
||||
summaryBTN.value = (name === "市场快讯");
|
||||
nowTab.value = name
|
||||
if (name === "市场快讯") {
|
||||
Analyze()
|
||||
}
|
||||
}
|
||||
|
||||
EventsOn("summaryStockNews", async (msg) => {
|
||||
@@ -320,14 +364,22 @@ function ReFlesh(source) {
|
||||
<n-card>
|
||||
<n-tabs type="line" animated @update-value="updateTab" :value="nowTab" style="--wails-draggable:no-drag">
|
||||
<n-tab-pane name="市场快讯" tab="市场快讯">
|
||||
<n-grid :cols="2" :y-gap="0">
|
||||
<n-grid :cols="1" :y-gap="0">
|
||||
<n-gi>
|
||||
<news-list :newsList="telegraphList" :header-title="'财联社电报'" @update:message="ReFlesh"></news-list>
|
||||
<div ref="treemapRef" style="width: 100%;height: 300px;" ></div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<news-list :newsList="sinaNewsList" :header-title="'新浪财经'" @update:message="ReFlesh"></news-list>
|
||||
<n-grid :cols="2" :y-gap="0">
|
||||
<n-gi>
|
||||
<news-list :newsList="telegraphList" :header-title="'财联社电报'" @update:message="ReFlesh"></news-list>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<news-list :newsList="sinaNewsList" :header-title="'新浪财经'" @update:message="ReFlesh"></news-list>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="全球股指" tab="全球股指">
|
||||
<n-tabs type="segment" animated>
|
||||
|
||||
2
frontend/wailsjs/go/main/App.d.ts
vendored
2
frontend/wailsjs/go/main/App.d.ts
vendored
@@ -14,6 +14,8 @@ export function AddStockGroup(arg1:number,arg2:string):Promise<string>;
|
||||
|
||||
export function AnalyzeSentiment(arg1:string):Promise<data.SentimentResult>;
|
||||
|
||||
export function AnalyzeSentimentWithFreqWeight(arg1:string):Promise<Record<string, any>>;
|
||||
|
||||
export function ChatWithAgent(arg1:string,arg2:number,arg3:any):Promise<void>;
|
||||
|
||||
export function CheckSponsorCode(arg1:string):Promise<Record<string, any>>;
|
||||
|
||||
@@ -22,6 +22,10 @@ export function AnalyzeSentiment(arg1) {
|
||||
return window['go']['main']['App']['AnalyzeSentiment'](arg1);
|
||||
}
|
||||
|
||||
export function AnalyzeSentimentWithFreqWeight(arg1) {
|
||||
return window['go']['main']['App']['AnalyzeSentimentWithFreqWeight'](arg1);
|
||||
}
|
||||
|
||||
export function ChatWithAgent(arg1, arg2, arg3) {
|
||||
return window['go']['main']['App']['ChatWithAgent'](arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user