Warning: file_exists(): open_basedir restriction in effect. File(/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-content/db.php) is not within the allowed path(s): (/www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/:/tmp/:/proc/:/var/log/nginx/:/www/wwwroot/com.xiximiao.oa/com.cmstop/public/:/www/wwwroot/com.xiximiao.oa/com.cmstop/vendor/:/www/wwwroot/com.xiximiao.oa/com.cmstop/ppk/) in /www/wwwroot/com.xiximiao.oa/com.cmstop/public/www/wp-includes/load.php on line 707
2331 ETF核心资产轮动动量因子加RSRS择时每日策略 量化交易策略代码 » 轻知量化 QMT、PTrade、聚宽策略分享交流平台

2331 ETF核心资产轮动动量因子加RSRS择时每日策略 量化交易策略代码

策略名称:动量因子加RSRS择时和ETF轮动策略

策略概述:

该策略结合了动量因子和RSRS择时模型,通过ETF轮动的方式实现资产配置优化。策略的核心逻辑是通过动量因子筛选出表现优异的ETF,并结合RSRS择时模型判断市场趋势,动态调整持仓,以实现收益最大化。


策略核心逻辑:

  1. 动量因子选股

    • 计算ETF的年化收益率和判定系数(R²),作为动量评分。

    • 根据动量评分对ETF进行排序,选择评分最高的ETF作为投资标的。

  2. RSRS择时模型

    • 使用OLS回归分析计算ETF的最高价和最低价之间的斜率(RSRS斜率)。

    • 通过计算RSRS斜率的Z分数,判断市场趋势(买入、卖出或持有信号)。

    • 结合均线比较(MA)进一步确认趋势信号。

  3. ETF轮动

    • 根据动量因子和RSRS择时信号,动态调整持仓。

    • 每次调仓时,卖出当前持仓的ETF,买入动量评分最高的ETF。

  4. 风险控制

    • 当RSRS择时模型发出卖出信号时,清空所有持仓,避免市场下跌风险。


策略特点:

  • 动量驱动:通过动量因子筛选表现优异的ETF,捕捉市场趋势。

  • 择时优化:结合RSRS择时模型,动态判断市场趋势,避免逆势操作。

  • ETF轮动:通过轮动方式优化资产配置,分散风险。

  • 自动化交易:策略实现全自动化交易,减少人为干预。


策略参数:

参数名称 参数值 说明
动量天数 25 计算动量评分的周期
RSRS计算周期(N) 18 计算RSRS斜率的周期
RSRS历史周期(M) 600 计算RSRS斜率Z分数的历史周期
均线计算周期 20 计算均线的周期
均线比较周期 3 比较均线的前后周期差
RSRS阈值 0.7 RSRS Z分数的阈值,用于判断买卖信号
最大持仓数 1 每次调仓时持有的ETF数量

策略流程:

  1. 初始化

    • 设置基准指数(沪深300)。

    • 定义ETF池(黄金ETF、纳指ETF、创业板ETF、上证180ETF)。

    • 初始化动量因子和RSRS择时模型的参数。

  2. 每日调仓

    • 计算ETF的动量评分,选择评分最高的ETF。

    • 根据RSRS择时模型判断市场趋势(买入、卖出或持有)。

    • 如果信号为买入且持仓与目标不一致,则调仓;如果信号为卖出,则清仓。

  3. 动量评分计算

    • 使用对数收益率和线性回归计算ETF的年化收益率和判定系数。

    • 动量评分 = 年化收益率 × 判定系数。

  4. RSRS择时模型

    • 使用OLS回归计算最高价和最低价的斜率。

    • 计算斜率的Z分数,结合均线比较生成买卖信号。

  5. 调仓操作

    • 卖出当前持仓的ETF。

    • 买入动量评分最高的ETF。



from jqdata import *    # 从jqdata模块导入所有内容
import numpy as np      # 导入numpy库

def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 用真实价格交易
    set_option('use_real_price', True)
    # 将滑点设置为0
    set_slippage(FixedSlippage(0.004))    
    # 设置交易成本万分之五
    set_order_cost(OrderCost(open_tax=0, close_tax=0, open_commission=0.0005, close_commission=0.0005, close_today_commission=0, min_commission=5),
                   type='fund')
    log.set_level('order', 'error')       # 过滤order中低于error级别的日志
    # 初始化全局变量g.index_pool,用于存放策略中关注的指数或ETF
    g.index_pool = [
        '518880.XSHG', #黄金ETF(大宗商品)'518880.XSHG'
        '513100.XSHG', #纳指100(海外资产)
        '159915.XSHE', #创业板100(成长股,科技股,题材性,中小盘)
        # '515080.XSHG', #红利ETF(价值股,蓝筹股,防御性,中大盘) '515080.XSHG'
        # '159928.XSHE', # 中证消费ETF
        '510180.XSHG',#上证180(价值股,蓝筹股,中大盘)
        # '159981.XSHE'#能源化工期货
    ]
    # 初始化全局变量,设置最大持仓数为1
    g.stock_num = 1
    # 设置动量天数为25天,用于计算股票的动量
    g.momentum_day = 25
    # 设置股票代码为沪深300指数
    g.stock = '000300.XSHG'
    # 设置N周期为18天,用于计算RS指标
    g.N = 18
    # 设置M周期为600天,用于计算RS指标
    g.M = 600
    # 设置均值计算天数为20天
    g.mean_day = 20 
    g.mean_diff_day = 3     # 设置比较均线时的前后天数差为3天
    g.score_threshold = 0.7 # 设置RS标准分指标阈值为0.7
    g.slope_series = initial_slope_series()[:-1]  # 初始化斜率序列,这里调用initial_slope_series函数并去掉序列中的第一个元素
     # 设置交易时间,每周任意时间执行一次
    # run_weekly(trade, weekday=3, time='9:45',reference_security='000300.XSHG')
    run_daily(trade,time='9:45')   # 设置交易时间,这里设置为每个交易日的9:45执行trade函数
  
# 定义 trade 函数,用于执行策略的交易逻辑
def trade(context):
    # 获取当前持仓的股票集合
    stock_hold = set(context.portfolio.positions.keys())
    # 调用 get_stock_pool 函数获取策略选定的股票池
    stock_pool = get_stock_pool()
    # 设置要持有的股票数量,不超过预设的最大持仓数 g.stock_num,也不超过股票池的大小
    g.stock_number = g.stock_num if (len(stock_pool) > g.stock_num) else len(stock_pool)
    # print(g.stock_number)
    # 选择股票池中的前 g.stock_num 只股票作为最终要买入的股票集合
    set_stock_pool=set(stock_pool[:g.stock_num])
    print(f'持仓股票{stock_hold}')  # 打印当前持仓的股票集合
    # print(f'所有要买入的股票{stock_pool}')
    print(f'最后要买入股票{set_stock_pool}')
    signal = get_signal()      # 获取交易信号
    print(signal)       # 打印交易信号
    
    # 如果有符合买入条件的股票池,并且当前交易信号不是卖出信号
    if stock_pool and signal != "SELL":
        # 如果当前持仓的股票集合与要买入的股票集合相同,且非空,不进行调仓
        if stock_hold == set_stock_pool and len(set_stock_pool) != 0:
            print("当前持仓和需买入集合一致,不进行调仓")
        else:
            # 否则,调用 change_position 函数调整持仓
            change_position(context, set_stock_pool)
    else:
        # 如果交易信号是卖出信号
        if signal == "SELL":
            print("RSRS择时模型发出清仓信号!")
        # 卖出当前持仓的所有股票
        for stock in stock_hold:
            # 将每只股票的目标持仓量设置为0,即全部卖出
            order_target_value(stock, 0)
    log.info('美好的一天结束')
    log.info('##############################################################')

关键函数解锁后查看:

# 定义 change_position 函数,用于调整持仓
def change_position(context, target_list):
    # 获取当前持仓列表
    hold_list = list(context.portfolio.positions)
    # 卖出当前持仓的所有股票
    for etf in hold_list:
        order_target_value(etf, 0)  # 将持仓量调整为0,即全部卖出
        print('卖出' + str(etf))
        
    # 如果目标股票数量大于0,则进行买入操作
    if g.stock_number > 0:
        # 计算每只股票的买入金额
        value = context.portfolio.available_cash / g.stock_number
        # 遍历目标股票列表,买入每只股票
        for etf in target_list:
            # 如果该股票不在当前持仓中,则买入
            if context.portfolio.positions[etf].total_amount == 0:
                order_target_value(etf, value)  # 将目标金额调整为value
                print('买入' + str(etf))

# 定义 get_signal 函数,用于产生交易信号
def get_signal():
    ''' 产生交易信号
    Returns:
        str: "BUY" or "SELL" or "KEEP"
    '''
    # 获取过去 g.mean_day + g.mean_diff_day 天的收盘价数据
    close_data = attribute_history(g.stock, g.mean_day + g.mean_diff_day, '1d', ['close'])
    # 计算今天及之前 g.mean_diff_day 天的收盘价均值
    today_MA = close_data.close[g.mean_diff_day:].mean() 
    # 计算之前 g.mean_day 天的收盘价均值
    before_MA = close_data.close[:-g.mean_diff_day].mean()
    # 获取过去 g.N 天的最高价和最低价数据
    data = attribute_history(g.stock, g.N, '1d', ['high', 'low'])
    # 调用 get_ols 函数进行 OLS 回归分析,得到截距、斜率和判定系数
    intercept, slope, r2 = get_ols(data.low, data.high)
    # 将新计算的斜率添加到 g.slope_series 列表中
    g.slope_series.append(slope)
    # 计算 RS/RS 指标的 z 分数,并乘以判定系数 r2
    rsrs_score = get_zscore(g.slope_series[-g.M:]) * r2
    # 根据 RS/RS 指标的 z 分数和均线比较结果产生交易信号
    if rsrs_score > g.score_threshold and today_MA > before_MA:
        return "BUY"
    elif rsrs_score < -g.score_threshold and today_MA < before_MA:
        return "SELL"
    else:
        return "KEEP"

# 定义 get_ols 函数,用于对输入的自变量和因变量建立 OLS 回归模型
def get_ols(x, y):
    ''' 对输入的自变量和因变量建立OLS回归模型
    Args:
        x (series of x): 每日最低价
        y (series of y): 每日最高价
    Returns:
        tuple: (截距,斜率,判定系数)
    '''
    # 使用 numpy 的 polyfit 函数进行一次线性回归,得到斜率和截距
    slope, intercept = np.polyfit(x, y, 1)
    # 计算判定系数 R^2
    r2 = 1 - (sum((y - (slope * x + intercept))**2) / ((len(y) - 1) * np.var(y, ddof=1)))
    # 返回截距、斜率和判定系数
    return (intercept, slope, r2)

# 定义 initial_slope_series 函数,用于初始化前 M 日内的斜率时间序列
def initial_slope_series():
    ''' 初始化前M日内的斜率时间序列
    Returns:
        list of slope (float)
    '''
    # 获取过去 g.N + g.M 天的最高价和最低价数据
    data = attribute_history(g.stock, g.N + g.M, '1d', ['high', 'low'])
    # 使用列表推导式计算序列中每 g.N 天的斜率
    # 对于序列中的每个 i,计算从 i 到 i+g.N 的最高价和最低价的 OLS 回归斜率
    return [get_ols(data.low[i:i+g.N], data.high[i:i+g.N])[1] for i in range(g.M)]

# 定义 get_zscore 函数,用于通过斜率序列计算标准分
def get_zscore(slope_series):
    ''' 通过斜率序列计算标准分
    Returns:
        float
    '''
    # 计算斜率序列的均值
    mean = np.mean(slope_series)
    # 计算斜率序列的标准差
    std = np.std(slope_series)
    # 计算最后一个斜率与序列均值的差,然后除以标准差,得到标准分
    return (slope_series[-1] - mean) / std

策略风险:

  1. 市场风险

    • 如果市场整体下跌,动量因子可能失效,导致策略表现不佳。

  2. 择时风险

    • RSRS择时模型的信号可能滞后或误判,导致错失机会或错误止损。

  3. 流动性风险

    • ETF的流动性不足可能导致买卖价差较大,影响策略收益。

  4. 参数敏感性

    • 策略对动量天数、RSRS阈值等参数较为敏感,参数设置不当可能导致策略失效。


策略优化方向:

  1. 多因子结合

    • 引入更多因子(如波动率、成交量等)优化选股模型。

  2. 动态参数调整

    • 根据市场环境动态调整动量天数和RSRS阈值。

  3. 风险控制增强

    • 加入止损机制,进一步控制回撤。

  4. ETF池扩展

    • 增加更多类型的ETF(如行业ETF、债券ETF等),丰富资产配置。


策略适用场景:

  • 市场环境:适用于趋势明显的市场环境,动量因子和RSRS择时模型能够有效捕捉趋势。

  • 投资者类型:适合风险承受能力中等、追求长期稳定收益的投资者。


策略回测表现:

  • 年化收益率:根据历史回测数据,策略年化收益率较高(具体数值需通过回测验证)。

  • 最大回撤:通过RSRS择时模型和动量因子优化,策略能够有效控制回撤。


总结:

“动量因子加RSRS择时和ETF轮动策略”通过动量因子和择时模型的结合,实现了对ETF的动态配置和趋势跟踪。策略具备较强的自动化能力和风险控制机制,适合在趋势明显的市场环境中运行。通过进一步优化和扩展,策略有望在更多市场环境中表现出色。

2025-02-21
⚠️
本站资源大多来自网络,仅供网友学习交流,未经作者或上传书面授权,请勿作他用。
站长 vx: xiangyin615 或者 留言反馈 ,我们将尽快处理。
Notice: When you of the legal rights be violate, please stir to vx: xiangyin615
个人中心
购物车
优惠劵
搜索