🚀 AI 一键生成 joinquant 策略代码

JoinQuant 平台构建 UOS 终极波动指标交易系统

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

问题描述

怎么编写 UOS 终极波动指标的交易策略?

解决方案

编写 UOS(Ultimate Oscillator,终极波动指标)交易策略的核心在于利用该指标综合短、中、长三个周期的特性,来捕捉市场的超买和超卖区域。

策略逻辑说明

UOS 指标由拉里·威廉姆斯(Larry Williams)开发,旨在解决单一周期震荡指标容易产生虚假信号的问题。

1. UOS 计算原理(本策略使用 TA-Lib 库计算):

  • 通常使用三个周期:7日、14日、28日。
  • 通过计算购买压力(Buying Pressure)与真实波幅(True Range)的比率,并加权平均得出。
  • 数值范围在 0 到 100 之间,50 为中轴。

2. 交易信号设计:
本策略采用经典的超买超卖反转逻辑:

  • 买入信号(做多): 当 UOS 指标低于 35(视为超卖区域)时,认为股价可能反弹,全仓买入。
  • 卖出信号(平仓): 当 UOS 指标高于 65(视为超买区域)时,认为股价可能回调,清仓卖出。

3. 资金管理:

  • 全仓买入,清仓卖出(仅作为示例,实盘建议配合风控模型)。

策略代码实现

以下是基于聚宽(JoinQuant)平台的完整策略代码。代码中使用了 talib 库来高效计算 UOS 指标。

# -*- coding: utf-8 -*-
import jqdata
import talib
import numpy as np

def initialize(context):
    """
    初始化函数,设定基准、手续费、滑点及全局变量
    """
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    
    # 设定股票类每笔交易时的手续费
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 定义要操作的股票,这里以平安银行为例
    g.security = '000001.XSHE'
    
    # UOS指标的三个周期参数
    g.p1 = 7
    g.p2 = 14
    g.p3 = 28
    
    # 设定超买超卖阈值
    g.buy_threshold = 35  # 低于此值视为超卖,买入
    g.sell_threshold = 65 # 高于此值视为超买,卖出
    
    # 每天开盘时运行
    run_daily(market_open, time='09:30')

def market_open(context):
    """
    每日交易逻辑
    """
    security = g.security
    
    # 获取计算UOS所需的历史数据
    # UOS最大周期是28,我们需要比28更多的数据来确保计算稳定,这里取60天
    # 包含 high, low, close
    history_data = attribute_history(security, 60, '1d', ['high', 'low', 'close'])
    
    # 确保数据长度足够
    if len(history_data) < g.p3 + 1:
        return
        
    # 将数据转换为numpy数组,供talib使用
    high_prices = history_data['high'].values
    low_prices = history_data['low'].values
    close_prices = history_data['close'].values
    
    # 使用 talib 计算 UOS 指标
    # 注意:talib.ULTOSC 返回的是一个数组,对应每一天的UOS值
    uos_values = talib.ULTOSC(high_prices, low_prices, close_prices, 
                              timeperiod1=g.p1, 
                              timeperiod2=g.p2, 
                              timeperiod3=g.p3)
    
    # 获取最新的 UOS 值(数组的最后一个元素)
    current_uos = uos_values[-1]
    
    # 检查是否计算出有效值(剔除NaN)
    if np.isnan(current_uos):
        return
        
    # 获取当前账户资金和持仓情况
    cash = context.portfolio.available_cash
    position = context.portfolio.positions[security]
    
    # 记录 UOS 值到图表,方便回测查看
    record(UOS=current_uos)
    
    # --- 交易逻辑 ---
    
    # 1. 买入逻辑:UOS 小于买入阈值 (超卖),且当前无持仓
    if current_uos < g.buy_threshold and position.closeable_amount == 0:
        # 全仓买入
        order_value(security, cash)
        log.info("买入信号触发:UOS值为 %.2f,低于阈值 %d,全仓买入 %s" % (current_uos, g.buy_threshold, security))
        
    # 2. 卖出逻辑:UOS 大于卖出阈值 (超买),且有持仓
    elif current_uos > g.sell_threshold and position.closeable_amount > 0:
        # 清仓卖出
        order_target(security, 0)
        log.info("卖出信号触发:UOS值为 %.2f,高于阈值 %d,清仓卖出 %s" % (current_uos, g.sell_threshold, security))

def after_trading_end(context):
    """
    盘后处理(可选)
    """
    pass

常见问题 (Q&A)

Q1: 为什么使用 talib.ULTOSC 而不是自己写公式计算?
A: talib 是底层的 C 语言库,计算速度极快且经过了广泛验证,准确性高。自己编写公式容易在处理 NaN 值或边界条件(如除数为0)时出错。在量化交易中,推荐优先使用成熟的库。

Q2: 阈值 35 和 65 是固定的吗?
A: 不是。拉里·威廉姆斯最初建议的买入标准是 UOS < 30,卖出标准是 UOS > 70。但在 A 股市场或特定个股上,波动特性可能不同。您可以根据回测结果调整 g.buy_thresholdg.sell_threshold(例如调整为 30/70 或 40/60)以获得更优的收益。

Q3: 这个策略适合什么类型的行情?
A: UOS 是震荡指标,因此该策略最适合震荡市(股价在箱体上下波动)。在单边的大牛市或大熊市中,震荡指标可能会出现“钝化”现象(例如牛市中 UOS 长期高于 65,导致过早卖出踏空;熊市中长期低于 35,导致过早抄底被套)。建议结合均线(MA)等趋势指标进行过滤。

Q4: 如何对多只股票运行此策略?
A: 您可以将 g.security 修改为一个列表(例如 get_index_stocks('000300.XSHG')),然后在 market_open 函数中使用 for 循环遍历每只股票,分别计算 UOS 并独立进行买卖判断。同时需要调整下单资金分配逻辑(例如每只股票分配总资金的 1/N)。