🚀 AI 一键生成 ptrade 策略代码

PTrade 震荡策略:威廉指标(Williams %R)超买超卖实战

ptrade | 发布时间: 2025/12/30
以下内容由 EasyQuant 生成。

问题描述

如何编写基于威廉指标 W%R 的超买超卖交易策略?

解决方案

威廉指标 (Williams %R) 超买超卖交易策略

威廉指标(Williams %R,简称 W%R)是一种动量指标,用于衡量市场的超买或超卖状态。它的取值范围在 0 到 -100 之间。

策略原理

  1. 指标计算
    $$ W%R = \frac{H_n - C}{H_n - L_n} \times -100 $$

    • $C$:当前收盘价
    • $H_n$:过去 $N$ 个周期内的最高价
    • $L_n$:过去 $N$ 个周期内的最低价
    • $N$:通常取 14 或 28。
  2. 交易逻辑

    • 超卖区间(买入信号):当 W%R 低于 -80 时,表示市场处于超卖状态,价格可能反弹,执行买入。
    • 超买区间(卖出信号):当 W%R 高于 -20 时,表示市场处于超买状态,价格可能回调,执行卖出。

PTrade 策略代码实现

由于 PTrade API 文档中未直接提供 get_WR 函数,我们需要利用 get_history 获取高、低、收数据后手动计算。

以下是完整的策略代码:

import numpy as np

def initialize(context):
    """
    策略初始化函数
    """
    # 1. 设置股票池 (这里以恒生电子为例,也可以设置为指数成分股)
    g.security_list = ['600570.SS']
    set_universe(g.security_list)
    
    # 2. 设置威廉指标参数
    g.N = 14  # 计算周期
    g.buy_threshold = -80  # 超卖阈值 (买入)
    g.sell_threshold = -20 # 超买阈值 (卖出)
    
    # 3. 设置回测费用 (佣金万三,印花税千一)
    set_commission(commission_ratio=0.0003, min_commission=5.0, type='STOCK')
    # 设置滑点
    set_slippage(slippage=0.002)

def handle_data(context, data):
    """
    按周期运行的策略逻辑 (日线级别)
    """
    # 遍历股票池中的每一只股票
    for stock in g.security_list:
        # 过滤停牌股票
        if data[stock].is_open == 0:
            continue
            
        # 1. 获取历史数据
        # 我们需要过去 N 天的数据来计算最高价和最低价
        # include=True 表示包含当前这根K线的数据 (日线回测时为当日收盘数据)
        hist = get_history(g.N, '1d', ['high', 'low', 'close'], stock, fq='pre', include=True)
        
        # 如果数据长度不足 N 天,跳过计算
        if len(hist) < g.N:
            continue
            
        # 2. 提取数据
        highs = hist['high'].values
        lows = hist['low'].values
        close = hist['close'].values[-1] # 当前最新收盘价
        
        # 3. 计算 N 日内的最高价和最低价
        highest_high = np.max(highs)
        lowest_low = np.min(lows)
        
        # 4. 计算威廉指标 W%R
        # 防止分母为0的情况 (即最高价等于最低价)
        if highest_high == lowest_low:
            wr = -50 # 给予一个中性值
        else:
            wr = (highest_high - close) / (highest_high - lowest_low) * -100
        
        # 打印日志方便调试
        # log.info("股票: %s, W%%R: %.2f" % (stock, wr))
        
        # 5. 获取当前持仓
        position = context.portfolio.positions[stock].amount
        
        # 6. 交易逻辑
        # 信号:W%R < -80 (超卖,买入)
        if wr < g.buy_threshold:
            if position == 0:
                # 全仓买入 (这里简单示例使用所有现金买入一只,多只股票需分配资金)
                cash = context.portfolio.cash
                if cash > 0:
                    order_value(stock, cash)
                    log.info("买入信号触发: %s, W%%R: %.2f, 价格: %.2f" % (stock, wr, close))
        
        # 信号:W%R > -20 (超买,卖出)
        elif wr > g.sell_threshold:
            if position > 0:
                # 清仓卖出
                order_target(stock, 0)
                log.info("卖出信号触发: %s, W%%R: %.2f, 价格: %.2f" % (stock, wr, close))

代码解析

  1. 数据获取 (get_history):

    • 我们使用 get_history(g.N, ...) 获取过去 14 天的最高价、最低价和收盘价。
    • 参数 include=True 非常重要,确保计算时包含当天的最新价格,这样指标才是实时的。
  2. 指标计算:

    • 利用 numpy 库的 maxmin 函数快速找出周期内的极值。
    • 严格按照 W%R 公式进行计算。增加了 highest_high == lowest_low 的判断以防止除以零错误(虽然在日线级别很少见,但在分钟级别或极端行情下可能发生)。
  3. 交易执行:

    • 买入: 当 wr < -80 且当前无持仓时,使用 order_value 用当前可用资金买入。
    • 卖出: 当 wr > -20 且当前有持仓时,使用 order_target(stock, 0) 将持仓调整为 0,即清仓。

优化建议

该策略是一个基础的均值回归策略,在实际应用中可以考虑以下优化方向:

  1. 结合趋势指标:W%R 在强趋势行情中容易出现“钝化”(例如长期停留在超买区但价格继续上涨)。可以结合移动平均线(MA)过滤信号,仅在上升趋势中执行超卖买入。
  2. 资金管理:代码中使用了全仓买入,建议根据股票池大小将资金等分(例如 cash / len(g.security_list))。
  3. 止损设置:虽然是超卖买入,但价格可能继续下跌,建议加入固定比例止损(如亏损 5% 止损)。

Q&A

Q: 为什么不直接调用 get_WR 接口?
A: PTrade 的官方 API 文档中并未提供直接计算威廉指标的接口(如 get_WR)。虽然部分第三方库(如 TA-Lib)可能支持,但为了保证策略在 PTrade 所有环境(回测、实盘)下的兼容性和稳定性,使用 numpy 基于基础行情数据手动计算是最可靠的方法。

Q: 这个策略适合什么频率?
A: 上述代码默认基于日线(handle_data 每日运行一次)。如果需要运行在分钟级别,只需在回测设置中将频率改为“分钟”,并将 get_history 的频率参数从 '1d' 改为 '1m' 即可。

Q: 如何避免 W%R 在 -100 或 0 附近频繁波动导致的频繁交易?
A: 可以修改开仓逻辑,不单纯判断“低于 -80”,而是判断“从下方上穿 -80”(即 昨日W%R < -80今日W%R > -80),这样可以确认反弹趋势确立后再入场。