每年四五月份,最忙的就是带毕业设计的老师。大数据专业的同学一窝蜂报"股票预测",但真正能把项目做得像样的不多。所谓"Django+LLM大模型股票行情预测系统",说白了就是以Django做Web框架,接入大模型(LLM)分析行情数据,再叠加量化交易策略回测的完整Web系统。这套东西之所以在毕设题目里受欢迎,是因为它把大数据分析、机器学习/深度学习、前后端开发、量化交易甚至最新的LLM应用全串在了一个项目里,工作量饱满,答辩也有话讲。接下来这篇文章,我就把这个题目的完整拆解思路、技术选型、核心实现和避坑经验全部写出来,手把手给准备做同类毕设的同学参考。
1. 选题动机和系统定位:LLM大模型在股票预测系统中的角色边界
1.1 别让评委问倒:你能讲明白LLM到底在预测什么吗
很多学生习惯把"股票行情预测"理解成"让大模型直接算明天涨跌",做出来的系统就是一个聊天框,输入股票代码问一句"明天会涨吗",然后LLM象征性输出一段模棱两可的话。这种设计在中级答辩中几乎必死,因为评委稍微懂点技术就会追问:你的模型在哪里训练?你用了什么数据?这个预测结果怎么验证?
真正合理的定位是:LLM不直接预测价格,而是作为"语义分析引擎+结构化决策辅助器"。系统先通过传统量化指标(RSI、MACD、KDJ等)计算行情特征,然后把这些特征数据、近期K线摘要、甚至新闻情感结果一起丢给LLM,让它基于已有信息生成一份带结构化评分的分析报告。它回答的是"当前市场状态怎么样、该不该谨慎、趋势偏多还是偏空",而不是"明天就涨停"。
这个定位有几个好处:第一,技术上不虚假,LLM本身不具备时序外推能力,说它直接预测回归值是站不住脚的;第二,把它当作自然语言接口和推理引擎,恰好能放大LLM的优势;第三,把传统特征工程和LLM结合,是一种可解释、可扩展的架构,答辩时有得聊。我还会在系统里加一行提示"本结果仅供技术学习演示,不构成任何投资建议",既显得严谨,也避免评委被带偏。
1.2 Django在毕设里的分工不是"画页面"
我见过太多同学把Django当成一个简单的HTML模板工具,然后将所有计算逻辑塞进views.py,最后页面各种卡顿。实际上,Django在这类系统里要承担三件事:一是ORM设计,把股票、行情、特征、预测结果、模拟交易记录这些实体理清关系;二是提供REST API给前端和第三方工具调用;三是作为后台管理界面,方便你随时调参和查看数据。至于核心的LLM推理和回测计算,放在Django之外的任务队列里执行,Django只负责结果展示和状态查询。
所以真正合理的架构是:数据获取脚本 + 特征工程模块 + LLM推理服务 + 回测引擎 + Django Web平台 + 前端可视化。Django是连接这些模块的中枢,而不是什么地方都塞的方便面。如果能在答辩时画出这个架构图,评委的第一印象就不一样。
1.3 "大数据"体现在哪里:别拿几个Excel文件糊弄
有些同学的大数据毕设最后只展示了几张折线图,那还不如不叫大数据。既然是"计算机大数据毕业设计",至少要体现数据的海量性、多维性和处理过程。股票日线数据虽然单只股票只有几千条,但如果你把多股票、多因子、多周期组合起来,数据量很容易到几十万甚至上百万行。这时要用Pandas做多周期特征拼接、用分组聚合处理股票池、用窗口函数计算滚动指标,最好还能引入数据库存储和索引优化。
更进一步,你可以用Spark或Dask做离线批量处理,但毕设阶段不一定非得上分布式,你可以在论文里提一句"对于更大规模数据可采用Spark进行处理",系统本身用Pandas+SQLite/MySQL已经足够跑演示。记住,评委关心的是你有没有"数据意识",而不是硬堆工具。
2. 技术选型与整体架构:为什么是Django+LLM+量化回测这个组合
2.1 Django的优势:快速成型与自带管理后台
后端框架我推荐Django而不是Flask或FastAPI,原因很实际:Django自带Admin后台、ORM、用户认证、安全防护,这些都是毕设评审时能直接展示的"标准功能"。特别是Admin后台,把数据模型注册进去后,评委可以看到数据库表、字段、甚至可以直接在后台修改数据,这种"可视化数据管理"很容易让项目显得完整。Django的ORM也省去了手写SQL的麻烦,外键关联查询在写股票和行情表时非常顺手。
当然Django也有缺点:同步模型处理长任务容易卡住,所以必须搭配异步组件。毕设不是工业级分布式项目,我们不需要微服务,只需要让模块边界清晰、代码能跑通、演示不翻车就够了。
2.2 LLM选型:外部API还是本地模型
LLM接入有两种主流路线:一是调用云端API,效果稳定,开发简单,但需要网络和费用,且个别学校对调用外部接口有限制;二是在本地部署一个开源模型,例如几B参数的量化版本,通过transformers或llama.cpp加载,离线推理,完全可控。我的建议是:优先用云端API跑通主流程,再在论文里补充本地部署的实验对比,这样又快又有深度。
选型时还要注意Token成本和响应速度。毕设里每日调用量不大,选便宜的基础款即可。Prompt的设计要尽量精简,别一次塞几千字,否则费钱又容易超时。
2.3 量化回测在系统里充当"验金石"
光有LLM预测结果,没有交易模拟和回测验证,整个系统就缺少闭环。量化回测模块相当于给预测结果设了一个"试验场":把历史数据按时间顺序输入策略,计算买入、卖出、持仓,最终得到净值曲线和收益风险指标。这一步让系统从"看起来能预测"变成"可以评估预测是否真的有交易价值"。
设计回测引擎时可以选用backtrader这类现成框架,也可以自己写一个简单的事件循环。我建议自己写一个几百行的小引擎,因为这样你对买卖逻辑的控制最精细,答辩时也能讲清楚每一步,而不会像用黑盒库一样一问三不知。
2.4 整体架构的模块划分与数据流转
把系统拆成五个独立模块,代码组织会清晰很多:
- 数据层:负责从数据源拉取股票行情,清洗后存入SQLite/MySQL。
- 特征层:读取原始行情,计算各类技术指标,生成特征宽表。
- 推理层:调用LLM服务,把特征摘要转化为结构化评分。
- 策略层:根据评分和历史数据生成交易信号,并执行回测。
- 展示层:Django后端提供API和Web页面,使用ECharts渲染K线,使用WebSocket推送实时分析结果。
数据流向是:原始行情 → 特征工程 → 特征摘要 → LLM推理 → 交易信号 → 回测评估 → 前端展示。每一层都有独立函数和独立输出,出现bug时好排查,也方便在论文里画数据流图。
3. 数据获取、特征工程与数据库设计:从原始行情到模型输入
3.1 行情数据获取:用免费库快速起步,但要处理三个坑
我用过的数据方案基本是从akshare和tushare开始,前者免费且无需token,后者部分接口要注册。实际做毕设,我用akshare获取沪深A股的日线数据,几分钟就能拉到几千只股票的历史行情。但这里有几个坑必须处理:
- 停牌问题:停牌期间的NaN值需要前向填充或直接删除,否则会影响滚动指标计算。
- 复权处理:推荐使用后复权价格,不然除权除息后会出现假跳空下跌,回测结果错得离谱。
- 接口频率限制:免费接口连续请求容易返回空数据或报错,加
time.sleep(0.5)这种简单限速就能解决。
我自己一般会把拉取到的数据直接落库,存成本地的csv或SQLite表,这样后边反复调试特征工程和回测时不用频繁请求外部接口。
3.2 特征工程:把行情数据变成"像样"的模型输入
原始数据只有时间、开盘、收盘、最高、最低、成交量,没有模型能直接用,所以特征工程非常关键。我比较推荐的是一套基础技术指标组合:
- 趋势类:MA5/MA10/MA20均线比率、MACD的DIF和DEA
- 动量类:RSI、KDJ的K/D/J
- 波动类:布林带宽度、ATR
- 量价类:成交量变化率、资金流近似
用Pandas的rolling()和ewm()能一次性生成大量特征。举个例子,RSI的计算脚本并不复杂,但要注意周期参数不同结果差异很大,通常选14日。
def calc_rsi(close, period=14): diff = close.diff(1) gain = diff.clip(lower=0).rolling(period).mean() loss = -diff.clip(upper=0).rolling(period).mean() rs = gain / loss rsi = 100 - 100 / (1 + rs) return rsi生成特征后,你需要做标准化和去极值处理。对于毕设来说,直接用sklearn.preprocessing.StandardScaler即可,注意要在回测训练窗口内拟合,不能用全量数据一次性标准化,否则会发生数据泄露。这个细节很多学生都会踩,写到论文里反而成了加分项。
3.3 数据库表设计与ORM核心模型
Django的模型设计直接影响后续开发效率。我的建议是建立五张核心表:Stock、StockPrice、StockFeature、PredictionResult、TradeRecord。其中StockPrice通过ForeignKey关联Stock,并设置unique_together = ('stock', 'date'),确保同一只股票同一天只有一条行情。StockFeature则存储技术指标,行数和StockPrice一一对应。PredictionResult存储LLM输出,包含预测日期、trend_score、risk和advice。TradeRecord存储模拟交易的买卖记录,字段包括方向、价格、数量、盈亏。
实际编写模型时,我建议给日期和股票代码添加db_index=True,查询速度会快很多。Admin后台注册后,所有数据都可以直接点击查看,论文截图也有了。
3.4 数据准备脚本的完整流程
把所有数据准备逻辑写成脚本,方便重复执行:
# prepare_data.py 简版流程 import akshare as ak import pandas as pd from utils import calc_features codes = ['600000', '000001'] # 测试股票池 for code in codes: df = ak.stock_zh_a_hist(symbol=code, period="daily", adjust="qfq") df = df.rename(columns={"日期": "date", "开盘": "open", ...}) df = calc_features(df) df.to_sql(f"stock_feature_{code}", conn, if_exists="replace") time.sleep(0.5)这样的脚本可以在论文的"系统实现"章节体现,也可以放在毕业设计四件套的源码包里,方便验收老师复现数据结果。
4. Django项目实战:大模型集成、异步任务与WebSocket推送
4.1 Django + Celery:让LLM推理不再卡住页面
在Django中集成LLM最忌讳的是在一个视图函数里同步调用模型。比如views.py里写analysis_result = llm_service.generate_analysis(...)然后再返回页面,这段代码运行期间,浏览器会一直转圈,用户体验极差。更好的做法是引入Celery任务队列:
- 用户在前端点击"开始分析";
- Django 收到请求后,生成一条异步任务,立刻返回"分析中"的状态;
- Celery worker 在后台执行特征提取和大模型调用;
- 任务完成将结果写入数据库,并通过 WebSocket 通知前端。
Celery 需要依赖 Redis 作为 broker,在本地开发时直接安装 Redis,不用额外写复杂配置。任务函数可以这么定义:
# tasks.py from celery import shared_task from .llm_service import LLMService from .models import StockFeature, PredictionResult @shared_task(bind=True, max_retries=3) def run_analysis_task(self, stock_code, feature_date): try: features = StockFeature.objects.filter(stock__code=stock_code, date=feature_date).first() result = LLMService().generate_analysis(features.to_prompt()) PredictionResult.objects.create(...) return result except Exception as exc: raise self.retry(exc=exc, countdown=60)这一步不仅让系统更可靠,也是答辩时能主动讲的"工程亮点"。
4.2 LLM Service的封装与Prompt结构
为了让LLM集成部分不散落各地,我会建一个llm_service.py,里面封装generate_analysis(feature_text)。核心函数大概长这样:
class LLMService: def __init__(self, api_key, model="qwen-plus"): self.client = OpenAI(base_url="...", api_key=api_key) self.model = model def generate_analysis(self, feature_text: str) -> dict: prompt = self.build_prompt(feature_text) response = self.client.chat.completions.create( model=self.model, messages=[{"role": "user", "content": prompt}] ) content = response.choices[0].message.content return json.loads(content)在构建Prompt时,一定要明确要求输出JSON,否则模型会给你一大段散文,程序没法解析。一个稳定可用的Prompt模板:
请根据以下技术指标摘要,分析股票600000的当前趋势,返回JSON: - 最近5日涨跌幅:+3.2% - RSI(14):62.5 - MACD:DIF=0.31,DEA=0.22,柱为正 - 收盘价位于MA20上方 输出格式:{"trend_score": 0.8, "risk": "low", "advice": "偏多震荡,关注量能"}如果解析失败,我会加一个重试逻辑,防止偶发的返回格式错误导致整个任务失败。这里还可以在后端记录原始响应,方便排查问题。
4.3 WebSocket实时推送与前端展示
WebSocket是答辩时很加分的点。使用Django Channels后,需要在asgi.py中配置协议类型,并在consumers.py写一个消费者,加入一个名为stock_updates的group。当Celery任务完成后,在task内通过async_to_sync发送消息到group,前端就能实时收到。
前端JavaScript部分可以这样接收:
const ws = new WebSocket('ws://localhost:8000/ws/stocks/'); ws.onmessage = function(event) { const data = JSON.parse(event.data); if (data.type === 'prediction_done') { renderResult(data.payload); } };页面上用ECharts画K线和均线,用卡片展示LLM分析结果,下方放交易记录表。整个页面不需要刷新,数据就能自动更新。这种交互效果很能吸引评委注意力。
4.4 管理后台、日志与错误处理
除了功能实现,Django Admin注册数据模型是很容易出彩的。比如在admin.py中注册PredictionResult,就可以在后台查看到历史上所有LLM预测记录,支持按日期排序和筛选。我还建议接入logging模块,把每次LLM调用的输入、输出、耗时都记录下来,方便调试和写实验分析。答辩时打开后台日志,说"这是我们系统运行的真实记录",比任何口头描述都有说服力。
5. 量化策略回测与实验评测:用指标说话而不是玄学
5.1 数据泄露和时序穿越:真实存在的魔鬼
做股票趋势预测的回测实验时,最严重的错误就是数据泄露。比如,用全量数据标准化特征后再划分训练/测试集,测试集的信息已经从scaler中溜进模型;又比如直接用未来数据填充NaN,导致指标"提前知道答案"。正确的做法是:只用t时刻之前的数据来构造t时刻的特征,并用滚动时间窗口扩展训练。
我会用一个简单方法验证特征序列的构造时间:
def build_features(df, window=20): df = df.copy() df['ma20'] = df['close'].rolling(window).mean().shift(1) # shift(1)是关键 df['rsi'] = calc_rsi(df['close']).shift(1) return df.dropna()shift(1)表示以上一根K线收盘后的信息作为当前特征,而不是用当天的已知信息预测当天。这个细节写进文章里,评委一眼就觉得你是懂行的。
5.2 回测指标怎么选:准确率之外的故事
坦白说,预测涨跌的准确率即便做到55%也已经不错,但股票交易要考虑连续收益、风险和波动。所以回测报告里除了准确率/召回率,我还会计算:
- 年化收益率:根据每日收益复利年化
- 夏普比率:(策略年化收益率 - 无风险利率)/年化波动率,衡量每单位风险回报
- 最大回撤:净值曲线从高点到最低点的最大跌幅
- 胜率和盈亏比:盈利交易次数占比和平均盈亏比值
你可以用empyrical这样的现成库计算,也可以自己写几十行代码计算。关键是答辩时能说出每个指标的含义:为什么夏普比率越高越好?最大回撤为什么越小越好?当评委问"你的策略有效吗",你直接报出年化15%、夏普1.2、最大回撤8%,比解释一堆理论更有力。
5.3 我实测踩过的两个大坑
第一个是复权方式选错。刚开始用前复权数据拉取,后来数据中间有除权除息,回测里出现了莫名的大亏。后来统一用后复权,把价格序列拉平,才算正常。第二个是手续费和滑点没加。没加托管成本的时候策略收益曲线漂亮得吓人,加上万二佣金和0.1%滑点后,收益直接砍掉三成,这恰恰说明真实回测的残酷。在论文里如实展示这两个对比,比造假好看得多。
5.4 用对比实验证明方案的价值
为了让实验更有说服力,建议做三组对比:一是"只用技术指标规则交易"作为基线策略;二是"LLM评分+规则交易";三是"随机选择买入"作为对照组。通过对比三组的回测曲线和指标,能说明LLM的引入是否真的提升了结果。即便提升不大,你也可以分析原因,比如"LLM评分与短期价格变化相关度有限,未来可加入新闻情感等更多信息",这本身就是有深度的结论。
我还会在实验部分放一张表格,列出三组策略的年化收益、夏普、最大回撤、胜率。表格是答辩PPT里最抓眼球的东西,评委拿着手机拍照都要拍这张表。
6. 论文写作、PPT答辩与四件套交付的实用经验
6.1 论文(LW)的结构和写法重点
毕设论文一般安排六到七章。我的建议是:摘要写清楚"系统基于Django搭建Web平台,引入LLM对多因子行情特征进行语义推理,结合量化回测模块实现完整的分析预测链路";引言讲背景意义;关键技术一章集中介绍Django、LLM、量化策略;系统设计一章给出架构图、模块图和数据库设计;核心实现一章贴关键代码和界面截图;实验一章放回测结果对比和案例分析;最后总结不足与展望。
写论文时最大的误区是把代码大段粘贴。其实评委更希望看到选择理由和对比分析,比如"为什么选择WebSocket而不是Ajax轮询""为什么LLM输出采用JSON而不是自然语言文本",这些内容最有含金量。另外要注意图表规范:架构图、数据流图、数据库E-R图、核心页面截图、回测结果表,建议总计15张以上,这样的论文第一眼就让人觉得工作量饱满。
6.2 PPT讲解的10分钟节奏
对应答辩PPT,我一般让学生按四段讲:
- 背景和问题:股票行情预测难在哪,传统方法有什么不足(1分钟)
- 系统架构和技术栈:你用了Django、LLM、大数据技术,怎么组合(3分钟)
- 核心功能和实测效果:现场演示K线页面、点击分析、展示回测曲线,重点说指标(4分钟)
- 创新点和不足:LLM + 量化特征融合、WebSocket实时推送、回测评价体系;不足和改进方向(1分钟)
如果在演示时LLM接口临时挂了,千万不要慌。PPT中放一份之前跑好的结果截图,先展示截图,再补一句"由于网络环境,现场调用可能超时,这是之前录制的效果",既能化解紧张,又不丢分。
6.3 源码、论文、PPT和讲解视频的交付标准
现在的毕设题目里,"源码+LW+PPT+讲解"往往是四件套。源码部分要保证能一键启动,README写清楚依赖安装命令、数据库迁移命令、启动命令;论文(LW)要图文并茂,图表至少10张以上;PPT要控制在10页内,页面上别堆满字;讲解视频宁可多录几分钟,也不要出现演示中途报错然后黑屏。
我经常提醒学生:交付物最重要的不是功能多酷炫,而是可复现性。如果老师或者实习单位按你的README跑不起来,前面的功夫全白费。所以源码包里最好附带一个requirements.txt、一个.env.example、一个start.sh,把环境变量和启动步骤写清楚。这些细节虽然不起眼,但在毕业设计评优和求职作品集里非常加分。
6.4 从"完成毕设"到"二次扩展"的方向
如果时间充裕,可以做一些扩展让项目更有竞争性:比如把LLM输出与新闻情感分析结合,通过爬取财经新闻做事件驱动得分;或者增加可视化大屏,展示股票池整体风险分布;又或者将回测引擎换成并行计算,支持多股票批量回测。每加一个扩展,论文里就能多一节,答辩时也多一个话题。
结尾
我自己一路做下来最大的体会是,这套系统真正的价值不在预测准不准,而在于把"数据-特征-模型-决策-展示"整条链路完整走了一遍。你在准备这个毕设时,不需要追求模型多深、收益多高,哪怕LLM预测的准确率只有50%,只要你把特征工程、数据隔离、回测评估、系统架构讲得头头是道,评委一样会给高分。最后一个小建议是,留出至少两周时间打磨前端交互和回测报告,因为答辩现场大家最愿意看到的不是一个黑漆漆的命令行,而是一个界面清爽、逻辑完整的系统。祝你开题顺利,毕业顺利。