Files
ljwx-stock/DEPLOYMENT_GUIDE_DOCKER.md
brunoandQwen-Coder 439ad8a854 feat: Upgrade to real-world dynamic stock recommendation system with Claude + Qwen3 AI collaboration
- Implement dynamic stock universe with 3-stage filtering (liquidity, fundamentals, technicals)
- Create Claude + Qwen3 AI collaboration service for intelligent stock analysis
- Update recommendation routes to use live market data instead of hard-coded lists
- Add new documentation and deployment scripts
- Update Docker configuration for AI model integration

BREAKING CHANGE: Replaces hard-coded stock recommendations with dynamic market-based filtering

Co-authored-by: Qwen-Coder <[email protected]>
2025-11-16 12:43:03 +08:00

8.1 KiB
Raw Permalink Blame History

Docker 部署指南

系统架构

AI协作架构

用户查询 → Claude (理解意图) → Qwen3-coder:30b (数据分析) → Claude (综合结果) → 用户

股票推荐流程

全股票池 (TuShare)
  ↓
第一阶段:流动性筛选 (日均成交额 > 1亿)
  ↓
第二阶段:基本面筛选 (PE < 50, PB < 10, ROE > 5%)
  ↓
第三阶段:技术面筛选 (MA5 > MA20, RSI < 70)
  ↓
ML模型评分 + Claude解释
  ↓
最终推荐列表

前置条件

1. 安装Ollama并下载Qwen3模型

# 安装Ollama (macOS)
brew install ollama

# 启动Ollama服务
ollama serve

# 在另一个终端下载Qwen3-coder:30b模型
ollama pull qwen3-coder:30b-a3b-q8_0

# 验证模型已下载
ollama list

2. 准备环境变量

确保 .env 文件包含所有必要的API密钥:

# .env 文件示例
OPENROUTER_API_KEY=sk-or-v1-xxx
TUSHARE_TOKEN=your_tushare_token
ALPHA_VANTAGE_API_KEY=your_alpha_vantage_key

# 数据库配置
DATABASE_URL=postgresql://stockai:stockai2025@postgres:5432/stock_ai
REDIS_URL=redis://:redis2025@redis:6379/0

# Ollama配置
OLLAMA_BASE_URL=http://host.docker.internal:11434
DEEPSEEK_MODEL=qwen3-coder:30b-a3b-q8_0

部署步骤

方式一:使用Docker Compose (推荐)

1. 构建镜像

# 停止旧容器(如果有)
docker-compose down -v

# 构建所有镜像
docker-compose build

# 或者只构建特定服务
docker-compose build backend
docker-compose build frontend

2. 启动所有服务

# 启动所有服务(后台运行)
docker-compose up -d

# 查看日志
docker-compose logs -f

# 只查看backend日志
docker-compose logs -f backend

3. 验证部署

# 检查服务状态
docker-compose ps

# 测试后端API
curl http://localhost:8001/health

# 测试AI助手
curl -X POST http://localhost:8001/api/assistant/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"推荐几只股票"}'

# 测试动态股票推荐
curl http://localhost:8001/api/recommendations

# 访问前端
open http://localhost:8090

方式二:单独构建和推送镜像

1. 构建Backend镜像

cd backend
docker build -t stock-backend:latest .
cd ..

2. 构建Frontend镜像

cd frontend
docker build -t stock-frontend:latest .
cd ..

3. 推送到Harbor (可选)

# 登录Harbor
docker login localhost:8443

# 标记镜像
docker tag stock-backend:latest localhost:8443/stock/backend:latest
docker tag stock-frontend:latest localhost:8443/stock/frontend:latest

# 推送镜像
docker push localhost:8443/stock/backend:latest
docker push localhost:8443/stock/frontend:latest

访问服务

服务 地址 说明
Frontend http://localhost:8090 Vue 3 前端界面
Backend API http://localhost:8001 FastAPI 后端服务
API Docs http://localhost:8001/docs Swagger UI文档
PostgreSQL localhost:5434 数据库
Redis localhost:6381 缓存服务
Adminer http://localhost:8091 数据库管理UI

关键API端点

1. 动态股票推荐 (使用真实数据)

GET /api/recommendations

工作流程:

  1. 从TuShare获取全部A股列表(~5000只)
  2. 流动性筛选(成交额 > 1亿)
  3. 基本面筛选(PE、PB、ROE)
  4. 技术面筛选(均线、RSI)
  5. ML模型评分
  6. 返回Top 10-20推荐

2. AI助手对话 (Claude + Qwen3)

POST /api/assistant/chat
{
  "message": "帮我推荐几只银行股",
  "context": {}
}

工作流程:

  1. Claude理解用户意图(行业="银行",任务="推荐")
  2. 生成Qwen3分析任务
  3. Qwen3执行数据筛选和分析
  4. Claude综合结果,生成自然语言回答

3. AI增强推荐

GET /api/ai/recommendations/explained?limit=10

特点:

  • 结合真实市场数据
  • Claude提供投资逻辑解释
  • 包含风险提示

4. 市场概览

GET /api/ai/market/overview

返回:

  • 实时市场情绪
  • 热门板块
  • 资金流向
  • AI分析

故障排查

1. Backend无法启动

# 查看详细日志
docker-compose logs backend

# 常见问题:
# - TuShare token无效 → 检查.env中的TUSHARE_TOKEN
# - 数据库连接失败 → 确保postgres服务已启动
# - Ollama连接失败 → 确保Ollama在本机运行 (ollama serve)

2. Qwen3模型调用失败

# 确认Ollama服务运行
ps aux | grep ollama

# 确认模型已下载
ollama list | grep qwen3-coder

# 测试Ollama API
curl http://localhost:11434/api/generate -d '{
  "model": "qwen3-coder:30b-a3b-q8_0",
  "prompt": "Hello",
  "stream": false
}'

3. TuShare API限流

# 症状:日志中出现 "API limit exceeded"
# 解决:
# 1. 增加缓存TTL(backend/app/config.py)
# 2. 减少并发请求
# 3. 使用TuShare积分账户

4. 前端无法访问后端

# 检查CORS配置
# backend/app/config.py 中的 CORS_ORIGINS

# 确保包含前端URL
CORS_ORIGINS=http://localhost:8090,http://localhost:5173

性能优化

1. 启用Redis缓存预热

# 访问缓存预热端点
curl -X POST http://localhost:8001/api/cache/prewarm

2. 调整筛选阶段

编辑 backend/app/routes/recommendations.py:

# 为了更快的响应,可以选择性禁用某些筛选
recommended_stocks = stock_universe.get_recommended_stocks(
    market="all",
    top_n=30,
    enable_liquidity_filter=True,   # 保留
    enable_fundamental_filter=True, # 保留
    enable_technical_filter=False   # 禁用(节省时间)
)

3. 使用更小的Qwen模型

如果qwen3-coder:30b太大,可以使用更小的模型:

# 下载更小的模型
ollama pull qwen3-coder:14b

# 更新 .env
DEEPSEEK_MODEL=qwen3-coder:14b

监控和日志

查看实时日志

# 所有服务
docker-compose logs -f

# 特定服务
docker-compose logs -f backend
docker-compose logs -f postgres
docker-compose logs -f redis

日志文件位置

backend/logs/app.log          # 应用日志
backend/logs/error.log        # 错误日志

监控指标

访问:http://localhost:8001/api/monitoring/stats

返回:

  • API调用统计
  • 缓存命中率
  • 平均响应时间
  • 错误率

停止服务

# 停止所有服务(保留数据)
docker-compose stop

# 停止并删除容器(保留数据卷)
docker-compose down

# 完全清理(包括数据)
docker-compose down -v

升级部署

# 1. 拉取最新代码
git pull

# 2. 重新构建镜像
docker-compose build

# 3. 重启服务
docker-compose up -d

# 4. 查看更新日志
docker-compose logs -f backend

生产环境建议

1. 使用专用数据库

不要使用Docker容器内的PostgreSQL,使用云数据库或独立部署:

# .env
DATABASE_URL=postgresql://user:pass@your-db-host:5432/stock_ai

2. 启用SSL

更新 docker-compose.yml,添加Nginx反向代理:

nginx:
  image: nginx:alpine
  ports:
    - "443:443"
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
    - ./ssl:/etc/nginx/ssl

3. 配置监控

使用Prometheus + Grafana监控系统健康:

docker-compose -f docker-compose.yml -f docker-compose.monitoring.yml up -d

4. 定期备份

# 备份PostgreSQL
docker exec stock_postgres pg_dump -U stockai stock_ai > backup.sql

# 备份Redis
docker exec stock_redis redis-cli --rdb /data/dump.rdb

常见问题 (FAQ)

Q1: 为什么推荐列表是空的?

A: 可能原因:

  1. TuShare token无效或过期
  2. 市场条件严格,没有股票通过筛选
  3. 检查日志:docker-compose logs backend | grep "No stocks"

Q2: AI助手响应太慢?

A: 优化建议:

  1. 使用更小的Qwen模型(14b代替30b)
  2. 减少分析任务数量
  3. 启用Redis缓存

Q3: 如何添加更多股票到推荐池?

A: 编辑 backend/app/modules/stock_universe.py 中的筛选参数:

def filter_by_liquidity(self, stocks, min_turnover=5e7):  # 降低最小成交额
def filter_by_fundamentals(self, stocks, max_pe=100):      # 放宽PE限制

联系支持