ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Django与Vue.js股票预测系统开发:从数据采集到可视化部署

Django与Vue.js股票预测系统开发:从数据采集到可视化部署 每年到毕业设计季节我都会收到不少类似的咨询想做一个和数据、可视化、预测相关、又能拿得出手的系统但又怕难度控制不住、答辩讲不清楚。今天要聊的“基于Django和Vue.js的股票预测系统”就是这类热度一直很高的选题。它把后端开发、前端可视化、机器学习预测、量化交易分析几个热门方向全部串在了一起既沾了大数据和人工智能的热点又能在有限时间内真正落地而不是停留在概念PPT里。这个系统解决的核心问题其实很实在从真实股票数据源拉取历史行情清洗后存入数据库用模型预测未来几天的价格走势或涨跌方向再叠加技术指标和回测结果生成买卖信号最后通过网页把K线、预测曲线、交易信号、回测收益全部可视化展示出来。整个过程就是一条完整的“数据采集 - 特征计算 - 模型推理 - 策略验证 - 可视化展示”链路比单纯做一个CRUD管理系统有深度得多。我把这个项目从选型、建模、接口设计到前端图表、实时推送、部署答辩的经验完整拆给你准备做类似题目的同学可以直接照着走已经开工的也能对照着查漏补缺。1. 项目整体设计与技术选型思路1.1 为什么这个选题会这么火股票预测系统在毕业设计里属于“自带亮点”的题目。它天然包含了金融数据、时间序列、机器学习、可视化这些听起来有含金量的关键词同时又有非常落地的业务场景。很多同学选这个题第一是因为它不用造轮子数据接口和预测模型都有现成方案第二是因为它好展示PPT里放几张K线图加预测曲线视觉冲击力远超普通管理系统。但这个题也有它的隐形门槛。我见过不少同学一开始兴致勃勃想用LSTM预测股价结果数据不会清洗模型训练完不知道往哪放前端要的数据格式和后端对不上最后变成了一个只有登录注册和一张死图的空壳。所以选这个题之前必须先承认一个事实这个项目的难点不在“某个单点”而在“把整条链路串起来”。谁能把链路串明白谁就拿到了高分的基础。1.2 系统架构与数据流设计整体架构采用前后端分离模式前端Vue.js负责交互和图表渲染后端Django提供RESTful API和数据处理服务数据库选用MySQL存储行情与用户数据预测模块则单独封装成本地服务或Celery异步任务。数据流是核心建议按下面这条链路设计数据接入层通过AkShare或Tushare定时拉取沪深A股日线行情包含开高低收、成交量、成交额等基础字段数据清洗层处理停牌导致的空值、复权因子、异常跳空数据统一存到MySQL特征计算层在Django内计算MA、MACD、RSI、KDJ等技术指标作为预测和量化分析的输入模型推理层加载训练好的预测模型ARIMA、Prophet或LSTM输出未来N日价格或涨跌概率策略回测层基于预测结果和技术指标生成买卖信号滑动回测历史区间计算收益和回撤可视化展示层Vue.js配合ECharts渲染K线图、预测曲线、资金曲线、指标面板这个分层的好处是每一层都能单独解释、单独测试答辩被追问时你也好回答。比如被问“预测模块怎么优化的”你只需要讲模型层被问“数据怎么保证一致性”你只需要讲清洗层。如果全揉在一个脚本里一旦被追问细节就会非常被动。1.3 技术栈选型的几个关键取舍Django在这个项目里的角色不只是“写接口的工具”。它自带的ORM、Admin后台、迁移机制和用户认证能省掉大量重复工作。特别是Django Rest Framework序列化器加视图集几行代码就能把查询、过滤、分页、认证全部接上非常契合毕设这种需要快速成型又必须有规范结构的场景。Vue.js方面我用的是Vue 3加Vite模板。Vue 3的组合式API在组织图表组件、定时器、WebSocket连接时比Options API更干净。ECharts则作为可视化的主力它对K线图、折线图、仪表盘、热力图的支持都是最成熟的社区文档也全遇到问题几乎都能搜到答案。这里有个重要的取舍建议预测模型不要一上来就奔着神经网络。LSTM确实热门但训练时间、数据量、归一化、序列构造这些环节对新手很不友好。更稳妥的做法是先用ARIMA或Prophet做一版能跑通的结果把链路调顺再考虑升级到LSTM。两个模型在系统里可以共存通过参数切换既展示了对比实验又降低了翻车风险。2. 核心功能模块拆解与实现要点2.1 数据采集与预处理怎么做才规范数据是整个系统的地基但恰恰是很多同学做得最糙的一环。直接用接口拉几万条数据灌进数据库不叫完成你得考虑字段设计、主键约束、索引和更新策略。我建议的股票基础表结构是这样设计的字段类型说明ts_codevarchar(16)股票代码如600519.SHtrade_datedate交易日期opendecimal(10,2)开盘价highdecimal(10,2)最高价lowdecimal(10,2)最低价closedecimal(10,2)收盘价pre_closedecimal(10,2)昨收盘价volbigint成交量手amountdecimal(20,2)成交额元pct_chgdecimal(6,3)涨跌幅表的联合主键建议设为(ts_code, trade_date)防止重复插入。实战中我吃过亏的是pct_chg这个字段很多数据源返回的数字是浮点百分比比如1.5代表涨了1.5%如果你直接用float存后续计算时容易忽略单位转换导致指标算错。数据清洗主要处理三种问题停牌缺失当天没有交易的股票不会产生行情记录不需要填零直接跳过即可复权处理做长期回测一定要复权否则除权除息日前后价格断崖式下跌会严重干扰预测和回测。我用的方案是前复权因为前复权保证最新价格不变画面最直观异常值剔除涨跌停、停牌复查、手误输入导致的极端值可以通过涨跌幅超过20%的过滤规则筛掉爬取策略上不要每次启动项目都全量拉数据。建议本地维护一个数据版本表记录每只股票已拉取到的最新日期增量更新只拉“最新日期1”到当天的数据这样接口压力小程序启动也快。2.2 预测模型部分怎么落地预测模型是这个系统的灵魂也是答辩时最容易被深挖的部分。我建议至少做两个模型做对比一个统计模型ARIMA一个机器学习或深度模型LSTM这样展示出来有层次感。ARIMA落地时最核心的是差分阶数d的选择。股票价格通常是非平稳序列我一般是先做ADF检验如果p值大于0.05就做一阶差分再检验通常一阶差分后就能平稳。p和q的确定可以用AIC最小值来搜索遍历p在0到5、q在0到5的网格选AIC最小的组合。这一步虽然简单但写进论文里显得非常专业。LSTM落地时有一个新手必踩的坑数据泄漏。训练集和测试集必须严格按照时间顺序切分绝对不能用未来的数据来做归一化。我的做法是先用训练集的均值方差拟合Scaler训练集和测试集都调用同一个已拟合的Scaler去变换这样就保证了测试过程看不到训练集之外的统计信息。序列构造的细节也要注意。如果要预测明天收盘价特征窗口我通常取60天输入形状是(batch_size, 60, feature_dim)。特征列建议包含close、vol、pct_chg以及部分技术指标值但不建议把raw的open、high、low全部塞进去因为高低开和收盘价有高度共线性会拖慢训练还容易过拟合。保存和调用模型我用joblib加pickle。ARIMA模型小直接pickle没问题LSTM模型如果只用几层全连接或LSTM模型文件也就几MB可以放进项目目录。但注意Django进程加载模型文件时路径最好用os.path.join(BASE_DIR, ...)避免相对路径在不同启动方式下报错。评价指标必须做全我用的是一组组合指标MAE、RMSE和方向准确率。方向准确率对股票场景特别有意义因为你做预测最终是为了判断涨和跌如果方向判断反了就算预测值和真实值误差很小在交易里也是亏钱的。我实测下来沪深300指数日线级别的方向准确率能稳定在52%到56%这个数字在答辩时已经很能说明问题了。2.3 量化交易分析与回测模块量化交易分析听起来高大上落到这个项目里其实就三件事技术指标计算、买卖信号生成、历史回测统计。技术指标我建议做MA、MACD、RSI、KDJ四个它们算法固定、解释性强ECharts里画出来也好看。MACD的计算细节容易出错EMA的初始值和平滑系数不同结果会不一样。我在代码里固定用EMA12和EMA26DEA用EMA9这样和主流行情软件对齐验证起来方便。买卖信号生成逻辑可以直接用规则策略。比如最简单的双均线策略MA5上穿MA20生成买入信号MA5下穿MA20生成卖出信号。这种策略解释成本低答辩时老师一听就懂。进阶一点可以叠加RSI超买超卖过滤RSI大于70不追高RSI小于30不杀跌。回测框架有两个选择自己写或用backtrader。毕设场景我建议自己写一个轻量级回测函数逻辑非常清晰还能顺便展示编程能力。核心逻辑是遍历每一天第一天以开盘价买入一定仓位遇到卖出信号时全部卖出记录每日持仓市值和现金余额计算资金曲线回测统计指标重点输出年化收益率、最大回撤、夏普比率、胜率。特别提醒回测时一定要把手续费和滑点算进去A股默认佣金按万2.5算卖出加收印花税千分之一。不加交易成本的回测曲线好看但答辩时老师一句“你的回测考虑了手续费吗”就能让你哑口无言。2.4 数据可视化与交互体验可视化部分决定了老师打开你系统的第一印象。ECharts的折线图和K线图必须做扎实我强烈建议至少包含三个核心图表K线图加MA均线叠加强势股选择、预测价格曲线和真实价格曲线对比、资金曲线与基准收益率对比。K线图用ECharts的candlestick系列数据格式是[open, close, low, high]不少同学在这个顺序上栽过跟头。K线图下面建议配成交量柱状图和MACD柱状图用dataZoom做联动缩放这是股票软件的标准布局做出来立刻就有专业感。页面交互上我做了三个实用功能股票搜索和自动补全、时间区间选择器、指标开关。自动补全用Element Plus的el-autocomplete从后端接口拉股票名称和代码。区间选择器直接控制图表展示的数据范围不需要重新请求接口性能更快。还有一个容易被忽略的点图表组件在Vue中必须正确处理销毁和重绘。页面切换时ECharts实例要调用dispose方法否则会出现内存泄漏和画布重叠报错。用Vue的onBeforeUnmount钩子做清理这个细节写进文档里也很加分。3. 实操过程与核心代码实现3.1 Django后端工程搭建与数据库建模动手第一步是搭项目结构。我推荐按功能拆分app不要所有代码堆在同一个app里。标准划分是三个appstock负责股票数据和行情管理prediction负责预测任务与模型加载strategy负责指标计算和回测。Django模型这块我贴一下核心代码from django.db import models class StockBasic(models.Model): ts_code models.CharField(max_length16, primary_keyTrue) symbol models.CharField(max_length8, db_indexTrue) name models.CharField(max_length32) industry models.CharField(max_length32, blankTrue) list_date models.DateField(nullTrue) class DailyQuote(models.Model): ts_code models.CharField(max_length16, db_indexTrue) trade_date models.DateField(db_indexTrue) open models.DecimalField(max_digits10, decimal_places2) high models.DecimalField(max_digits10, decimal_places2) low models.DecimalField(max_digits10, decimal_places2) close models.DecimalField(max_digits10, decimal_places2) pct_chg models.FloatField() vol models.BigIntegerField() amount models.DecimalField(max_digits20, decimal_places2) class Meta: unique_together (ts_code, trade_date)注意DailyQuote里的unique_together这条约束在数据增量更新时配合get_or_create能有效防重。模型迁移后如果数据量到百万级记得给ts_code和trade_date加联合索引查询速度会快很多。API层我用DRF的ViewSet加ModelSerializer股票列表、K线数据、技术指标、回测结果分别提供接口。接口返回格式我统一用{code, data, msg}的结构前端好判断状态。行情数据接口要注意按trade_date排序和分页前端K线组件一次性拿5000根K线没问题但如果整表全量返回就会卡死。3.2 预测接口与策略回测接口实现预测接口的核心逻辑是接收股票代码和窗口天数从数据库取出最近N日行情构造特征序列加载模型推理返回未来N天的预测值。ARIMA模型在Django里的调用很简单Pickle加载后用model.forecast(n)直接预测。但这里有个细节ARIMA训练时的时间索引维度在模型里是固定的换一只股票或者换一段数据就必须重新训练所以我的设计是把模型文件按股票代码缓存避免每次请求都重新拟合。加一个简单的字典缓存key是ts_codevalue是模型对象实测响应时间能降低一个数量级。LSTM推理前要处理的是特征构造和归一化。我从数据库抽出最近60天的数据按训练时的Scaler转换再变成(1, 60, feature_dim)的张量推理后逆变换回价格区间。预测结果需要和真实K线合并成一个List返回给前端格式统一成[{date, close, predict}]前段直接双折线展示。回测接口相对独立。输入参数是股票代码、开始日期、结束日期、初始资金输出是每日资金曲线和策略交易记录。回测代码核心逻辑是循环中判断信号并更新持仓状态最后返回结果JSON。回测耗时一般在一秒内可以同步执行但如果未来要支持多股票组合回测就得扔到Celery里异步跑。3.3 Vue.js前端页面与图表联动前端我用Vite创建Vue3项目配合Vue Router和Pinia做状态管理。页面结构是左侧菜单加右侧内容区菜单包含Dashboard总览、个股分析、预测与回测、量化策略四个模块。个股分析页是核心页面布局分上下两块上面是搜索栏和股票信息卡片下面是K线图和指标区。K线图组件封装如下// components/KLineChart.vue import * as echarts from echarts import { onMounted, onBeforeUnmount, ref } from vue const chartRef ref(null) let chartInstance null onMounted(() { chartInstance echarts.init(chartRef.value) }) onBeforeUnmount(() { chartInstance chartInstance.dispose() }) function renderKLine(dates, kData, ma5, ma10, volData) { chartInstance.setOption({ tooltip: { trigger: axis }, legend: { data: [K线, MA5, MA10] }, grid: [ { left: 60, right: 20, top: 30, height: 55% }, { left: 60, right: 20, top: 72%, height: 18% } ], xAxis: [ { type: category, data: dates, boundaryGap: true }, { type: category, gridIndex: 1, data: dates } ], yAxis: [ { scale: true }, { gridIndex: 1, splitLine: { show: false } } ], dataZoom: [{ type: inside }, { type: slider }], series: [ { name: K线, type: candlestick, data: kData, itemStyle: { color: #ef232a, color0: #14b143, borderColor: #ef232a, borderColor0: #14b143 } }, { name: MA5, type: line, data: ma5, smooth: true, showSymbol: false }, { name: MA10, type: line, data: ma10, smooth: true, showSymbol: false }, { name: 成交量, type: bar, xAxisIndex: 1, yAxisIndex: 1, data: volData } ] }) }注意candlestick数据顺序是[open, close, lowest, highest]红涨绿跌的配色在国内股票软件是惯例别用反了。联动的实现思路是所有子图表共用一个dataZoom索引这样拖动缩放时K线、成交量和MACD会同步变化。axios请求统一封装在request.js里请求拦截器自动带上JWT Token响应拦截器统一处理401跳转登录。项目里我用的是djangorestframework-simplejwt做认证登录后前端把access和refresh两个token都存起来请求头里带access过期时用refresh换新的。3.4 WebSocket实时推送的落地方式毕设里如果能做实时数据推送档次会明显提升。我做的方案是Django Channels加WebSocket后端每5秒模拟推送一次最新的“虚拟实时行情”给前端温度计的仪表盘实时刷新。实际生产可以对接证券行情推送但毕设用模拟数据已经完全够用关键是展示“后端主动推送前端被动接收”的能力。Django Channels的consumer代码骨架如下import json from channels.generic.websocket import AsyncWebsocketConsumer class QuoteConsumer(AsyncWebsocketConsumer): async def connect(self): self.group_name quotes await self.channel_layer.group_add(self.group_name, self.channel_name) await self.accept() async def disconnect(self, close_code): await self.channel_layer.group_discard(self.group_name, self.channel_name) async def quote_send(self, event): await self.send(text_datajson.dumps(event[data], ensure_asciiFalse))前端Vue里用原生WebSocket连接收到消息后更新图表。这里有个坑Channels4和Daphne部署时ASGI配置和进程数不仔细会出连接不上或推送错乱的问题。如果时间紧张可以用一个替代方案前端用setInterval轮询行情接口效果接近省去Channels的部署复杂度。但WebSocket作为亮点写进论文含金量确实更高建议有余力就上。4. 常见问题与排查技巧实录4.1 数据层面的坑我在实际开发中遇到最多的就是数据问题。第一个坑是数据库时间字段的类型Django的DateField对应MySQL的date类型如果从接口拿的是datetime字符串转换时要用pd.to_datetime然后取.date()否则存入带时分秒的数据后前端日期匹配会出现偏差。第二个坑是前复权数据在回测里的使用。前复权会把历史价格整体压低最新价保持真实值这导致如果某个期间股票有多次分红历史前复权价可能出现负值。负价格在计算收益率时会出奇怪结果所以我的策略是回测前先过滤掉复权后价格为负的数据。第三个坑是数据源接口频率限制。免费接口通常有每分钟调用次数限制如果批量拉几千只股票的日线很容易被限流。我的做法是拉取时加随机sleep并且把拉取任务做成Celery周期任务凌晨跑一次增量更新避开白天的高峰时期。4.2 模型与回测的坑预测模块最常见的坑是“看起来很好实际不能用于交易”。我在做对比实验时发现直接用收盘价做LSTM预测结果曲线往往比真实曲线滞后一天因为模型学到了“今天的价格约等于昨天的价格”这个最简单规律导致预测曲线整体右移。这种现象叫延迟预测在答辩时一定要主动说明自己通过方向准确率和滞回检验发现过并尝试用多步预测或残差修正来缓解这就是亮点。回测模块的坑主要在数据对齐和偷看未来。比如计算MA20时第20天之前是没有MA20值的这段区间的策略信号应该为空不能把空值当0处理。防止偷看未来的关键在于所有指标值都必须用历史数据算出不允许用当天的收盘价提前知道第二天的信号。我还遇到过回测收益率被高估的情况原因是我用收盘价判断信号并在收盘价成交实际操作中信号产生和成交之间的滑点完全没考虑。我后来在回测里加入了固定滑点买入价加0.1%卖出价减0.1%曲线立刻变丑很多但更真实。这种“曲线变丑但是更可信”的经验恰恰是论文里值得写的一笔。4.3 前后端联调与部署的坑联调阶段遇到最多的问题是跨域。Django后端必须安装django-cors-headers在settings里配置CORS_ALLOWED_ORIGINS如果前端跑在5173端口就填http://localhost:5173不要图省事全部用星号否则带Cookie的请求会有问题。另一个高频问题是JWT Token的Authorization头格式。DRF的simplejwt默认要求格式是“Bearer ”前端axios拦截器里必须加Bearer前缀否则后端返回401。这个问题排查起来很隐蔽因为网络请求本身是成功的只是认证头格式不对。部署环节我建议用Gunicorn加Nginx。Gunicorn跑Django应用Nginx反向代理同时托管前端打包后的静态文件。后端接口路径用/api前缀Nginx配置里把/api请求转发到Gunicorn的8000端口其他路径直接指向dist目录。静态文件冲突是常见的麻烦把所有接口统一挂/api前缀能轻松避开。4.4 答辩和文档准备的建议最后聊几句答辩的事。这套系统答辩的时候老师大概率会问三个方向数据从哪来、模型的准确性怎么验证、回测策略能不能赚钱。对应的答法我建议准备好第一个方向讲你的增量更新和数据清洗流程第二个方向讲你的评价指标体系不要只讲准确率要讲MAE和方向准确率第三个方向比较敏感明确说明系统是教学研究用途不构成投资建议同时坦诚讲清回测的限制条件。文档部分架构图用分层图加数据流图时序图表达用户请求预测的完整链路。PPT不用太多页按照选题背景、系统架构、功能展示、实验结果、总结展望这个顺序走核心页面放图表截图和指标表格别放大段代码代码留给正文附件。5. 最后的个人经验这个项目我从最开始的纯Django模板渲染版本一路改到前后端分离加WebSocket前后删过三四版代码最大的感悟是想清楚链路比写代码更重要。第一天就把数据流画出来后面每一步都是往这个框架里填东西效率会高非常多。在预测模型上再多说一句论文里不要只写“预测准确率高达90%”这种话行家一看就知道是过拟合或者数据泄漏。真实市场里线性模型的预测有效性很有限把实验过程写实、把局限性写透反而比夸大效果更能获得老师的认可。如果你还有时间做扩展建议往三个方向加深一是接入实时行情把模拟推送换成真实接口二是加入多因子选股模块对全部A股做打分排序选前N只三是把回测模块升级成参数优化器用网格搜索自动找均线策略的最优参数。每一步都能让这个系统从“合格毕设”变成“优秀毕设”也让你在面试讲项目的时候有更多东西可以说。这套大而全的思路可能不是最省力的但一定是一条能让你从头到尾讲清楚自己的项目、经得住老师连番追问的路。你按这个结构一步步做踩坑了再回头看这篇文章多半能对号入座找到解决办法。祝顺。
返回列表