资讯详情

资讯详情

DeepSeek证券研报自动化生成:从数据到策略的闭环实践

简介这是一份围绕DeepSeek模型在证券研报自动化生成场景落地的技术方案面向金融数据分析师、量化研究及AI工程人员系统解决多源金融数据处理、研报结构化生成与投资策略自动提炼等关键问题。文档共257页、48个大章节从多源异构数据接入、财经文本噪声过滤、量化数据归一化到Embedding模型选型与调优、金融Prompt指令设计、研报Schema字段映射与逻辑关联再到数据标注体系构建、DeepSeek-R1预训练与监督微调、分布式训练与梯度稳定性优化、LoRA/QLoRA低资源微调、模型效果评估等完整覆盖证券研报自动化生成的全链路兼顾原理讲解与工程落地。内容支持书签大纲和章节快速跳转编排清晰便于按需查阅。压缩包为单份PDF格式大小11.71MB体积精简但体系完整。目前已有177人学习浏览适合作为从数据预处理到模型落地的全链路参考亦可作为金融AI项目的技术蓝图。1. DeepSeek证券研报自动化生成方案从数据到策略的一次闭环重构证券研报的痛点不是字数不够而是“数据到结论”这一段几乎全靠人工。分析师白天梳理行情、晚上写长文重复劳动把深度研究的时间挤掉了。DeepSeek出现后一个可行的自动化路径浮现出来用金融数据分析模块把原始行情、财务数据变成结构化的指标和信号再交给DeepSeek生成研报正文和投资策略规则最后用回测验证策略有效性。这套方案适合三类人需要批量覆盖多标的的卖方研究员、构建内部投研工具的量化团队、以及想在自选股上跑通“数据→观点”闭环的独立投资者。它不追求替代人而是把“写报告”这件事从手工变成半监督流程——人负责定调、纠错、决策模型负责把数据和逻辑组织成可读、可利用的内容。2. DeepSeek证券研报自动化生成的流水线与API调用2.1 从数据到研报自动化生成的整体链路一个可用的研报生成系统不能只靠“把行情粘贴给DeepSeek”。模型不知道昨天的收盘价意味着什么除非你先告诉它。我一般会把整条链路拆成四段数据采集、分析计算、内容生成、回测反馈。数据采集负责拉取股票日线、财务指标、行业对比数据分析计算负责算出动量、估值、资金流等因子内容生成是DeepSeek的活它需要接收一段“已经整理成句子或结构化字段”的输入回测反馈则把生成的策略规则放回历史数据里跑一遍验证收益曲线和回撤。这四段里最容易做坏的是第一段和第三段的衔接。很多人直接把DataFrame打印出来丢进提示词结果模型输出一堆“根据以上数据可以看出……”。要避免这个得在提示词里明确告诉模型数据是经过预处理的不要复述直接给结论。同时研报的结构也要预先定义比如“市场综述、个股分析、风险提示”三个固定板块模型在固定框架里填内容质量远比自由发挥稳定。从技术选型角度看数据端用Python生态最省事pandas处理表格akshare或tushare取行情这些工具在社区里已经成熟。生成端直接调DeepSeek API不推荐在本地跑大模型因为研报需要长上下文和批量处理API的推理速度和并发上限更适合生产环境。如果你只是实验可以用deepseek官方给的示例代码如果是团队用建议在API外面包一层队列避免触发限流。2.2 DeepSeek API的基础调用一个最小可用的请求选好链路后先跑通最小的API调用确认模型能正常返回。我用Python的标准requests库避免引入过重依赖。下面这个示例会请求DeepSeek的对话补全接口让它根据一段简短的金融数据输出研报开头。import requests import json payload { model: deepseek-chat, messages: [ {role: system, content: 你是证券研报分析师输出要简洁、客观、有数据支撑。}, {role: user, content: XX股票近5日收盘价10.2, 10.5, 10.3, 10.8, 11.0成交量放大请写一段50字以内的市场观察。} ], temperature: 0.3, max_tokens: 200 } resp requests.post( https://api.deepseek.com/chat/completions, headers{Authorization: Bearer YOUR_API_KEY, Content-Type: application/json}, jsonpayload, timeout30 ) result resp.json() print(result[choices][0][message][content])这里有个容易被忽略的点messages里system和user的角色区分。system规定模型的全局行为比如“你是证券研报分析师”user是具体任务。如果只在user里写要求模型容易把“输出简洁”这种指令当成报告内容的一部分导致开头出现“根据您的要求我将简要分析……”这类废话。temperature要低于0.5研报生成不需要创造性过高的温度会让模型编造数据。max_tokens控制输出长度研报段落建议设成500到1000单次请求太长容易被截断。跑通这个最小请求之后你会发现一个问题模型输出的是纯文本拿不到字段化的“投资评级”或“目标价”。这时就需要改用结构化输出方案。2.3 用JSON Schema约束研报的结构化输出纯文本研报只能给人看不能直接进下游系统。如果想让“投资评级”自动变成数据表里的一个字段需要让模型返回JSON。DeepSeek兼容OpenAI的response_format参数可以直接指定json_object。下面是一个为研报自动生成设计的请求示例import requests json_schema { type: object, properties: { summary: {type: string}, rating: {type: string, enum: [买入, 增持, 中性, 减持]}, target_price: {type: number}, risk_factors: {type: array, items: {type: string}} }, required: [summary, rating, target_price, risk_factors] } payload { model: deepseek-chat, messages: [ {role: system, content: 你是研报生成器必须输出JSON不要输出其他内容。}, {role: user, content: 依据以下数据生成研报要点PE25, 营收增速15%, 行业景气度高。输出JSON} ], response_format: {type: json_object}, temperature: 0.2, max_tokens: 300 } resp requests.post( https://api.deepseek.com/chat/completions, headers{Authorization: Bearer YOUR_API_KEY, Content-Type: application/json}, jsonpayload, timeout30 ) try: content resp.json()[choices][0][message][content] structured json.loads(content) print(structured[rating], structured[target_price]) except KeyError: print(模型没有返回合法JSON检查response_format或增加few-shot示例)response_format的参数值是json_object它保证输出是合法JSON但不会校验字段结构。字段名拼错、枚举值不在预设列表里模型都可能犯。所以我在代码里加了json.loads以及后续的字段存在性检查。更稳妥的做法是在system提示词里写清楚“target_price必须是数字不允许带单位”同时在解析层做一个默认值兜底。结构化输出的价值在于研报生成完成后summary直接进文档库rating和target_price进数据库risk_factors作为标签参与筛选。这样研报不再是孤立的PDF而是一个可聚合、可回测的数据实体。3. 金融数据分析让DeepSeek看到数字背后的信号3.1 金融数据的获取与预处理DeepSeek训练时看过无数行数字但它不知道今天的行情是新的。所以喂给它的数据必须是“这一刻拉到的、已经清洗过的”数据。我用akshare取A股日线因为它是免费且不需要token的适合自动化脚本。数据拿到后要做两件事去重和补缺失值。import akshare as ak import pandas as pd # 获取XX股票最近120个交易日数据 df ak.stock_zh_a_hist(symbol000001, perioddaily, start_date20240101, end_date20241231, adjustqfq) # 重命名列便于后续处理 df.rename(columns{日期: date, 开盘: open, 收盘: close, 最高: high, 最低: low, 成交量: volume}, inplaceTrue) # 按日期排序删除重复行 df df.sort_values(date).drop_duplicates(subsetdate).reset_index(dropTrue) # 成交量缺失则用前值填充 df[volume].fillna(methodffill, inplaceTrue) print(df.tail(5))adjustqfq是指前复权解决了分红送股导致的价格跳空问题回测和趋势分析必须用复权价。drop_duplicates是因为有些数据源会在盘中多次更新同一日期的记录不清理会让后面的指标计算出现重复信号。ffill处理停牌导致的成交量缺失注意如果连续缺失超过5天应该直接剔除而不是填充因为长期停牌复牌后的价格行为是特殊的。预处理完的数据不应该直接喂给DeepSeek因为模型无法从综复杂的数据列表里准确提取趋势。需要先计算出人脑能理解的指标。3.2 技术指标计算与信号生成技术指标是把价格翻译成信号的中间层。MA和RSI是最容易被模型理解的MA说明趋势方向RSI说明超买超卖。下面这段代码会生成三个字段5日均线斜率、RSI14、以及一个组合信号“金叉/死叉”。df[ma5] df[close].rolling(window5).mean() df[ma20] df[close].rolling(window20).mean() df[ma5_slope] df[ma5].diff(3) # 5日均线3日变化量 # 计算RSI14 delta df[close].diff() gain delta.clip(lower0) loss -delta.clip(upper0) avg_gain gain.rolling(window14).mean() avg_loss loss.rolling(window14).mean() rs avg_gain / avg_loss df[rsi14] 100 - (100 / (1 rs)) # 金叉死叉信号 df[cross] None df.loc[df[ma5] df[ma20], cross] 金叉 df.loc[df[ma5] df[ma20], cross] 死叉 # 只看最后一天的信号 last df.iloc[-1] context { date: last[date], close: last[close], ma5_slope: round(last[ma5_slope], 2), rsi14: round(last[rsi14], 2), cross_signal: last[cross] } print(context)ma5_slope用diff(3)是为了消除日间波动噪声只看趋势是否延续。RSI的计算里有一个除零风险当avg_loss为0时rs会变成无穷大我一般会在计算后加一个fillna(100)处理。组合信号比单个指标更适合让DeepSeek推理因为金叉死叉本质上已经是一个“市场状态”的结论模型只需要围绕这个结论补充理由。这里要提醒技术指标是研报的素材不是决策依据。DeepSeek生成的“建议”必须基于你提供的指标值而不是它自己想象的K线。所以上下文里要明确写上“MA20大于MA5说明短期趋势强于长期”。3.3 把分析结果组装成DeepSeek的上下文数据算完了接下来是构建提示词。我见过很多失败的生成案例原因都是上下文排列太乱——先给财报再给行情最后又说了一遍行业模型抓不住重点。我习惯把上下文组织成三段市场环境、个股数据、分析要求。prompt f 【市场环境】当前日期{context[date]}大盘指数处于震荡区间成交额较前5日放大12%。 【个股数据】股票代码000001收盘价{context[close]}元。 1. 5日均线3日变化量{context[ma5_slope]}元正数代表短期趋势向上 2. RSI14{context[rsi14]}70超买30超卖 3. 均线状态{context[cross_signal]}金叉表示短期均线上穿长期均线 【分析要求】 1. 结合以上数据写一段200字的个股技术面分析不要复述数据本身直接给出对趋势和操作的含义。 2. 给出投资评级枚举值为买入、增持、中性、减持。 3. 给出目标价格式为数字。 这段提示词的关键在于每个指标后面都带了“解读方向”比如“正数代表短期趋势向上”这能防止模型把ma5_slope当成一个无意义的随机数字。同时“不要复述数据”这句话降低模型的废话率。如果生成的报告里还是出现“根据数据”的套话我会在system里加一句“直接下结论不要提数据来源”。组装好上下文后把它放进messages的user部分配合第2章的结构化输出参数就能得到“字段级”的研报内容。整个流程从拉数据到出JSON可以在20秒内完成批量跑几百只股票时唯一瓶颈就是API并发限制。4. 投资策略自动生成与回测验证4.1 用DeepSeek生成策略规则与参数研报只是起点真正的目标是投资策略自动生成。传统做法是把指标阈值人肉写死比如“RSI小于30买入”。但DeepSeek可以根据历史数据里的统计特征提出策略规则甚至给出参数建议。下面是一个让模型生成策略的提示词prompt f 你是一个量化策略研究员。基于以下某股票的日线统计特征生成一个交易策略 - 近60日收益率波动率0.82% - 20日均线与5日均线差值分布平均差0.15元最大差0.4元 - RSI14分位数20%分位28.580%分位71.2 要求 1. 策略规则用一句话描述必须包含买入和卖出条件。 2. 给出策略的三组参数阈值、持有天数、止损比例。 3. 用JSON输出字段包括 rule, params, rationale。 模型生成的可能是这样的输出rule: 当RSI14低于32且5日均线斜率转正时买入持有5天或RSI超过70卖出。你会发现规则基本合理但存在过拟合风险——因为它是根据历史分位数猜的阈值。所以要进入回测验证规则在历史行情上是否真的赚钱。这里有个认知误区不要指望DeepSeek直接生成一个稳定盈利的策略它的作用是快速生成“有逻辑的假设”。假设的检验必须交给回测框架用数据说话。4.2 回测框架的选择与接入回测我用的是backtrader因为社区文档多遇到问题容易查。DeepSeek生成的策略规则是一个自然语言描述接入回测前需要人工翻译成代码。这是个半自动的过程我一般先把rule拆成“买入条件”和“卖出条件”两个函数填入下面这个模板import backtrader as bt class DeepSeekStrategy(bt.Strategy): params dict( rsi_buy32, rsi_sell70, hold_days5, stop_loss0.05 ) def __init__(self): self.rsi bt.indicators.RSI(self.data.close, period14) self.ma5 bt.indicators.SimpleMovingAverage(self.data.close, period5) self.ma5_slope self.ma5 - self.ma5(-1) self.hold_count 0 def next(self): if self.position: self.hold_count 1 if self.rsi[0] self.p.rsi_sell or self.hold_count self.p.hold_days: self.close() self.hold_count 0 else: if self.rsi[0] self.p.rsi_buy and self.ma5_slope[0] 0: self.buy(size100) self.hold_count 0这段代码里self.ma5_slope是前一天收盘与今天的差值表示均线方向。buy之后用hold_count计数强制持有天数防止策略一直扛单。stop_loss参数目前没接入我简化了逻辑实际使用时要加订单回调检查止损。回测运行三分钟你会看到收益率曲线和最大回撤。如果最大回撤超过20%说明规则太敏感如果交易次数少于10次说明阈值太严格。根据回测结果修改params里的阈值再喂回给DeepSeek让它做一次参数重新建议——这形成了一个“生成-回测-修正”的闭环。4.3 回测结果反馈与迭代优化回测不是为了证明策略赚钱而是给DeepSeek一个“反馈信号”。我通常会把回测报告里的关键指标——累计收益率、年化波动率、夏普比率、最大回撤——拼接成一段文字加上当前策略规则请求DeepSeek给出优化建议。feedback f 当前策略规则{rule} 近5年回测结果 - 累计收益率18.3% - 年化波动率12.1% - 最大回撤24.5% - 交易次数42次 请分析策略的主要问题并给出3个改进方向的参数建议。输出JSON。 这个反馈循环的价值在于DeepSeek能看到每个参数对结果的量化影响。比如它可能会建议“降低买入阈值因为RSI32在牛市里很少触发导致交易次数过少”。这类建议通常是合理的但仍需回测确认。实际使用中我会把整个迭代过程控制在三轮以内超过三轮模型容易过拟合而且会为了追求正收益编造不合理的逻辑。需要注意回测框架本身也有陷阱比如前视偏差、手续费未计入。所以我的回测里固定设置了commission0.001并且在next()里不允许使用未来数据。DeepSeek生成的策略规则如果涉及“未来函数”比如“当明天涨停时买入”必须直接丢弃。5. 进阶用法DeepSeek harness与本地部署排错5.1 用DeepSeek harness固化研报生成流程当你把第2到第4章的脚本文件夹聚起来后会发现每次跑批量研报都要手动改股票代码、日期范围还容易漏掉prompt里的某个字段。这就是DeepSeek harness的用武之地——它可以把“拉数据→算指标→调API→解析JSON→写回数据库”串联成一个后台服务。harness本质上是一个工作流编排层类似轻量级的任务队列而不是又一个API封装。我通常会在harness里定义两个任务generate_report(stock_code, date)和backtest_strategy(rule, params)。前者负责调用第3章的数据处理函数后者负责把第4章的回测脚本跑起来。这样每次新增股票只需要调用generate_report不用再打开Jupyter Notebook。harness还会自动记录每次生成的prompt和response方便追溯模型输出异常的原因——这个能力在纯脚本里是缺失的。如果你不想引入额外依赖可以直接用Python的subprocess调度脚本但对于需要监控日志、失败重试的场景harness的队列机制能减少很多人工干预。5.2 常见报错与参数调优最后一章分享三个高频问题。第一个是rate limit错误原因是并发请求太多。解法是在harness里加一个信号量限制同时只有5个请求在飞够用且不需要改API端配置。第二个是模型返回内容被max_tokens截断导致JSON解析失败。我一般把max_tokens设成输出预期长度的1.5倍并在解析前用json.loads捕获异常发现截断就自动用更精简的prompt重试一次。第三个是temperature过高导致评级与数据不符比如PE 50还给出“买入”。检查一下你的system提示词把“评级必须基于给定数据不要外部推测”写上同时把温度降到0.2以下。关于本地部署DeepSeek如果数据敏感必须内网闭环可以用llama.cpp或者vLLM跑量化版模型然后修改API基地址为http://localhost:8000。但要注意本地小参数的模型生成研报的专业度会明显下降长上下文性能也会缩水。我的建议是先用API验证流程确认提示词稳定后再上本地部署不要一开始就和模型质量较劲。研报自动化的核心价值是结构化地压缩信息而不是让模型成为第一个垫脚石。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →