Python股票量化教程:手把手实现WR威廉指标
前言
WR(Williams %R,威廉指标)是短线交易常用的超买超卖指标,擅长捕捉股价短期高低拐点。WR和RSI原理相近,但WR灵敏度更高,经常提前发出反转信号,适合震荡行情抄底、逃顶。
很多同学自己写WR时容易踩坑:分子分母写反、忘记乘以负号,最终计算结果和通达信、东方财富不一致。本文严格遵循通达信原版公式,使用Pandas原生实现,不依赖TA-Lib,附带绘图展示、自动交易信号识别,全部代码可直接复制运行,能够接入量化回测系统。
⚠️ 重要声明:本文仅作为Python量化编程学习,不构成任何投资建议。
一、WR指标原理与通达信计算公式
指标简介
WR威廉指标,利用一段时间内最高价、最低价与当前收盘价的相对位置,判断股价是否处于短期极端高位/低位。
A股软件默认双周期参数:WR1=10,WR2=20
通达信原版公式
HH:=HHV(HIGH,N);
LL:=LLV(LOW,N);
WR:=(HH-CLOSE)/(HH-LL)*100;
WR指标 = -WR
数学公式:
WR=−HHN−CloseHHN−LLN×100WR = -\frac{HH_N - Close}{HH_N - LL_N} \times 100WR=−HHN−LLNHHN−Close×100
- HHNHH_NHHN:N周期内最高价
- LLNLL_NLLN:N周期内最低价
- CloseCloseClose:当日收盘价
重点提醒:最终结果需要取负数!区间范围 [-100, 0]
WR指标基础交易规则
- 超买区(0 ~ -20)
股价短期上涨过多,多头动能衰竭,有回调风险,止盈、减仓信号。 - 超卖区(-80 ~ -100)
短期持续下跌,空头释放充分,反弹概率加大,关注低吸机会。 - 中性区间(-20 ~ -80)
多空相对均衡,没有明确超买超卖信号,观望为主。 - 双周期共振
WR1、WR2同时进入超卖区,底部信号可靠性更高;同时进入超买区,回落风险加大。
二、环境依赖
pip install pandas numpy matplotlib
三、Python实现WR指标计算
3.1 封装通用WR计算函数
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def calc_wr(df, high_col="high", low_col="low", close_col="close", n1=10, n2=20):
"""
复刻通达信 WR威廉指标
:param df: K线DataFrame,必须包含 high low close
:param high_col: 最高价列名
:param low_col: 最低价列名
:param close_col: 收盘价列名
:param n1: WR1短期周期 默认10
:param n2: WR2长期周期 默认20
:return: 添加 WR1 WR2 后的DataFrame
"""
data = df.copy()
# N周期最高价、最低价
hh_n1 = data[high_col].rolling(window=n1).max()
ll_n1 = data[low_col].rolling(window=n1).min()
hh_n2 = data[high_col].rolling(window=n2).max()
ll_n2 = data[low_col].rolling(window=n2).min()
# 防止除零(横盘,最高价=最低价)
# WR1
denom1 = hh_n1 - ll_n1
wr1_raw = np.where(denom1 == 0, 0, (hh_n1 - data[close_col]) / denom1 * 100)
data["WR1"] = -wr1_raw
# WR2
denom2 = hh_n2 - ll_n2
wr2_raw = np.where(denom2 == 0, 0, (hh_n2 - data[close_col]) / denom2 * 100)
data["WR2"] = -wr2_raw
return data
3.2 模拟行情数据测试
if __name__ == "__main__":
np.random.seed(666)
base_price = 12
data_list = []
for i in range(180):
change = np.random.normal(0, 0.22)
close = round(base_price + change, 2)
high = round(close + abs(np.random.normal(0, 0.1)), 2)
low = round(close - abs(np.random.normal(0, 0.1)), 2)
data_list.append({"high": high, "low": low, "close": close})
base_price = close
df = pd.DataFrame(data_list)
df["date"] = pd.date_range(start="2026-01-01", periods=180, freq="D")
# 计算WR
df = calc_wr(df)
print(df[["date", "close", "WR1", "WR2"]].tail(15))
前N-1行数据会是NaN,属于正常现象,滚动窗口需要足够K线数量。
四、WR指标可视化绘图
上下双图:上图股价,下图WR曲线,同时画出-20、-80两条分界线,贴近行情软件样式:
def plot_wr_chart(df):
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14,8), sharex=True, gridspec_kw={"height_ratios":[2,1]})
# 上图:收盘价走势
ax1.plot(df["date"], df["close"], c="#f5222d", linewidth=1.6, label="收盘价")
ax1.set_title("股价走势 + WR威廉指标", fontsize=14)
ax1.set_ylabel("价格")
ax1.legend()
ax1.grid(alpha=0.3)
# 下图 WR曲线
ax2.plot(df["date"], df["WR1"], c="#1890ff", linewidth=1.3, label="WR1(10)")
ax2.plot(df["date"], df["WR2"], c="#fa8c16", linewidth=1.3, label="WR2(20)")
# 超买超卖分界线
ax2.axhline(y=-20, c="red", linestyle="--", alpha=0.6)
ax2.axhline(y=-80, c="green", linestyle="--", alpha=0.6)
ax2.set_ylabel("WR")
ax2.legend()
ax2.grid(alpha=0.3)
plt.tight_layout()
plt.show()
plot_wr_chart(df)
五、自动识别WR交易信号
根据超买超卖区间生成信号,方便策略回测:
def generate_wr_signal(df):
data = df.copy()
signal_list = []
for _, row in data.iterrows():
wr1 = row["WR1"]
wr2 = row["WR2"]
if pd.isna(wr1) or pd.isna(wr2):
signal_list.append(None)
continue
# 双周期同时进入超卖区:低吸信号
if wr1 <= -80 and wr2 <= -80:
signal_list.append("buy")
# 双周期同时进入超买区:卖出信号
elif wr1 >= -20 and wr2 >= -20:
signal_list.append("sell")
else:
signal_list.append(None)
data["wr_signal"] = signal_list
return data
df = generate_wr_signal(df)
buy_signal = df[df["wr_signal"] == "buy"]
sell_signal = df[df["wr_signal"] == "sell"]
print("====WR超卖低吸信号====")
print(buy_signal[["date","close","WR1","WR2"]])
print("\n====WR超买卖出信号====")
print(sell_signal[["date","close","WR1","WR2"]])
六、开发高频踩坑总结
1. 分子分母写反(最常见错误)
错误写法:(Close - LL)/(HH-LL)
正确写法:(HH - Close)/(HH-LL)
顺序颠倒会直接导致指标走势完全反向。
2. 忘记乘以负号
部分国外资料WR范围是0~100,而国内通达信统一 [-100,0],计算完成后必须取负,否则区间和信号全部相反。
3. 缺少除零保护
长期横盘个股,周期内最高价等于最低价 HH-LL=0,直接除法会触发inf无穷值,代码中需要增加判断规避。
4. WR不适合单边大趋势
持续牛市,WR会长时间处于超买区间;持续熊市,长期处于超卖区间。单纯依靠WR极易出现持续假信号,建议搭配趋势指标MACD、均线组合使用。
5. 忽略周期参数
短线交易用10周期,中长线可调整20、30周期,参数越大指标越平滑、灵敏度越低。
七、拓展方向
- 接入Akshare / Tushare获取A股真实日线、分钟K数据;
- 增加WR背离检测(顶背离、底背离);
- WR+MACD共振策略开发与历史回测;
- 封装为API接口,供前端量化页面实时计算指标;
- 结合仓位管理规则构建完整交易策略。
八、总结
- WR威廉指标核心是利用周期高低点相对位置判断超买超卖;复刻通达信重点注意分子顺序 + 末尾取负数;
- 默认双周期WR1(10)、WR2(20)共振使用,信号稳定性高于单周期;
- WR优势是反应灵敏、提前捕捉拐点,短板是单边行情容易持续失真;
- 量化开发优先手写指标,摆脱第三方库黑盒,便于自定义修改、问题排查与策略调试。
更多推荐


所有评论(0)