第四章:财务数据获取与清洗

做量化投资,数据就是你的弹药。没有干净的数据,再牛的模型也是白搭。这一章,咱们就聊聊怎么把三大报表搞到手,再把它收拾得服服帖帖。

4.1 三大报表的数据获取

我个人习惯用 Tushare 和 AKShare 这两个库。前者老牌,后者更新快。你选一个顺手就行。

先看利润表怎么拿:

import akshare as ak
import pandas as pd

# 获取贵州茅台利润表
profit_df = ak.stock_profit_sheet_by_report_em(symbol="600519")
print(profit_df.head())

资产负债表和现金流量表也类似:

# 资产负债表
balance_df = ak.stock_balance_sheet_by_report_em(symbol="600519")

# 现金流量表
cashflow_df = ak.stock_cash_flow_sheet_by_report_em(symbol="600519")

嗯,这里要注意。不同接口返回的字段名可能不一样。我建议你每次拿到数据后,先打印列名看看。

避坑指南: 我曾经遇到过一个问题——同一家公司,不同数据源返回的营收数据差了2个亿。后来发现是一个包含了营业外收入,一个没包含。所以,一定要搞清楚字段定义

4.2 数据对齐与合并

三张报表拿回来了,但它们的报告期可能不一样。有的按季度,有的按半年。怎么办?对齐!

我的做法是:统一用「报告期」作为索引。

# 设置报告期为索引
profit_df.set_index('报告期', inplace=True)
balance_df.set_index('报告期', inplace=True)
cashflow_df.set_index('报告期', inplace=True)

# 横向合并
merged_df = pd.concat([profit_df, balance_df, cashflow_df], axis=1, join='inner')
print(merged_df.shape)

这里用 join='inner' 的意思是:只保留三张表都有的报告期。说白了,就是取交集。

为什么会这样?因为有些公司可能延迟披露某个季度的数据。取交集能保证数据完整性。

小技巧: 如果你发现合并后数据少了很多,可以用 join='outer' 先看看哪些报告期缺失了。然后再去补数据。

4.3 财务指标计算

数据对齐了,接下来就是算指标。ROE、毛利率、净利率,这三个是成长股的核心。

4.3.1 ROE(净资产收益率)

ROE = 净利润 / 净资产。巴菲特最看重的指标之一。

# 计算ROE
merged_df['ROE'] = merged_df['净利润'] / merged_df['净资产']
merged_df['ROE'] = merged_df['ROE'] * 100  # 转为百分比

print(merged_df[['ROE']].head())

我在项目中遇到过一个问题:有些公司净资产为负,ROE 算出来是负数。这时候要小心,可能公司已经资不抵债了。

4.3.2 毛利率

毛利率 = (营业收入 - 营业成本) / 营业收入。这个指标能看出公司的护城河。

merged_df['毛利率'] = (merged_df['营业收入'] - merged_df['营业成本']) / merged_df['营业收入']
merged_df['毛利率'] = merged_df['毛利率'] * 100

你想想看,毛利率持续高于40%的公司,通常有定价权。比如茅台、海天味业。

4.3.3 净利率

净利率 = 净利润 / 营业收入。这个指标反映的是公司最终能赚多少钱。

merged_df['净利率'] = merged_df['净利润'] / merged_df['营业收入']
merged_df['净利率'] = merged_df['净利率'] * 100
核心观点: 毛利率高说明产品好,净利率高说明管理好。两者都高的公司,才是真正的成长股。

4.4 行业分类处理

不同行业的财务指标差异很大。比如,科技公司的毛利率普遍高于制造业。所以,我们需要做行业分类。

我个人习惯用申万行业分类。它把A股分成了28个一级行业。

# 获取行业分类
industry_df = ak.stock_board_industry_name_em()
print(industry_df.head())

拿到行业分类后,把它合并到你的数据框里:

# 假设你有一个股票代码列表
stock_list = ['600519', '000858', '002304']

# 获取每只股票的行业
industry_map = {}
for code in stock_list:
    info = ak.stock_individual_info_em(symbol=code)
    industry = info[info['item'] == '行业']['value'].values[0]
    industry_map[code] = industry

# 合并到主数据框
merged_df['行业'] = merged_df['股票代码'].map(industry_map)
避坑指南: 我曾经犯过一个错误——把不同行业的公司放在一起比较ROE。结果发现,房地产公司的ROE普遍高于消费品公司。但这不代表房地产公司更好,只是行业特性不同。所以,一定要在同行业内比较

4.5 本章知识体系

下面这张图,帮你理清本章的核心逻辑:

财务数据获取与清洗流程 第一步:数据获取 利润表/资产负债表/现金流量表 第二步:数据对齐 按报告期合并,取交集 第三步:指标计算 ROE/毛利率/净利率 第四步:行业分类 申万行业分类/同行业比较 最终输出:干净、对齐的财务数据 可用于量化策略回测 ⚠️ 注意事项 字段定义要确认 不同行业不可直接比较 💡 常用工具 Tushare AKShare

这张图把整个流程串起来了。从数据获取到最终输出,每一步都不能马虎。

我的经验: 刚开始做量化的时候,我花在数据清洗上的时间,比写策略的时间还多。但后来发现,这恰恰是最值得投入的环节。数据干净了,策略的成功率至少提高30%。

好了,这一章的内容就到这里。记住:数据是量化投资的基石。把基础打牢,后面的路才能走得更远。


公众号:蓝海数据掘金营,微信deep3321