LSTM 股票预测 Django Web 系统:Python 3.10 + Scrapy 数据采集实战(附 3 大模块源码)
LSTM股票预测Django Web系统:Python 3.10全栈开发实战
1. 系统架构设计
现代金融科技应用中,将机器学习模型产品化为Web服务已成为核心需求。本系统采用三层架构设计:
- 数据层:Scrapy爬虫+MySQL实现高频数据采集
- 算法层:PyTorch构建的LSTM时序预测模型
- 表现层:Django+ECharts实现交互式可视化
关键技术栈版本:
Python 3.10 Django 4.2 Scrapy 2.11 PyTorch 2.0 ECharts 5.4提示:建议使用conda创建隔离环境,避免依赖冲突:
conda create -n stock_pred python=3.10 conda activate stock_pred2. 数据采集模块实现
2.1 Scrapy爬虫工程化
股票数据采集需要处理反爬机制和异常高频请求。我们采用分布式爬虫架构:
# spiders/stock_spider.py import scrapy from scrapy_redis.spiders import RedisSpider class StockSpider(RedisSpider): name = 'stock' redis_key = 'stock:start_urls' custom_settings = { 'DOWNLOAD_DELAY': 0.5, 'CONCURRENT_REQUESTS': 4, 'ITEM_PIPELINES': { 'pipelines.StockPipeline': 300 } } def parse(self, response): # 解析股票数据页面 item = { 'code': response.css('.stock-code::text').get(), 'name': response.css('.stock-name::text').get(), 'price': float(response.css('.current-price::text').get()), 'volume': int(response.css('.trade-volume::text').get().replace(',','')) } yield item关键优化点:
- 使用Redis实现请求去重和分布式调度
- 自定义User-Agent轮询
- 异常重试机制配置
2.2 数据存储设计
MySQL表结构设计需考虑时序数据特性:
CREATE TABLE `stock_daily` ( `id` bigint NOT NULL AUTO_INCREMENT, `code` varchar(10) COLLATE utf8mb4_bin NOT NULL, `trade_date` date NOT NULL, `open` decimal(10,2) DEFAULT NULL, `high` decimal(10,2) DEFAULT NULL, `low` decimal(10,2) DEFAULT NULL, `close` decimal(10,2) DEFAULT NULL, `volume` bigint DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_code_date` (`code`,`trade_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;3. LSTM模型开发
3.1 数据预处理流程
金融时序数据需要特殊处理:
# utils/data_processor.py import numpy as np from sklearn.preprocessing import MinMaxScaler class StockScaler: def __init__(self, feature_range=(-1, 1)): self.scaler = MinMaxScaler(feature_range) def fit_transform(self, df): """归一化处理""" self._save_meta(df) scaled = self.scaler.fit_transform(df.values) return pd.DataFrame(scaled, columns=df.columns) def inverse_transform(self, data): """反归一化""" return self.scaler.inverse_transform(data) def _save_meta(self, df): """保存原始统计量用于还原""" self.meta = { 'min': df.min(), 'max': df.max(), 'mean': df.mean() }3.2 PyTorch模型实现
改进的LSTM架构加入Attention机制:
# models/predictor.py import torch import torch.nn as nn class LSTMAttention(nn.Module): def __init__(self, input_size=5, hidden_size=64): super().__init__() self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True) self.attention = nn.Sequential( nn.Linear(hidden_size, hidden_size), nn.Tanh(), nn.Linear(hidden_size, 1) ) self.regressor = nn.Linear(hidden_size, 1) def forward(self, x): lstm_out, _ = self.lstm(x) # [batch, seq_len, hidden] # Attention机制 attn_weights = torch.softmax( self.attention(lstm_out), dim=1 ) context = torch.sum(attn_weights * lstm_out, dim=1) return self.regressor(context)训练关键参数配置:
# config/train_config.py TRAIN_PARAMS = { 'batch_size': 64, 'epochs': 100, 'learning_rate': 0.001, 'lookback_window': 20, # 使用20天历史数据 'train_ratio': 0.8, 'early_stop_patience': 10 }4. Django系统集成
4.1 项目结构设计
采用分应用模式组织代码:
stock_project/ ├── core/ # 核心业务逻辑 ├── predictor/ # 预测模型服务 ├── scraper/ # 爬虫管理 ├── static/ │ └── js/ # ECharts脚本 └── templates/ # 前端页面4.2 异步任务处理
使用Celery处理耗时操作:
# core/tasks.py from celery import shared_task from predictor.inference import make_prediction @shared_task(bind=True) def predict_stock_task(self, stock_code): try: result = make_prediction(stock_code) return { 'status': 'SUCCESS', 'result': result.tolist() } except Exception as e: self.retry(exc=e, countdown=60)4.3 前后端数据交互
Django视图处理预测请求:
# core/views.py from django.http import JsonResponse from core.tasks import predict_stock_task def get_prediction(request, stock_code): task = predict_stock_task.delay(stock_code) return JsonResponse({'task_id': task.id}, status=202)前端通过AJAX获取结果:
// static/js/prediction.js function fetchPrediction(stockCode) { fetch(`/api/predict/${stockCode}`) .then(response => response.json()) .then(data => { if (data.status === 'SUCCESS') { renderChart(data.result); } else { checkTaskStatus(data.task_id); } }); }5. ECharts可视化实现
5.1 趋势对比图表
配置项示例:
option = { tooltip: { trigger: 'axis', axisPointer: { type: 'cross' } }, legend: { data: ['实际价格', '预测价格'] }, xAxis: { type: 'category', data: dates // 日期数组 }, yAxis: { type: 'value' }, series: [ { name: '实际价格', type: 'line', smooth: true, data: actualPrices }, { name: '预测价格', type: 'line', smooth: true, lineStyle: { type: 'dashed' }, data: predictedPrices } ] };5.2 移动端适配方案
通过响应式设计确保多端兼容:
/* static/css/responsive.css */ @media (max-width: 768px) { .chart-container { width: 100%; height: 300px; } .data-table { font-size: 0.8rem; } }6. 系统部署方案
6.1 生产环境配置
推荐使用Docker Compose编排服务:
# docker-compose.prod.yml version: '3.8' services: web: build: . command: gunicorn core.wsgi:application --bind 0.0.0.0:8000 volumes: - static:/app/static depends_on: - redis - mysql celery: build: . command: celery -A core worker -l info depends_on: - redis redis: image: redis:6 ports: - "6379:6379" mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${DB_PASSWORD} volumes: - db_data:/var/lib/mysql volumes: static: db_data:6.2 性能优化建议
针对高频预测场景的优化策略:
- 缓存层:对历史预测结果使用Redis缓存
- 模型量化:将PyTorch模型转为TorchScript提升推理速度
- 异步加载:前端实现数据分片加载
- CDN加速:静态资源部署到CDN
7. 扩展开发方向
本系统可进一步扩展的功能模块:
- 多模型集成:结合Transformer等新型架构
- 实时预警:设置价格波动阈值通知
- 组合分析:多股票相关性分析
- 自动化回测:策略历史表现验证
实际开发中发现,LSTM模型在5-7天的短期预测中表现最佳,而更长周期的预测需要引入宏观经济指标作为外部变量。系统源码中已包含模型再训练的接口设计,方便后续迭代升级。
