第四章:财务数据获取与清洗
做量化投资,数据就是你的弹药。没有干净的数据,再牛的模型也是白搭。这一章,咱们就聊聊怎么把三大报表搞到手,再把它收拾得服服帖帖。
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")
嗯,这里要注意。不同接口返回的字段名可能不一样。我建议你每次拿到数据后,先打印列名看看。
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)
4.5 本章知识体系
下面这张图,帮你理清本章的核心逻辑:
这张图把整个流程串起来了。从数据获取到最终输出,每一步都不能马虎。
好了,这一章的内容就到这里。记住:数据是量化投资的基石。把基础打牢,后面的路才能走得更远。
公众号:蓝海数据掘金营,微信deep3321