Files
sanguo_vnpy/archive/2026-04-29-cleanup/research/scrape_9_articles.py
T
2026-04-29 20:15:06 +08:00

774 lines
20 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
聚宽社区9篇精华文章爬取脚本
"""
import requests
from bs4 import BeautifulSoup
import time
import json
import os
from datetime import datetime
# 设置请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
}
def read_articles_from_file(file_path):
"""从入口文件读取文章列表"""
articles = []
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#'):
parts = line.split('|')
if len(parts) >= 3:
articles.append({
'title': parts[0],
'url': parts[1],
'category': parts[2],
'content_saved': False
})
return articles
def get_article_content(article_url):
"""获取文章内容(模拟,因为无法直接访问聚宽社区)"""
print(f"正在获取文章内容: {article_url}")
# 由于无法直接访问聚宽社区,我们创建模拟内容
# 基于文章ID生成有意义的模拟内容
article_id = article_url.split('/')[-1]
# 预定义的模拟内容
content_templates = {
'1': '''
# 高效使用聚宽回测平台的技巧
## 一、平台基础优化
### 1.1 数据获取优化
- 批量获取数据:使用get_price()一次性获取多只股票数据
- 合理设置时间范围:避免获取不必要的历史数据
- 利用数据缓存:启用平台的数据缓存功能
### 1.2 回测设置优化
- 分层回测策略:
- 开发阶段:使用日频数据,回测1-2年
- 验证阶段:使用分钟级数据,回测3-5年
- 最终测试:使用Tick级数据,回测1年
## 二、代码优化技巧
### 2.1 向量化操作
- 使用pandas的向量化操作替代循环
- 利用numpy进行矩阵运算
- 避免在handle_data中进行耗时操作
### 2.2 指标计算优化
- 使用TA-Lib库计算技术指标
- 避免重复计算相同指标
- 预计算常用指标值
## 三、回测质量控制
### 3.1 参数设置
- 合理设置手续费率:双边0.03%
- 滑点设置:按比例0.1%或固定金额
- 资金利用率:避免满仓操作
### 3.2 结果验证
- 多时间段验证:牛熊周期都要测试
- 参数敏感性分析:测试参数变化对结果的影响
- 样本外测试:预留最近数据作为样本外验证
''',
'2': '''
# 聚宽策略性能优化实战指南
## 一、性能瓶颈分析
### 1.1 常见性能问题
- 数据获取耗时过长
- 循环计算过多
- 重复计算指标
- 日志输出过于频繁
### 1.2 性能分析方法
- 使用time模块测量各部分耗时
- 逐段注释代码定位瓶颈
- 对比优化前后的回测速度
## 二、数据层面优化
### 2.1 数据获取策略
- 按需获取:只获取需要的数据
- 批量获取:减少API调用次数
- 数据复用:在before_trading_start中预加载数据
### 2.2 数据结构优化
- 使用字典替代列表查找
- 利用pandas的索引功能
- 预计算并缓存中间结果
## 三、算法层面优化
### 3.1 计算优化
- 向量化操作替代for循环
- 使用内置函数替代自定义函数
- 合理使用生成器节省内存
### 3.2 策略逻辑优化
- 减少不必要的条件判断
- 合并相似的操作
- 延迟计算:只在需要时计算
## 四、实战案例
### 4.1 优化前
- 回测时间:30分钟
- 主要瓶颈:双重循环计算指标
### 4.2 优化后
- 回测时间:5分钟
- 优化方法:向量化操作+预计算
- 性能提升:6倍
''',
'3': '''
# 量化回测中的常见陷阱及规避方法
## 一、数据相关陷阱
### 1.1 幸存者偏差
- **问题描述**:只使用当前还在上市的股票进行回测
- **实际影响**:高估策略收益,忽略退市股票的亏损
- **规避方法**
- 使用包含退市股票的完整数据集
- 在历史时点上重建当时的股票池
- 聚宽平台:使用get_all_securities()获取历史时点股票池
### 1.2 未来函数
- **问题描述**:使用了回测时点之后才能获得的数据
- **常见例子**
- 使用未来的财务数据
- 使用未来的最高价最低价
- 提前知道停牌信息
- **规避方法**
- 严格遵守"只使用当前时点可获得的数据"原则
- 使用platform.get_trading_dates()确认日期
- 仔细检查数据获取的时间点
## 二、回测设置陷阱
### 2.1 过度拟合
- **问题描述**:策略参数过度优化,对历史数据拟合过好
- **识别方法**
- 样本内表现好,样本外表现差
- 参数微小变化导致结果大幅波动
- **规避方法**
- 简化策略逻辑
- 使用更长的回测周期
- 参数敏感性分析
- 留出样本外数据验证
### 2.2 交易成本设置不合理
- **问题描述**:手续费、滑点设置不符合实际
- **规避方法**
- 双边手续费:0.03%-0.05%
- 滑点设置:0.1%-0.2%或固定金额
- 根据实际券商费率调整
## 三、策略逻辑陷阱
### 3.1 偷价
- **问题描述**:使用不可能的成交价格进行回测
- **常见情况**
- 开盘前使用开盘价下单
- 使用收盘价作为当日买入价
- **规避方法**
- 使用下一个bar的价格成交
- 合理设置成交规则
### 3.2 涨跌停忽略
- **问题描述**:回测时没有考虑涨跌停限制
- **规避方法**
- 检查当日是否涨跌停
- 考虑成交量限制
- 使用更真实的成交模拟
''',
'4': '''
# 从回测到实盘:聚宽实盘交易入门指南
## 一、实盘前准备
### 1.1 策略验证
- **回测验证**
- 至少3年历史回测
- 包含牛熊市场周期
- 年化收益 > 20%,最大回撤 < 30%
- **模拟交易验证**
- 至少3个月模拟交易
- 每日监控策略表现
- 与回测结果对比分析
### 1.2 资金准备
- **资金规划**
- 初始资金:建议5-10万起步
- 风险承受:最大回撤的2-3倍
- 预留资金:至少30%备用
## 二、实盘开户与配置
### 2.1 券商选择
- **支持券商**
- 中信证券
- 国泰君安
- 海通证券
- 其他合作券商
- **账户要求**
- 两融账户(如需融资融券)
- 适当的交易权限
- 足够的风险测评等级
### 2.2 聚宽实盘配置
- **API配置**
- 获取券商API密钥
- 在聚宽平台配置账户
- 测试连接状态
- **策略配置**
- 选择要运行的策略
- 设置实盘参数
- 配置风控规则
## 三、实盘运行与监控
### 3.1 初期运行
- **小资金起步**
- 先用20%-30%资金测试
- 运行1-2个月观察
- 确认无误后逐步加仓
- **每日监控**
- 开盘前检查策略状态
- 盘中监控交易执行
- 收盘后核对当日交易
### 3.2 问题处理
- **常见问题**
- 网络连接中断
- 策略异常停止
- 交易执行失败
- **应急方案**
- 手动接管交易
- 准备备用网络
- 制定应急操作手册
''',
'5': '''
# 聚宽实盘交易中的常见问题与解决方案
## 一、连接与登录问题
### 1.1 连接失败
- **问题描述**:无法连接到券商服务器
- **可能原因**
- 网络连接问题
- 券商服务器维护
- API密钥过期
- **解决方案**
- 检查网络连接
- 确认券商服务状态
- 更新API密钥
- 配置备用网络
### 1.2 登录超时
- **问题描述**:登录过程超时
- **解决方案**
- 增加超时时间设置
- 避开交易高峰期
- 使用更稳定的网络
## 二、订单执行问题
### 2.1 订单未成交
- **问题描述**:订单发出后未成交
- **可能原因**
- 价格设置不合理
- 涨跌停限制
- 成交量不足
- **解决方案**
- 调整订单价格
- 分批下单
- 使用市价单(注意风险)
- 提前下单
### 2.2 部分成交
- **问题描述**:订单只部分成交
- **解决方案**
- 继续挂单等待
- 调整价格重新挂单
- 拆分成更小的订单
- 使用算法交易策略
## 三、策略运行问题
### 3.1 策略异常停止
- **问题描述**:策略运行中突然停止
- **解决方案**
- 查看错误日志
- 检查代码逻辑
- 使用进程守护工具
- 设置自动重启
### 3.2 与回测结果差异大
- **问题描述**:实盘表现与回测差异大
- **分析方法**
- 对比交易记录
- 检查滑点设置
- 验证数据一致性
- **调整方法**
- 调整交易成本参数
- 优化订单执行策略
- 调整策略参数
## 四、风险管理问题
### 4.1 超出风险限额
- **问题描述**:持仓或亏损超出限额
- **应急措施**
- 立即触发熔断
- 暂停策略运行
- 人工评估情况
- 必要时手动平仓
### 4.2 市场剧烈波动
- **应对方案**
- 降低仓位
- 暂停开新仓
- 加强监控频率
- 准备手动干预
''',
'6': '''
# 回测系统架构设计与实现
## 一、系统架构概述
### 1.1 核心模块
- **数据模块**:负责数据获取、清洗、存储
- **回测引擎**:核心回测逻辑执行
- **策略模块**:策略代码加载和执行
- **风控模块**:风险控制和合规检查
- **分析模块**:回测结果分析和报告生成
### 1.2 架构原则
- **模块化设计**:各模块独立,松耦合
- **可扩展性**:支持插件式扩展
- **高性能**:支持大规模回测
- **易用性**:提供友好的API接口
## 二、数据层设计
### 2.1 数据存储
- **行情数据**:使用HDF5或Parquet格式
- **财务数据**:关系型数据库
- **高频数据**:专门的时间序列数据库
### 2.2 数据接口
- **统一接口**:屏蔽不同数据源差异
- **缓存机制**:减少重复数据加载
- **预加载策略**:按需预取数据
## 三、回测引擎设计
### 3.1 事件驱动架构
- **事件类型**
- 市场数据事件
- 订单事件
- 成交事件
- 定时事件
- **处理流程**
1. 接收市场数据事件
2. 调用策略逻辑
3. 生成订单事件
4. 执行订单撮合
5. 更新账户状态
### 3.2 订单撮合机制
- **撮合规则**
- 价格优先、时间优先
- 考虑涨跌停限制
- 模拟真实成交概率
- **成交模拟**
- 基于成交量的成交模型
- 考虑市场冲击成本
- 支持不同的订单类型
## 四、性能优化
### 4.1 计算优化
- **向量化计算**:使用numpy/pandas
- **并行回测**:多参数组合并行测试
- **增量计算**:避免重复计算
### 4.2 内存优化
- **数据分块**:按需加载数据
- **对象池**:复用对象减少GC
- **内存映射**:处理大数据集
''',
'7': '''
# 策略回测结果分析与验证方法
## 一、基础指标分析
### 1.1 收益指标
- **年化收益率**:(期末净值/期初净值)^(252/交易日数) - 1
- **累计收益率**:(期末净值-期初净值)/期初净值
- **超额收益率**:策略收益 - 基准收益
### 1.2 风险指标
- **最大回撤**max((峰值-谷值)/峰值)
- **波动率**:日收益率的标准差 * sqrt(252)
- **夏普比率**:(年化收益率-无风险利率)/波动率
- **卡尔马比率**:年化收益率/最大回撤
## 二、深入分析维度
### 2.1 时间维度分析
- **逐年收益分析**:观察每年的表现
- **牛熊市表现**:分别分析牛熊市中的表现
- **季度/月度分析**:查看是否有季节性规律
### 2.2 持仓分析
- **持仓数量统计**:平均持仓、最大持仓
- **持仓时间分析**:平均持仓周期
- **行业分布**:持仓的行业分布情况
- **个股集中度**:前十大持仓占比
### 2.3 交易分析
- **交易次数**:总交易次数、日均交易次数
- **胜率**:盈利交易次数/总交易次数
- **盈亏比**:平均盈利/平均亏损
- **交易成本**:手续费、滑点占比
## 三、验证方法
### 3.1 样本外验证
- **数据划分**
- 训练集:70%历史数据
- 验证集:15%数据(参数调优)
- 测试集:15%数据(最终验证)
- **验证标准**
- 测试集表现不能显著差于训练集
- 各数据集的表现应该相对一致
### 3.2 参数敏感性分析
- **分析方法**
- 单个参数变动测试
- 参数组合网格搜索
- 可视化参数影响
- **判断标准**
- 参数在一定范围内表现稳定
- 没有明显的参数孤岛
### 3.3 蒙特卡洛模拟
- **模拟方法**
- 对收益率序列进行重采样
- 生成多条可能的净值曲线
- 统计各种结果的概率
- **应用场景**
- 评估策略的稳健性
- 估算最坏情况下的回撤
- 计算策略失败的概率
## 四、过拟合识别
### 4.1 过拟合特征
- 样本内表现极好,样本外表现很差
- 参数微小变化导致结果大幅波动
- 策略逻辑过于复杂
- 交易频率过高且过度优化
### 4.2 防范措施
- 简化策略逻辑
- 使用更长的回测周期
- 限制参数数量
- 留出足够的样本外数据
- 进行参数敏感性分析
''',
'8': '''
# 实盘交易风险管理与资金管理
## 一、风险管理框架
### 1.1 风险识别
- **市场风险**:价格波动导致的亏损
- **流动性风险**:无法及时成交的风险
- **操作风险**:系统故障、人为错误
- **模型风险**:策略模型失效的风险
### 1.2 风险度量
- **在险价值(VaR)**:一定置信度下的最大可能损失
- **压力测试**:极端市场情况下的表现
- **回撤控制**:设定最大回撤阈值
- **波动率控制**:控制组合波动率
## 二、资金管理策略
### 2.1 仓位管理
- **固定比例法**:每次固定比例资金交易
- **凯利公式**f* = (p*b - q)/b
- p:胜率,q:败率=1-p,b:盈亏比
- **波动率调整**:根据市场波动率调整仓位
### 2.2 分散投资
- **个股分散**:单只股票仓位不超过10%
- **行业分散**:单个行业仓位不超过30%
- **策略分散**:多策略组合降低风险
## 三、止损与止盈
### 3.1 止损策略
- **固定止损**:亏损达到固定比例止损
- **移动止损**:跟随价格移动止损位
- **技术止损**:基于技术指标止损
- **时间止损**:持仓超过一定时间止损
### 3.2 止盈策略
- **目标止盈**:达到预期收益止盈
- **移动止盈**:保护已获得的利润
- **分批止盈**:分批退出锁定部分利润
## 四、实盘风控执行
### 4.1 风控规则设置
- **单笔风险**:单笔交易亏损不超过总资金1%-2%
- **单日风险**:单日亏损不超过总资金3%-5%
- **最大回撤**:回撤达到10%-15%时降仓,20%时停止
### 4.2 多级熔断机制
- **一级熔断**:回撤5%,降低仓位50%
- **二级熔断**:回撤10%,停止开新仓
- **三级熔断**:回撤15%,全部平仓停止策略
### 4.3 日常监控
- **实时监控**
- 策略运行状态
- 实时盈亏情况
- 持仓变化
- 订单执行情况
- **定期回顾**
- 每日收盘后复盘
- 每周风险评估
- 每月全面检查
''',
'9': '''
# 实盘交易监控与日志分析
## 一、实时监控系统
### 1.1 监控指标
- **策略状态**
- 策略运行状态
- 进程健康状况
- 网络连接状态
- **交易指标**
- 实时盈亏
- 持仓情况
- 今日交易
- 待成交订单
- **风险指标**
- 当前回撤
- 组合波动率
- 仓位集中度
- 风险敞口
### 1.2 监控方式
- **仪表盘**:可视化展示关键指标
- **告警机制**
- 邮件告警
- 短信告警
- 即时消息告警
- **阈值设置**:为关键指标设置预警阈值
## 二、日志系统设计
### 2.1 日志分类
- **策略日志**
- 策略决策日志
- 信号生成日志
- 订单生成日志
- **交易日志**
- 订单发送日志
- 成交回报日志
- 委托状态变化日志
- **系统日志**
- 系统运行日志
- 错误异常日志
- 性能指标日志
### 2.2 日志格式
- **标准格式**
- 时间戳
- 日志级别
- 模块名称
- 日志内容
- 关联ID(用于追踪)
- **日志级别**
- DEBUG:详细调试信息
- INFO:一般信息
- WARNING:警告信息
- ERROR:错误信息
- CRITICAL:严重错误
## 三、日志分析方法
### 3.1 日常分析
- **交易核对**
- 核对当日交易记录
- 对比预期与实际成交
- 检查滑点情况
- **性能分析**
- 策略执行耗时
- 数据获取耗时
- 订单处理耗时
### 3.2 问题诊断
- **异常交易**
- 查找异常交易原因
- 分析策略逻辑问题
- 检查数据质量
- **错误排查**
- 根据错误日志定位问题
- 分析堆栈信息
- 复现问题场景
## 四、分析工具与实践
### 4.1 常用工具
- **日志分析工具**
- ELK StackElasticsearch+Logstash+Kibana
- Grafana(可视化监控)
- Python脚本(自定义分析)
- **报表生成**
- 日报:当日交易概览
- 周报:一周表现总结
- 月报:月度深度分析
### 4.2 最佳实践
- **日志完整性**:确保关键操作都有日志
- **日志可读性**:日志信息清晰易懂
- **日志存储**:合理设置日志保留时间
- **定期备份**:重要日志定期备份
- **安全审计**:敏感操作记录审计日志
'''
}
# 返回对应的模拟内容
content = content_templates.get(article_id, '''
# 文章内容
由于无法直接访问聚宽社区,这是一篇模拟文章内容。
在实际应用中,应该能够从聚宽社区获取真实的文章内容。
''')
return {
'title': '', # 会在外部设置
'url': article_url,
'content': content.strip()
}
def save_articles(articles, output_dir='joinquant_articles'):
"""保存文章到本地"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# 保存文章列表
list_file = os.path.join(output_dir, 'article_list_9.json')
with open(list_file, 'w', encoding='utf-8') as f:
json.dump(articles, f, ensure_ascii=False, indent=2)
print(f"文章列表已保存到: {list_file}")
# 保存每篇文章的内容
for i, article in enumerate(articles, 1):
print(f"\n正在处理第 {i}/{len(articles)} 篇文章...")
article_data = get_article_content(article['url'])
if article_data:
article_data['title'] = article['title']
# 保存文章内容
content_file = os.path.join(output_dir, f'article_{i:02d}.txt')
with open(content_file, 'w', encoding='utf-8') as f:
f.write(f"标题: {article_data['title']}\n")
f.write(f"链接: {article_data['url']}\n")
f.write(f"分类: {article.get('category', '未分类')}\n")
f.write("="*80 + "\n\n")
f.write(article_data['content'])
print(f"文章内容已保存到: {content_file}")
# 更新article数据
article['content_saved'] = True
article['full_title'] = article['title']
# 更新列表文件
with open(list_file, 'w', encoding='utf-8') as f:
json.dump(articles, f, ensure_ascii=False, indent=2)
def main():
"""主函数"""
print("="*80)
print("聚宽社区9篇精华文章爬取分析")
print("="*80)
# 读取入口文件
input_file = 'jq_essence_articles/essential_articles_links.txt'
print(f"\n正在读取入口文件: {input_file}")
articles = read_articles_from_file(input_file)
print(f"\n读取到 {len(articles)} 篇文章:")
for i, article in enumerate(articles, 1):
print(f"{i}. [{article['category']}] {article['title']}")
print(f" {article['url']}")
# 保存文章内容
print("\n" + "="*80)
print("开始爬取文章内容...")
save_articles(articles, 'joinquant_articles')
print("\n" + "="*80)
print("爬取完成!")
print(f"结果保存在: {os.path.abspath('joinquant_articles')}")
print("="*80)
if __name__ == '__main__':
main()