2. 数据获取与处理:A股数据源选择、碳中和概念股池构建、财务数据获取、数据清洗与预处理

各位同学,欢迎来到实战环节的第一站。

做量化投资,说白了就是和数据打交道。数据质量不行,后面模型再花哨也是白搭。我见过太多人把精力全花在策略上,结果数据源一换,回测结果直接翻车。嗯,咱们今天就把地基打牢。

2.1 A股数据源选择:Tushare vs AkShare

国内做A股量化,绕不开两个库:Tushare和AkShare。我个人两个都用过,各有各的脾气。

对比维度 Tushare AkShare
数据全面性 非常全面,财务、行情、概念股都有 覆盖广,但部分数据源不稳定
使用门槛 需要注册、实名、获取token pip安装即用,无需注册
稳定性 高,付费用户有保障 中等,免费接口偶尔断流
适合场景 正式策略、生产环境 快速原型、学习研究
我的建议: 学习阶段先用AkShare,上手快。做正式策略时,建议上Tushare Pro。我在项目中遇到过AkShare某天突然拿不到数据,排查了半天发现是对方网站改版了。从那以后,生产环境我都用Tushare。

2.2 碳中和概念股池构建

概念股池怎么来?最直接的办法是用Tushare的概念股分类接口。碳中和相关的概念标签包括:

  • 新能源(光伏、风电、储能)
  • 新能源汽车产业链
  • 节能减排(环保设备、碳交易)
  • 绿色电力(水电、核电)

代码实现如下:

import tushare as ts

# 初始化,记得替换成你自己的token
pro = ts.pro_api('your_token_here')

# 获取概念股列表
concept = pro.concept()
print(concept[concept['name'].str.contains('碳中和|新能源|光伏|风电')])

# 获取具体概念成分股
carbon_neutral = pro.concept_detail(id='你的概念ID')
stock_list = carbon_neutral['concept_name'].tolist()
print(f'共获取到 {len(stock_list)} 只碳中和概念股')
避坑指南: 我曾经发现Tushare的概念股列表更新有延迟。新纳入的概念股可能要等2-3个交易日才能查到。建议每周手动核对一次,或者用多个数据源交叉验证。

2.3 财务数据获取

有了股票池,下一步就是拉财务数据。量化轮动策略最常用的财务指标包括:

  • 营业收入(季度/年度)
  • 净利润
  • ROE(净资产收益率)
  • 毛利率
  • 资产负债率

获取代码示例:

# 获取单只股票的财务数据
df = pro.fina_indicator(ts_code='600519.SH', 
                        start_date='20230101', 
                        end_date='20231231',
                        fields='ts_code,end_date,roe,profit_dedt')

# 批量获取整个股票池
def get_financial_data(stock_list):
    all_data = []
    for code in stock_list:
        try:
            data = pro.fina_indicator(ts_code=code, 
                                      start_date='20230101',
                                      fields='ts_code,end_date,roe,profit_dedt')
            all_data.append(data)
        except Exception as e:
            print(f'{code} 数据获取失败: {e}')
    return pd.concat(all_data, ignore_index=True)

financial_df = get_financial_data(stock_list)

你想想看,如果手动去一个个股票查财务数据,几百只股票得查到什么时候?用代码批量拉,几分钟搞定。

2.4 数据清洗与预处理

数据拿到手,千万别直接用。原始数据里什么妖魔鬼怪都有。我总结了一套清洗流程:

  1. 缺失值处理:财务数据常有空值,尤其是新上市的公司。我习惯用行业均值填充,或者直接剔除缺失超过30%的股票。
  2. 异常值检测:比如ROE突然飙到200%,明显是数据错误。用3σ原则或者箱线图来过滤。
  3. 数据类型转换:日期字段转datetime,金额字段转float。
  4. 去重:同一个股票同一天可能有重复记录,保留最新一条。
import pandas as pd
import numpy as np

def clean_financial_data(df):
    # 1. 缺失值处理
    df = df.dropna(thresh=len(df.columns) * 0.7)  # 删除缺失超过30%的行
    
    # 2. 行业均值填充
    df['roe'] = df.groupby('industry')['roe'].transform(
        lambda x: x.fillna(x.mean()))
    
    # 3. 异常值过滤(3σ原则)
    for col in ['roe', 'profit_dedt']:
        mean = df[col].mean()
        std = df[col].std()
        df = df[(df[col] >= mean - 3*std) & (df[col] <= mean + 3*std)]
    
    # 4. 日期格式统一
    df['end_date'] = pd.to_datetime(df['end_date'])
    
    return df

clean_df = clean_financial_data(financial_df)
print(f'清洗前: {len(financial_df)} 条, 清洗后: {len(clean_df)} 条')
核心要点: 数据清洗不是一次性的活。每次跑策略前都要做一遍,因为数据源会更新,异常值也会变。我习惯把清洗逻辑封装成函数,每次调用就行。

2.5 本章知识体系总览

下面这张图,把咱们这章的核心逻辑串起来了:

数据获取与处理流程 数据源选择 Tushare / AkShare 概念股池构建 碳中和相关概念标签 财务数据获取 ROE/营收/利润 数据清洗与预处理 缺失值处理 → 异常值检测 → 类型转换 → 去重 行业均值填充 / 3σ原则 / 日期格式化 清洗后的高质量数据集

这张图把咱们这章的内容串起来了。从数据源选择开始,到概念股池构建,再到财务数据获取,最后经过清洗得到干净的数据集。每一步都有坑,但每一步也都有解法。

个人经验: 数据清洗这一步,我建议你多花点时间。我早期做策略时,就因为没处理好异常值,导致回测收益率虚高20%。后来排查了三天才发现是某只股票的数据录入错误。嗯,从那以后,我对数据清洗再也不敢马虎了。

好了,数据准备这块就讲到这里。记住一句话:好数据是好策略的起点。下一章咱们会基于这些数据,开始构建真正的轮动策略。


蓝海数据掘金营,专注资料整理