#!/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 Stack（Elasticsearch+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()
