From c782246a1d6920ebfa0548275639a5fc9802c31a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Sun, 9 Mar 2025 23:51:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E6=8F=90=E7=A4=BA?= =?UTF-8?q?=E8=AF=8D=E5=B7=A5=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Managers/NewsManager.cs | 66 ++++++++++- .../Managers/StockMarketManager.cs | 111 +++++++++++++++--- 2 files changed, 158 insertions(+), 19 deletions(-) diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs index dafc4c12..c725a035 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs @@ -3,6 +3,7 @@ using Yi.Framework.SqlSugarCore.Abstractions; using Yi.Framework.Stock.Domain.Entities; using Yi.Framework.Stock.Domain.Managers.SemanticKernel; using Yi.Framework.Stock.Domain.Managers.SemanticKernel.Plugins; +using System.Text; namespace Yi.Framework.Stock.Domain.Managers; @@ -16,17 +17,72 @@ public class NewsManager:DomainService _newsRepository = newsRepository; } + /// + /// 获取最近的新闻 + /// + /// 获取数量 + /// 最近的新闻列表 + public async Task> GetRecentNewsAsync(int count = 10) + { + return await _newsRepository._DbQueryable + .OrderByDescending(n => n.CreationTime) + .Take(count) + .Select(n => new StockNewsAggregateRoot + { + Title = n.Title, + Summary = n.Summary, + Source = n.Source, + CreationTime = n.CreationTime + }) + .ToListAsync(); + } + /// /// 生成一个新闻 /// /// public async Task GenerateNewsAsync() - { var question = """ - 生成并保存一个新闻,包含新闻标题、新闻内容、新闻简介、新闻来源 - 内容关于娱乐圈 - 只用生成一次即可 + { + // 获取最近10条新闻 + var recentNews = await GetRecentNewsAsync(10); + + // 构建新闻背景上下文 + var newsContext = new StringBuilder(); + if (recentNews.Any()) + { + newsContext.AppendLine("以下是最近的新闻简介:"); + foreach (var news in recentNews) + { + newsContext.AppendLine($"- {news.CreationTime:yyyy-MM-dd} 来源:{news.Source}"); + newsContext.AppendLine($" 标题:{news.Title}"); + newsContext.AppendLine($" 简介:{news.Summary}"); + newsContext.AppendLine(); + } + } + else + { + newsContext.AppendLine("目前没有最近的新闻记录。"); + } + + var question = $$""" + 基于以下最近的新闻背景,生成一条新的股市相关新闻。 + + {{newsContext}} + + 请生成一条有关联性的新闻,包含以下要素: + 1. 新闻标题:吸引人且与股市、金融或经济相关 + 2. 新闻内容:详细且符合逻辑的报道,篇幅适中 + 3. 新闻简介:简明扼要的总结 + 4. 新闻来源:提供一个可信的媒体或机构名称 + + 注意: + - 新闻内容应当与前面的新闻有一定关联性 + - 内容应当暗示可能对股市产生某种影响(积极或消极) + - 行业焦点可以包括娱乐、科技、能源、金融等多个领域 + - 只需生成一次即可 """; - await _skClient.ChatCompletionAsync(question, ("NewsPlugins","save_news")); + + await _skClient.ChatCompletionAsync(question, ("NewsPlugins","save_news")); } public async Task SaveNewsAsync(NewsModel news) diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs index 532e33e6..44d0f96b 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/StockMarketManager.cs @@ -11,6 +11,7 @@ using Yi.Framework.SqlSugarCore.Abstractions; using Yi.Framework.Stock.Domain.Managers.SemanticKernel; using Yi.Framework.Stock.Domain.Managers.SemanticKernel.Plugins; using Microsoft.Extensions.Hosting; +using System.Text; namespace Yi.Framework.Stock.Domain.Managers { @@ -29,6 +30,7 @@ namespace Yi.Framework.Stock.Domain.Managers private readonly ILocalEventBus _localEventBus; private readonly SemanticKernelClient _skClient; private readonly IHostEnvironment _hostEnvironment; + private readonly NewsManager _newsManager; public StockMarketManager( ISqlSugarRepository stockHoldingRepository, @@ -37,7 +39,8 @@ namespace Yi.Framework.Stock.Domain.Managers ISqlSugarRepository stockMarketRepository, ILocalEventBus localEventBus, SemanticKernelClient skClient, - IHostEnvironment hostEnvironment) + IHostEnvironment hostEnvironment, + NewsManager newsManager) { _stockHoldingRepository = stockHoldingRepository; _stockTransactionRepository = stockTransactionRepository; @@ -46,6 +49,7 @@ namespace Yi.Framework.Stock.Domain.Managers _localEventBus = localEventBus; _skClient = skClient; _hostEnvironment = hostEnvironment; + _newsManager = newsManager; } /// @@ -346,29 +350,108 @@ namespace Yi.Framework.Stock.Domain.Managers await BatchSaveStockPriceRecordsAsync(priceRecords); } } + + /// + /// 获取所有活跃股票的最新价格 + /// + /// 股票ID和最新价格的字典 + private async Task> GetLatestStockPricesAsync() + { + // 获取所有活跃的股票 + var activeStocks = await _stockMarketRepository.GetListAsync(s => s.State && !s.IsDeleted); + var result = new Dictionary(); + + foreach (var stock in activeStocks) + { + try + { + var price = await GetCurrentStockPriceAsync(stock.Id); + result.Add(stock.Id, price); + } + catch + { + // 如果获取价格失败,使用默认值或跳过 + continue; + } + } + + return result; + } + /// /// 生成最新股票记录 /// /// public async Task GenerateStocksAsync() { - var question = """ - 根据给出的模拟新闻,模拟生成多家股票未来价格 + // 获取所有活跃股票的最新价格 + var stockPrices = await GetLatestStockPricesAsync(); + if (!stockPrices.Any()) + { + return; // 没有股票数据,直接返回 + } + + // 获取所有活跃股票信息,用于构建提示词 + var activeStocks = await _stockMarketRepository.GetListAsync(s => + s.State && !s.IsDeleted && stockPrices.Keys.Contains(s.Id)); + + // 获取最近10条新闻 + var recentNews = await _newsManager.GetRecentNewsAsync(10); + + // 构建新闻上下文 + var newsContext = new StringBuilder(); + if (recentNews.Any()) + { + newsContext.AppendLine("以下是最近的新闻摘要:"); + foreach (var news in recentNews) + { + newsContext.AppendLine($"- {news.CreationTime:yyyy-MM-dd}: {news.Title}"); + newsContext.AppendLine($" {news.Summary}"); + newsContext.AppendLine(); + } + } + else + { + newsContext.AppendLine("最近没有重要新闻报道。"); + } + + // 构建股票信息上下文 + var stocksContext = new StringBuilder(); + stocksContext.AppendLine("以下是需要预测的股票信息:"); + foreach (var stock in activeStocks) + { + if (stockPrices.TryGetValue(stock.Id, out var price)) + { + stocksContext.AppendLine($"{stock.MarketName}:id:{stock.Id} 最后一次价格:{price:F2}"); + } + } + + var question = $$""" + 根据最近的新闻和当前股票价格,预测多家股票未来24小时的价格走势 - 以下是近期新闻: - ai势力逐步崛起 - 大量网红下岗 - 近期群星演唱会即将开幕 + {{newsContext}} - 以下是多个股票: - 伦敦股票:id:3a1886d5-1479-5402-3bcb-063e989898d1 最后一次价格:188.7 - 上海股票:id:3a1886d5-4393-606c-b040-52f1ef7d2158 最后一次价格:125.2 - 纽约股票:id:3a1886d5-6906-8f30-d955-198fbcfe4026 最后一次价格:185.5 + {{stocksContext}} - 根据上面信息,给每个股票返回未来24小时的股票价格,每个小时,整点为单位一条记录,一家共有24条,返回股票id 与 长度为24的价格列表 - 只用生成一次即可 + 请分析上述新闻对各个股票可能产生的影响,并预测每支股票未来24小时的价格变动: + 1. 考虑新闻中提到的行业、公司或经济趋势 + 2. 分析这些因素对不同股票的积极或消极影响 + 3. 根据分析生成合理的价格波动 + + 对每支股票,请返回: + - 股票id + - 一个长度为24的价格数组,表示未来24小时(每小时整点)的预测价格 + + 价格变动应当符合以下规则: + - 相邻时间点的价格波动通常不超过前值的20% + - 考虑市场开盘和收盘时间可能带来的较大波动 + - 不同股票之间的相关性(如同行业股票可能有类似走势) + - 部分股票可能对某些新闻更敏感 + + 请确保数据格式正确,以便系统能够自动处理。 """; - await _skClient.ChatCompletionAsync(question,("StockPlugins","save_stocks")); + + await _skClient.ChatCompletionAsync(question, ("StockPlugins", "save_stocks")); } } } \ No newline at end of file