问题描述
解决方案
在 PTrade 中使用 get_history 函数时,fq(复权)参数的选择取决于你的策略逻辑和使用场景。
简单来说:绝大多数做技术分析和趋势跟踪的策略,应该选择 'pre'(前复权)。
以下是详细的对比和建议:
1. 前复权 (fq='pre') —— 推荐用于策略信号生成
- 含义:以当前价格为基准,对历史价格进行调整。保持当前价格不变,向下调整历史价格,以消除分红、配股、拆细等造成的缺口。
- 适用场景:
- 技术指标计算:计算均线(MA)、MACD、KDJ、RSI 等指标。
- 信号判断:因为实盘交易中获取到的实时价格(
data[security]['close'])是不复权的(即盘面真实价格)。使用前复权计算出的均线,其尾端与当前的实时价格处于同一个价格体系下,可以直接比较(例如:current_price > MA20)。
- 优点:K 线图形连续,技术指标不会因为除权除息出现跳空缺口,且与当前实时股价无缝衔接。
2. 后复权 (fq='post') —— 推荐用于计算长期收益率
- 含义:以上市首日价格为基准,对之后的价格进行调整。保持历史价格不变,向上调整当前和最近的价格。
- 适用场景:
- 资产增长分析:计算一只股票在很长一段时间内的真实累计收益率(假设分红再投资)。
- 回测分析:用于分析如果不考虑除权影响,股价理论上应该到达的高度。
- 缺点:计算出的价格可能非常高(例如某股票现价 10 元,后复权价可能是 500 元)。不能直接拿后复权计算出的均线与当前的实时价格(不复权)进行比较,否则会产生严重的信号错误。
3. 不复权 (fq=None) —— 推荐用于价格校验
- 含义:交易所记录的原始成交价格。
- 适用场景:
- 挂单价格校验:当你需要判断当前价格是否触及涨跌停板(
high_limit/low_limit),或者需要以具体的盘口价格下单时。 - 除权日识别:通过对比前一日收盘价,识别当日是否发生了除权除息。
- 挂单价格校验:当你需要判断当前价格是否触及涨跌停板(
- 缺点:如果股票发生送转或分红,K 线图会出现巨大的跳空缺口,导致技术指标(如均线)突然断崖式下跌,从而触发错误的卖出信号。
代码示例
以下是一个典型的双均线策略片段,展示了如何正确使用 'pre'(前复权):
def initialize(context):
g.security = '600570.SS'
set_universe(g.security)
def handle_data(context, data):
# 【重要】计算技术指标时,务必使用 'pre' (前复权)
# 如果使用 None (不复权),遇到分红拆股时,均线会断崖下跌导致误判
# 如果使用 'post' (后复权),均线价格会远高于当前股价,导致无法比较
hist = get_history(20, '1d', 'close', g.security, fq='pre')
if len(hist) < 20:
return
# 获取过去20天的收盘价数据
close_prices = hist['close']
# 计算均线
ma5 = close_prices[-5:].mean()
ma20 = close_prices[-20:].mean()
# 获取当前实时价格 (注意:data中的价格是不复权的,也就是真实盘面价格)
current_price = data[g.security]['close']
# 因为使用了前复权,ma5 和 ma20 的价格基准与 current_price 是一致的,可以直接比较
if ma5 > ma20:
log.info("5日均线大于20日均线,当前价: %.2f, MA5: %.2f" % (current_price, ma5))
# 交易逻辑...
总结
- 写策略、算指标(MA, MACD等):请用
fq='pre'。 - 算长期回报、回测净值分析:可用
fq='post'。 - 判断涨跌停、挂单具体价格:可用
fq=None。
Q&A
Q: 如果我在 get_history 中不传 fq 参数会怎样?
A: 根据 PTrade 文档,fq 参数的默认值是 None。这意味着如果你不指定,获取到的是不复权数据。如果你的策略依赖技术指标,一旦遇到股票除权除息,指标会出现剧烈波动,导致策略发出错误的交易信号。因此,建议显式地指定 fq='pre'。
Q: 为什么实盘交易中 data 里的价格是不复权的,但我却要用前复权的历史数据?
A: 前复权的原理就是“把历史价格调整到与当前价格可比的水平”。实盘中的 data 是当前的真实价格,而前复权恰恰是保持当前价格不变,去修改历史价格。因此,它们在数学上是处于同一个坐标系内的,可以直接进行比较(如 if current_price > ma_pre)。
Q: dypre(动态前复权)是什么?
A: dypre 是 PTrade 特有的一种复权方式,它在回测过程中,每天都以“当天的回测日期”为基准向前复权。这在模拟真实交易环境时非常有用,因为它避免了“未来函数”(即避免了在 2015 年回测时就已经知道了 2020 年的分红信息)。但在简单的策略编写中,使用 'pre' 通常已经足够满足需求。