问题描述
解决方案
在 QMT 量化交易平台中,dividend_type 参数用于控制获取行情数据时的复权方式。复权处理对于消除因分红、送股、配股等造成的股价“缺口”至关重要。
以下是关于 dividend_type 的详细参数说明及其对策略的具体影响。
1. dividend_type 参数填什么?
QMT 中有两个主要获取历史数据的接口,它们对 dividend_type 的参数要求不同,请根据你使用的函数选择:
A. 使用 ContextInfo.get_market_data_ex() (推荐接口)
该接口使用字符串来指定复权方式:
| 参数值 (String) | 含义 | 说明 |
|---|---|---|
'none' |
不复权 | 原始的交易所撮合价格,包含除权除息缺口。 |
'front' |
前复权 | (最常用) 以当前价格为基准,向下调整历史价格。保持最新价与实盘一致。 |
'back' |
后复权 | 以历史上市价为基准,向上调整当前价格。适合计算长期累计收益。 |
'follow' |
跟随主图 | (默认) 跟随当前策略运行界面(或回测设置)中主图的复权设置。 |
'front_ratio' |
等比前复权 | 相比普通前复权(等差),更能保持涨跌幅比例的一致性。 |
'back_ratio' |
等比后复权 | 相比普通后复权(等差),更能保持涨跌幅比例的一致性。 |
B. 使用 ContextInfo.get_history_data() (旧版接口)
该接口使用整数 (int) 来指定复权方式:
| 参数值 (Int) | 含义 |
|---|---|
0 |
不复权 (默认) |
1 |
前复权 |
2 |
后复权 |
3 |
等比前复权 |
4 |
等比后复权 |
2. 复权对策略有什么影响?
复权的核心目的是保持价格走势的连续性。如果不进行复权,股票在发生“高送转”或“分红”时,股价会突然大幅下跌(例如 10 送 10,股价会腰斩),这种非市场交易导致的下跌会对策略产生严重误导。
(1) 对技术指标策略的影响 (MA, MACD, RSI 等)
- 不复权的影响:如果股票发生除权(如股价从 20 元变成 10 元),均线系统会瞬间死叉,MACD 翻绿,RSI 暴跌。策略会误判为“暴跌”从而触发止损或卖出信号。
- 正确做法:必须使用前复权 (
front)。前复权修复了缺口,使得技术指标能真实反映趋势。
(2) 对价格触发类策略的影响 (如:价格 > 100 买入)
- 后复权的影响:后复权会将现在的价格根据历史分红不断向上调整,导致现在的“后复权价”可能远高于实际盘面价格(例如某股票现价 10 元,后复权价可能是 500 元)。如果策略逻辑包含具体的绝对价格判断(如
close > 20),使用后复权会导致逻辑失效。 - 正确做法:使用前复权 (
front)。前复权保证了当天的收盘价与投资者在交易软件上看到的现价一致,便于逻辑判断。
(3) 对回测收益计算的影响
- 不复权的影响:回测时如果在除权日持有股票,账户市值会突然缩水,导致回测收益率大幅低于真实水平。
- 正确做法:QMT 的回测引擎通常会自动处理分红派息的资金回补,但在编写策略逻辑获取历史数据计算信号时,依然建议使用前复权以保证信号生成的准确性。
3. 最佳实践代码示例
在绝大多数趋势跟踪、均线交叉或机器学习策略中,建议统一使用 前复权 (front)。
# -*- coding: gbk -*-
def init(ContextInfo):
# 设置股票池
ContextInfo.set_universe(['600519.SH'])
def handlebar(ContextInfo):
# 获取当前主图代码
stock_code = ContextInfo.stockcode
# 【推荐】使用 get_market_data_ex 获取前复权数据
# 这样计算出来的 MA 均线才是平滑的,不会受分红除权影响
data = ContextInfo.get_market_data_ex(
fields=['close'],
stock_code=[stock_code],
period='1d',
count=100,
dividend_type='front' # 显式指定前复权
)
if stock_code in data:
df = data[stock_code]
# 计算均线
ma5 = df['close'].rolling(5).mean().iloc[-1]
ma20 = df['close'].rolling(20).mean().iloc[-1]
print(f"代码: {stock_code}, 最新价: {df['close'].iloc[-1]}, MA5: {ma5}, MA20: {ma20}")
Q&A
Q: 为什么实盘交易时有时候用“不复权”?
A: 在实盘交易的瞬间,交易所推送的 Tick 数据(分笔数据)是不复权的真实成交价。如果你的策略是基于盘口挂单价格(Order Book)或高频撮合逻辑,必须使用不复权数据。但在计算历史指标(如过去 5 天的均线)作为参考时,历史部分仍需复权。
Q: front 和 front_ratio (等比前复权) 有什么区别?
A: 普通前复权通常是基于价格差额(等差)进行调整,可能会在极长的时间跨度下改变涨跌幅比例(例如 10 年前涨停板是 10%,复权后算出来可能不是 10%)。front_ratio(等比)通过乘法因子调整,能严格保持历史 K 线的涨跌幅百分比不变。对于对收益率敏感的模型(如机器学习训练),推荐使用 front_ratio。
Q: 如果我不填 dividend_type 会怎样?
A: get_market_data_ex 默认是 'follow',即取决于你在 QMT 界面上右键点击 K 线图时选择的复权方式。为了防止策略在不同电脑或不同设置下表现不一致,强烈建议在代码中显式指定(如 'front')。