一、进阶技能树:从「会取数」到「会造因子」
如果说第一篇是「量化民工」的必备技能,那么第二篇就是「量化研究员」的分水岭。你需要掌握:
1️⃣ 财务数据分析能力:读懂资产负债表、利润表、现金流量表,提取价值/成长/质量因子
2️⃣ 时序特征工程:用移动平均、EMA、标准差等构造技术因子
3️⃣ 截面分析能力:行业中性、市值中性、Z-Score标准化,消除冗余信息
4️⃣ 多因子合成:IC测试、因子相关性、因子加权
二、财务数据:量化因子的「金矿」
AmazingData的InfoData类提供了完整的财务数据接口,涵盖三大报表+业绩快报+业绩预告。对于普通人来说,你不需要像会计师那样逐行分析,只需要提取几个关键字段即可。
三大报表核心字段速查:
资产负债表(Balance Sheet):
• TOTALASSETS:资产总计 → 用于计算ROA
• TOT_SHARE_EQUITY_INCL_MININT:股东权益合计 → 用于计算ROE、PB
• TOT_SHARE:期末总股本(股) → 用于计算每股指标
利润表(Income):
• NETPROINCLMIN_INT_INC:净利润(含少数股东损益) → 用于计算ROE
• TOTOPERAREV:营业总收入 → 用于计算营收增长率
• BASIC_EPS:基本每股收益 → 价值因子
现金流量表(Cash Flow):
• NETCASHFLOWS_OPERA_ACT:经营活动现金流净额 → 用于计算经营性现金流/市值
• FREECASHFLOW:企业自由现金流量 → 质量因子
实战代码:批量获取全市场财务数据
import AmazingData as ad
from AmazingData.operator.math_function import MathFunction
from AmazingData.operator.statistics_function import StatisticsFunction
from AmazingData.operator.time_series_function import TimeSeriesFunction
from AmazingData.operator.cross_section_function import CrossSectionFunction
import pandas as pd
import numpy as np
# 登录(略,同第一篇)
# ad.login(...)
base_data = ad.BaseData()
info_data = ad.InfoData()
calendar = base_data.get_calendar()
today = calendar[-1]
# 获取全市场历史代码(防幸存者偏差)
all_codes = base_data.get_hist_code_list(
security_type='EXTRA_STOCK_A_SH_SZ',
start_date=20200101,
end_date=today,
local_path='D://AmazingData_local_data//'
)
# 获取资产负债表(本地缓存,第一次较慢)
balance_sheet = info_data.get_balance_sheet(
code_list=all_codes,
local_path='D://AmazingData_local_data//',
is_local=True
)
# 获取利润表
income = info_data.get_income(
code_list=all_codes,
local_path='D://AmazingData_local_data//',
is_local=True
)
print("资产负债表字段示例:")
print(list(balance_sheet[all_codes[0]].columns)[:10])
print("利润表字段示例:")
print(list(income[all_codes[0]].columns)[:10])
数据说明:财务数据返回的是dict,key为股票代码,value为DataFrame。每个股票的报表包含多个报告期(季报、年报),需要通过REPORTING_PERIOD字段筛选最新报告期。
三、构建经典因子:PB-ROE模型
PB-ROE是价值投资最经典的框架之一:低PB(便宜)+ 高ROE(质量好)= 潜在超额收益。我们用AmazingData的财务数据来构造这两个因子。
Step 1:计算ROE和PB
def calc_factors(balance_sheet, income, market_data, trade_date):
'''
计算单期PB和ROE因子
'''
pb_list = []
roe_list = []
codes = []
for code in balance_sheet.keys():
try:
bs = balance_sheet[code]
inc = income[code]
# 取最新报告期(合并报表)
bs_latest = bs[bs['STATEMENTTYPE'] == '1'].sort_values('REPORTINGPERIOD').iloc[-1]
inc_latest = inc[inc['STATEMENTTYPE'] == '1'].sort_values('REPORTINGPERIOD').iloc[-1]
# 股东权益
equity = bs_latest['TOT_SHARE_EQUITY_INCL_MININT']
# 总股本(股)
total_share = bs_latest['TOT_SHARE']
# 净利润
net_profit = inc_latest['NETPROINCLMIN_INT_INC']
# 获取当日收盘价(从market_data.query_kline或本地缓存)
# 这里假设price_df是已获取的收盘价DataFrame
if code in price_df.columns and trade_date in price_df.index:
close_price = price_df.loc[trade_date, code]
# 计算PB = 总市值 / 净资产 = 收盘价 * 总股本 / 股东权益
market_cap = close_price * total_share
pb = market_cap / equity if equity > 0 else np.nan
# 计算ROE = 净利润 / 股东权益
roe = net_profit / equity if equity > 0 else np.nan
pb_list.append(pb)
roe_list.append(roe)
codes.append(code)
except Exception as e:
continue
factor_df = pd.DataFrame({
'code': codes,
'PB': pb_list,
'ROE': roe_list
}).set_index('code')
return factor_df
# 假设已获取某日全市场收盘价
factor_df = calc_factors(balance_sheet, income, market_data, '20240630')
print(factor_df.describe())
Step 2:截面标准化(Z-Score)
不同行业的PB天然不同(银行PB低、科技PB高),直接比较不公平。AmazingData的截面函数CrossSectionFunction提供了CSZSCORE,可以对因子进行Z-Score标准化:
# 构建截面数据:行=日期,列=股票
# 假设我们有多个交易日的PB和ROE数据
pb_panel = pd.DataFrame({date: pb_series for date, pb_series in pb_dict.items()}).T
roe_panel = pd.DataFrame({date: roe_series for date, roe_series in roe_dict.items()}).T
# 截面Z-Score标准化
pb_zscore = CrossSectionFunction.CSZSCORE(pb_panel)
roe_zscore = CrossSectionFunction.CSZSCORE(roe_panel)
# 合成因子:低PB(取负)+ 高ROE
# 注意:PB是越低越好,所以取负号;ROE越高越好,保持正值
combined_factor = -pb_zscore + roe_zscore
# 截面排名,取前50只
daily_top50 = CrossSectionFunction.CSRANK(combined_factor, ascending=False).apply(
lambda x: x <= 50, axis=1
)
print("每日选股结果(True表示入选):")
print(daily_top50.tail())
因子中性化:实际研究中,还需要做市值中性化和行业中性化。AmazingData提供了get_industry_constituent和get_industry_base_info接口,可以获取行业分类,配合回归去残差即可完成中性化。
四、时序特征工程:技术因子的「自动化工厂」
除了财务因子,技术因子也是量化策略的重要组成部分。AmazingData内置了丰富的时序函数和统计函数,让你不用自己写循环就能实现复杂计算。
常用时序函数一览:
• MA(X,N):N日简单移动平均
• EMA(X,N):N日指数移动平均
• HHV(X,N):N周期内最高值
• LLV(X,N):N周期内最低值
• STD(X,N):N周期标准差(波动率因子)
• REF(X,N):引用N周期前的值(计算环比)
• SUM(X,N):N周期求和
• CROSS(A,B):A上穿B时返回1(金叉信号)
实战:用AmazingData算20日波动率 + 5日均价偏离度
# 获取某股票日线(同第一篇)
df = kline_dict['600519.SH']
# 计算20日收益率标准差(波动率因子)
returns = df['close'].pct_change()
vol_20 = StatisticsFunction.STD(returns, 20)
# 计算5日均价
ma5 = TimeSeriesFunction.MA(df['close'], 5)
# 计算价格偏离度 = (收盘价 - 5日均价) / 5日均价
deviation = (df['close'] - ma5) / ma5
# 金叉信号:5日均线上穿20日均线
ma20 = TimeSeriesFunction.MA(df['close'], 20)
golden_cross = TimeSeriesFunction.CROSS(ma5, ma20)
# 整合到DataFrame
df['vol_20'] = vol_20
df['deviation_ma5'] = deviation
df['golden_cross'] = golden_cross
print(df[['close', 'vol_20', 'deviation_ma5', 'golden_cross']].tail(20))
五、截面分析:消除「苹果比橘子」的谬误
截面函数是量化多因子策略的核心工具。AmazingData的CrossSectionFunction提供了16个截面算子,覆盖从基础统计到标准化排名的全链路。
核心截面算子:
• CSMEAN / CSSTD / CSVAR:截面均值、标准差、方差
• CSZSCORE:Z-Score标准化(零均值、单位方差)
• CSNORMALIZE:Min-Max归一化到[0,1]
• CSRANK:截面排名(处理极端值的神器)
• CSPCTRANK:百分位排名(0-1之间)
• CSCORR:截面相关度(计算两个因子的共线性)
• CSDEMEAN:截面去均值(常用于行业中性化)
实战:因子IC值计算(信息系数)
IC值衡量因子对未来收益的预测能力,是因子评价的金标准。
# 计算下期收益率(未来5日)
future_return = price_df.pct_change(5).shift(-5) # 未来5日收益
# 截面IC = 因子值与下期收益的截面相关系数
ic_series = CrossSectionFunction.CSCORR(combined_factor, future_return)
print(f"IC均值:{ic_series.mean():.4f}")
print(f"IC标准差:{ic_series.std():.4f}")
print(f"IR比率:{ic_series.mean()/ic_series.std():.4f}")
# IC > 0.02 通常认为因子有效;IR > 0.5 认为因子稳定