第二章:数据源准备——获取行情数据
做量化交易,数据就是你的弹药库。
我见过太多人,策略写得天花乱坠,结果一跑回测,数据源就有问题。嗯,那感觉就像你精心准备了满汉全席,结果发现米是馊的。今天我们就来搞定情绪量化最核心的四个数据源:涨跌家数、成交量、换手率、北向资金。
2.1 涨跌家数——市场情绪的体温计
涨跌家数,说白了就是今天有多少股票在涨,多少在跌。这个数据简单粗暴,但极其有效。
我个人习惯用这个指标来判断市场是否出现极端情绪。比如某天上涨家数不到500家,那基本就是情绪冰点了。反过来,上涨家数超过3000家,那就是沸点区域。
获取这个数据,我一般用 tushare 或者 akshare。下面是我常用的代码:
import akshare as ak
import pandas as pd
# 获取A股涨跌家数
def get_advance_decline_data():
"""
获取全市场涨跌家数数据
返回:DataFrame,包含日期、上涨家数、下跌家数
"""
df = ak.stock_market_activity_baidu()
# 只保留需要的列
result = df[['日期', '上涨家数', '下跌家数']].copy()
result['涨跌比'] = result['上涨家数'] / (result['上涨家数'] + result['下跌家数'])
return result
# 调用示例
data = get_advance_decline_data()
print(data.tail())
2.2 成交量——资金的真实态度
成交量不会骗人。价格可以操纵,但成交量是实打实的真金白银。
我曾经踩过一个坑:只看价格不看量,结果在缩量反弹时追了进去,第二天就被埋了。从那以后,我每次分析情绪都会先看成交量。
获取成交量数据,我推荐用 tushare 的 pro 接口:
import tushare as ts
# 初始化tushare
pro = ts.pro_api('你的token')
# 获取上证指数成交量
def get_market_volume(start_date='20240101', end_date='20241231'):
"""
获取市场整体成交量数据
"""
df = pro.index_daily(ts_code='000001.SH',
start_date=start_date,
end_date=end_date)
# 成交量单位:手
df['vol_ratio'] = df['vol'] / df['vol'].rolling(20).mean()
return df[['trade_date', 'vol', 'vol_ratio']]
volume_data = get_market_volume()
print(volume_data.head())
2.3 换手率——筹码的活跃度
换手率反映的是筹码交换的活跃程度。换手率越高,说明市场分歧越大,情绪越亢奋。
你想想看,如果一只股票换手率只有0.5%,说明没人愿意买卖,市场冷清得很。如果换手率突然飙升到5%以上,那一定是有什么大事发生了。
获取全市场换手率,我一般这样处理:
def get_turnover_rate():
"""
获取全市场平均换手率
使用akshare获取所有A股数据,然后计算平均值
"""
# 获取全部A股实时数据
df = ak.stock_zh_a_spot_em()
# 计算全市场平均换手率
avg_turnover = df['换手率'].mean()
# 也可以按板块分组
sector_turnover = df.groupby('板块')['换手率'].mean()
return avg_turnover, sector_turnover
avg, sector = get_turnover_rate()
print(f"全市场平均换手率: {avg:.2f}%")
print(sector)
- 低于1%:市场冷清,情绪冰点区域
- 1%-3%:正常交易状态
- 高于3%:情绪亢奋,注意风险
2.4 北向资金——聪明钱的动向
北向资金,江湖人称「聪明钱」。这帮外资机构的信息优势和判断力,确实比大多数散户强。
我记得2020年3月,全球股市暴跌,北向资金连续流出。但到了3月底,北向突然开始连续净流入。我当时就判断,底部可能到了。果不其然,后面就是一波大反弹。
获取北向资金数据,我推荐用东方财富的接口:
def get_northbound_flow():
"""
获取北向资金流向数据
包含:沪股通、深股通、合计
"""
# 使用akshare获取北向资金
df = ak.stock_hsgt_north_net_flow_in_em()
# 计算累计净流入
df['累计净流入'] = df['净流入'].cumsum()
# 计算5日均值,用于判断趋势
df['净流入_5日均值'] = df['净流入'].rolling(5).mean()
return df
north_data = get_northbound_flow()
print(north_data.tail(10))
2.5 数据整合——构建情绪数据库
上面四个数据源,单独看都有价值,但整合在一起威力更大。我习惯把它们合并成一个DataFrame,方便后续分析。
def build_sentiment_database():
"""
整合所有情绪数据源
返回:统一的DataFrame
"""
# 获取各数据源
adv_dec = get_advance_decline_data()
volume = get_market_volume()
turnover = get_turnover_rate()
north = get_northbound_flow()
# 按日期合并
sentiment_db = adv_dec.merge(volume, on='trade_date', how='left')
sentiment_db = sentiment_db.merge(north, on='trade_date', how='left')
# 添加换手率(日频数据)
sentiment_db['turnover_rate'] = turnover
# 数据清洗
sentiment_db = sentiment_db.dropna()
sentiment_db = sentiment_db.sort_values('trade_date')
return sentiment_db
# 构建数据库
sentiment_data = build_sentiment_database()
print(sentiment_data.info())
2.6 知识体系总览
下面这张图,是我自己整理的情绪数据源框架。你可以把它当作一个检查清单,每次做情绪分析时对照着看:
数据源准备好了,下一步就是清洗和特征工程。不过那是下一章的内容了。今天先把这四个数据源跑通,你可以在自己的机器上试试看。
1. 涨跌家数:判断市场极端情绪的最直接指标
2. 成交量:结合均量看,避免被单日异常值误导
3. 换手率:反映筹码活跃度,与成交量互补
4. 北向资金:聪明钱的动向,有领先指示作用
5. 四个数据源要整合使用,单一指标容易误判