问题描述
请问 ,通过jqdatasdk下载好的本地数据,如何根据未复权价格和复权因子,基于某一个特定的基准日,计算出前复权价格?
解决方案
在量化交易中,处理股票的除权除息是非常重要的一环。如果您已经通过 jqdatasdk 下载了未复权(真实)的行情数据以及对应的复权因子(factor),可以通过简单的数学公式计算出基于任意特定基准日的前复权价格。
1. 计算公式
前复权的核心思想是保持基准日(通常是最近的一个交易日)的价格不变,将历史价格按比例向下调整。
计算公式如下:
目标日的前复权价格 = 目标日的不复权价格 × (目标日的复权因子 / 基准日的复权因子)
- 目标日:您想要计算复权价格的历史某一天。
- 基准日:您选定的作为复权基准的日期(该日的前复权价格等于其不复权价格)。
2. Python 代码实现
假设您已经将数据下载并存储在一个 Pandas DataFrame 中,包含 close(未复权收盘价)和 factor(复权因子)两列,且索引为日期(DatetimeIndex)。
以下是具体的代码示例:
import pandas as pd
import numpy as np
# 假设 df 是您通过 jqdatasdk 下载的数据
# 示例数据结构:
# close factor
# 2023-01-01 10.0 1.0
# 2023-05-01 5.0 2.0 (假设发生了10送10的拆股)
# 2023-10-01 6.0 2.0
# 1. 设定基准日 (例如设定为数据中的最后一天)
benchmark_date = df.index[-1]
# 或者指定特定日期: benchmark_date = pd.to_datetime('2023-10-01')
# 2. 获取基准日的复权因子
benchmark_factor = df.loc[benchmark_date, 'factor']
# 3. 计算前复权价格
# 公式:前复权价格 = 未复权价格 * (当日复权因子 / 基准日复权因子)
df['pre_close'] = df['close'] * (df['factor'] / benchmark_factor)
# 如果您需要计算开盘价、最高价、最低价的前复权,同理:
# df['pre_open'] = df['open'] * (df['factor'] / benchmark_factor)
# df['pre_high'] = df['high'] * (df['factor'] / benchmark_factor)
# df['pre_low'] = df['low'] * (df['factor'] / benchmark_factor)
print(df)
3. 注意事项
- 复权因子的含义:JoinQuant 提供的
factor通常是累计后复权因子。这意味着随着时间的推移,发生分红送转时,factor的值会变大。利用上述公式中的比例关系(当日factor / 基准日factor),可以完美地将后复权因子转化为前复权所需的调整比例。 - 成交量的复权:如果您还需要计算复权后的成交量(
volume),公式是反过来的。因为价格降低了,为了保持成交额不变,成交量需要相应放大:
前复权成交量 = 未复权成交量 × (基准日复权因子 / 目标日复权因子) - 动态复权:在 JoinQuant 官网回测时,通常建议使用
set_option('use_real_price', True)开启真实价格模式,系统会在底层自动处理复权逻辑。但在本地使用jqdatasdk进行研究时,掌握手动复权的方法是非常有必要的。