问题描述
威廉指标定义
def WR(price, N=21, N1=42): #W&R 威廉指标
CLOSE = price['close']
HIGH = price['high']
LOW = price['low']
WR = (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) * 100
WR1 = (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) * 100
return RD(list(WR)), RD(list(WR1))
使用
prices_day = get_bars(stock, 300, '1d', fields=['open','high','low','close'],fq_ref_date=None, df=True)
# 日线WR指标
WR1_day, WR2_day = WR(prices_day)
结果
使用 600475.XSHG 跑结果发现:
2023-06-19 09:00:00 - INFO - WR1_day[-1]:74.272
2023-06-19 09:00:00 - INFO - WR2_day[-1]:76.233
2023-06-19 09:00:00 - INFO - WR1_day[-2]:88.35
2023-06-19 09:00:00 - INFO - WR2_day[-2]:89.238
同花顺的值
WR1_day[-1]:69.01
WR2_day[-1]:60.81
WR1_day[-2]:85.96
WR2_day[-2]:73.87
解决方案
您好!在量化平台计算技术指标时,与同花顺等传统行情软件出现数值不一致是非常常见的现象。根据您提供的代码和数据,导致WR(威廉指标)不一致的核心原因主要有以下两点:
1. 数据复权方式不同(最核心原因)
在您的代码中,获取数据使用的是:
prices_day = get_bars(stock, 300, '1d', fields=['open','high','low','close'], fq_ref_date=None, df=True)
这里的关键在于 fq_ref_date=None,这意味着您获取的是不复权(真实价格)数据。而同花顺、通达信等行情软件在K线图上计算技术指标时,默认使用的是前复权数据。
如果该股票在您计算的周期内(过去42天内)发生过分红、送转等除权除息事件,不复权数据的最高价(HIGH)和最低价(LOW)会产生巨大的断层,从而导致计算出的 HHV 和 LLV 与同花顺完全不同,最终 WR 指标差异巨大。
解决方法:将获取数据的方式改为前复权。
2. 指标参数设置不同
您代码中使用的参数是 N=21, N1=42。请务必打开同花顺软件,在K线图上右键点击WR指标,选择“修改指标参数”,确认同花顺当前使用的参数是否也是 21 和 42。同花顺默认的 WR 参数通常是 N=10, N1=6 或者 N=14 等。如果参数不同,计算结果必然不同。
修正后的代码示例
为了与同花顺保持一致,建议使用前复权数据。在 JoinQuant 中,可以通过设置 fq_ref_date 为当前日期来实现前复权,或者直接使用 get_price 函数。
import pandas as pd
import datetime
# 假设 HHV 和 LLV 的实现如下(使用 pandas 的 rolling 函数)
def HHV(series, n):
return series.rolling(window=n).max()
def LLV(series, n):
return series.rolling(window=n).min()
def WR(price, N=21, N1=42):
# W&R 威廉指标
CLOSE = price['close']
HIGH = price['high']
LOW = price['low']
# 注意:威廉指标的标准公式有时不乘100,或者用100减去该值,请确保与同花顺公式完全一致
WR = (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) * 100
WR1 = (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) * 100
# 剔除前面的 NaN 值
return round(WR, 2).tolist(), round(WR1, 2).tolist()
# 获取前复权数据
stock = '600475.XSHG'
# 方法一:使用 get_bars 并设置 fq_ref_date 为今天(即前复权)
now_date = datetime.datetime.now().date()
prices_day = get_bars(stock, 300, '1d', fields=['open','high','low','close'], fq_ref_date=now_date, df=True)
# 方法二:使用 get_price 获取前复权数据(推荐)
# prices_day = get_price(stock, count=300, end_date='2023-06-19', frequency='daily', fields=['open','high','low','close'], fq='pre')
# 计算日线WR指标
WR1_day, WR2_day = WR(prices_day, N=21, N1=42) # 请确保这里的 N 和 N1 与同花顺一致
print(f"WR1_day[-1]: {WR1_day[-1]}")
print(f"WR2_day[-1]: {WR2_day[-1]}")
总结排查步骤:
- 统一复权方式:量化平台默认可能不复权,行情软件默认前复权。计算技术指标一律建议使用前复权 (
fq='pre')。 - 统一参数:核对 N 和 N1 的周期参数。
- 统一公式细节:威廉指标有几种变体,有的是
(HHV - CLOSE) / (HHV - LLV) * 100,有的是(CLOSE - LLV) / (HHV - LLV) * 100,请查看同花顺的公式源码(Ctrl+F打开公式管理器查看)确保分子分母逻辑一致。 - 数据截面:确保 JoinQuant 获取数据的截止时间与同花顺看盘的时间完全一致(例如是否包含了当天的最新未收盘数据)。