研报复现系列(二):【光大证券】基于阻力支撑相对强度(RSRS)的市场择时

1.研报概述

本文是券商金工研报复现系列的第二篇,文本复现了【光大证券】的【基于阻力支撑相对强度(RSRS)的市场择时】。

阻力位与支撑位传统的应用方法一般是选取特定的阻力位、支撑位作为阈值来进行突破、反转策略的构建,常见的策略如均线策略:【若当日收盘价超过 20 日均线,则建仓买入。一直持仓至收盘价低于 20 日均线,卖出平仓】。

不同于选取阻力位与支撑位阈值区间的传统应用方法,该篇研报关注阻力位与支撑位的相对强弱程度。

阻力位与支撑位实际上反应了交易者对市场状态顶部和底部的预期判断。

从直觉上看,如果这种预期判断极易改变,则表明支撑位或阻力位的强度小,有效性弱;而如果众多交易者预期较为一致、变动不大,则表明支撑位或阻力位强度高,有效性强。

如果支撑位的强度小,作用弱于阻力位,则表明市场参与者对于支撑位的分歧大于对于阻力位的分歧,市场接下来更倾向于向熊市转变。而如果支撑位的强度大,作用强于阻力位,则表示市场参与者对于支撑位的认可度更高于对于阻力位的认可度,市场更倾向于在牛市转变。
我们按照不同市场状态分类来说明支撑阻力相对强度的应用逻辑:
1.市场在上涨牛市中:
如果支撑明显强于阻力,牛市持续,价格加速上涨
如果阻力明显强于支撑,牛市可能即将结束,价格见顶
2.市场在震荡中:
如果支撑明显强于阻力,牛市可能即将启动
如果阻力明显强于支撑,熊市可能即将启动
3.市场在下跌熊市中:
如果支撑明显强于阻力,熊市可能即将结束,价格见底
如果阻力明显强于支撑,熊市持续,价格加速下跌

该篇研报构建衡量阻力位与支撑位相对强度的指标RSRS(Resistance Support Relative Strength),当支撑位强度小,阻力位强度大时,RSRS的值较高,相反RSRS的值较低。

2.研究环境

数据源:聚宽JoinQuant,2005.6-2017.5日线数据

import datetime 
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import statsmodels.api as sm
import warnings
warnings.filterwarnings("ignore")
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

3.研报复现

3.1量化阻力位支撑位相对强度RSRS

该研报要解决的首要问题是如何定义并量化阻力位与支撑位的相对强度,而解决该问题首先要选取一对合适的阻力位与支撑位指标。

3.1.1如何选取阻力位与支撑位

量化阻力位与支撑位相对强度的第一步,是选取合适的阻力位和支撑位指标。在技术分析学派中,已经有了许多对于支撑位与阻力位的定义,常见的包括通道线(布林带的上下轨),一段时间内 的前高与前低,区间震荡线(DPO)等等。

该篇研报选取每日的最高价和最低价作为阻力位和支撑位,因为每日的最高价和最低价可以迅速反应近期市场对于阻力位与支撑位态度的性质。

3.1.2RSRS构建的基本思想

本篇研报提出了多种相对强弱程度的量化方法,并且是逐层优化的关系。

这里对各自方法进行简单的介绍,后面会给出每种量化方法构建的策略的效果。

基本思想:

这里使用最高价和最低价的相对变化速率,即类似 delta(high)/delta(low)的值来描

述支撑位与阻力位的相对强度,即最低价每变动 1 的时候,最高价变动的幅度。

基于该基本思想,原研报使用

线性回归线的斜率

斜率标准分

修正标准分

右偏标准分

四种方法量化阻力支撑相对强弱程度。这四种方法是逐层递进、优化的关系。

最后又结合价量数据优化策略。本文将会对每一种方法给出其计算方法和构建的策略的效果。

3.2 具体计算方法和策略效果

3.2.0 数据格式与策略统计函数

在给出具体的策略代码之前,我们先介绍策略使用的数据格式。

在策略回测中,我们使用DataFrame格式的数据df。其不仅包含价格和RSRS指标的时间序列,还有flag和position两列。

flag是开仓平仓标志位,df[‘flag’][i]为1时,表明第i日进行了开仓操作,df[‘flag’][i]为-1时,表明第i日进行了平仓操作。position是账户持仓标志位,其值为1表明当前账户持有证券,其值为0表明当前账户为空仓。

同时,本文构建的策略中,只有当前账户空仓时才进行买入操作

这里,我们先给出统计策略结果的函数,后文会多次用到该函数。

def calculate_statistics(df):
    '''
    输入:
    DataFrame类型,包含价格数据和仓位、开平仓标志
        position列:仓位标志位,0表示空仓,1表示持有标的
        flag列:买入卖出标志位,1表示在该时刻买入,-1表示在该时刻卖出
        close列:日收盘价
        
    输出:dict类型,包含夏普比率、最大回撤等策略结果的统计数据
    '''
    #净值序列
    df['net_asset_pct_chg'] = df.net_asset_value.pct_change(1).fillna(0)
    
    #总收益率与年化收益率
    total_return = (df['net_asset_value'][df.shape[0]-1] -1)
    annual_return = (total_return)**(1/(df.shape[0]/252)) -1
    total_return = total_return*100
    annual_return = annual_return*100
    #夏普比率
    df['ex_pct_chg'] = df['net_asset_pct_chg']
    sharp_ratio = df['ex_pct_chg'].mean() * math.sqrt(252)/df['ex_pct_chg'].std()
    
    #回撤
    df['high_level'] = (
            df['net_asset_value'].rolling(
            min_periods=1, window=len(df), center=False).max()
    )
    df['draw_down'] = df['net_asset_value'] - df['high_level']
    df['draw_down_percent'] = df["draw_down"] / df["high_level"] * 100
    max_draw_down = df["draw_down"].min()
    max_draw_percent = df["draw_down_percent"].min()
    
    #持仓总天数
    hold_days = df['position'].sum()
    
    #交易次数
    trade_count = df[df['flag']!=0].shape[0]/2
    
    #平均持仓天数
    avg_hold_days = int(hold_days/trade_count)
    
    #获利天数
    profit_days = df[df['net_asset_pct_chg'] > 0].shape[0]
    #亏损天数
    loss_days = df[df['net_asset_pct_chg'] < 0].shape[0]
    
    #胜率(按天)
    winrate_by_day = profit_days/(profit_days+loss_days)*100
    #平均盈利率(按天)
    avg_profit_rate_day = df[df['net_asset_pct_chg'] > 0]['net_asset_pct_chg'].mean()*100
    #平均亏损率(按天)
    avg_loss_rate_day = df[df['net_asset_pct_chg'] < 0]['net_asset_pct_chg'].mean()*100
    #平均盈亏比(按天)
    avg_profit_loss_ratio_day = avg_profit_rate_day/abs(avg_loss_rate_day)
    
    
    #每一次交易情况  
    buy_trades = df[df['flag']==1].reset_index()
    sell_trades = df[df['flag']==-1].reset_index()
    result_by_trade = {
        'buy':buy_trades['close'],
        'sell':sell_trades['close'],
        'pct_chg':(sell_trades['close']-buy_trades['close'])/buy_trades['close']
    }
    result_by_trade = pd.DataFrame(result_by_trade)
    #盈利次数
    profit_trades = result_by_trade[result_by_trade['pct_chg']>0].shape[0]
    #亏损次数
    loss_trades = result_by_trade[result_by_trade['pct_chg']<0].shape[0]
    #单次最大盈利
    max_profit_trade = result_by_trade['pct_chg'].max()*100
    #单次最大亏损
    max_loss_trade = result_by_trade['pct_chg'].min()*100
    #胜率(按次)
    winrate_by_trade = profit_trades/(profit_trades+loss_trades)*100
    #平均盈利率(按次)
    avg_profit_rate_trade = result_by_trade[result_by_trade['pct_chg'] > 0]['pct_chg'].mean()*100
    #平均亏损率(按次)
    avg_loss_rate_trade = result_by_trade[result_by_trade['pct_chg'] < 0]['pct_chg'].mean()*100
    #平均盈亏比(按次)
    avg_profit_loss_ratio_trade = avg_profit_rate_trade/abs(avg_loss_rate_trade)
    
    statistics_result = {
        'net_asset_value':df['net_asset_value'][df.shape[0]-1],#最终净值
        'total_return':total_return,#收益率
        'annual_return':annual_return,#年化收益率
        'sharp_ratio':sharp_ratio,#夏普比率
        'max_draw_percent':max_draw_percent,#最大回撤
        'hold_days':hold_days,#持仓天数
        'trade_count':trade_count,#交易次数
        'avg_hold_days':avg_hold_days,#平均持仓天数
        'profit_days':profit_days,#盈利天数
        'loss_days':loss_days,#亏损天数
        'winrate_by_day':winrate_by_day,#胜率(按天)
        'avg_profit_rate_day':avg_profit_rate_day,#平均盈利率(按天)
        'avg_loss_rate_day':avg_loss_rate_day,#平均亏损率(按天)
        'avg_profit_loss_ratio_day':avg_profit_loss_ratio_day,#平均盈亏比(按天)
        'profit_trades':profit_trades,#盈利次数
        'loss_trades':loss_trades,#亏损次数
        'max_profit_trade':max_profit_trade,#单次最大盈利
        'max_loss_trade':max_loss_trade,#单次最大亏损
        'winrate_by_trade':winrate_by_trade,#胜率(按次)
        'avg_profit_rate_trade':avg_profit_rate_trade,#平均盈利率(按次)
        'avg_loss_rate_trade':avg_loss_rate_trade,#平均亏损率(按次)
        'avg_profit_loss_ratio_trade':avg_profit_loss_ratio_trade#平均盈亏比(按次)
    }
    return statistics_result

3.2.1斜率方法

因为市场上存在噪声,所以考虑用连续N日的最高价与最低价的线性回归模型的斜率来量化支撑位与阻力位的相对强度,以求增加信噪比。

即,取连续N日的最高价与最低价的线性回归模型

high = alpha + beta*low

中的beta,即直线的斜率,作为我们的相对强度RSRS。

斜率指标计算方法:

  1. 取前 N 日的最高价序列与最低价序列。
  2. 将两列数据按式(1)的模型进行 OLS 线性回归。
  3. 将拟合后的 beta 值作为当日 RSRS 斜率指标值。

在原研报中,经过对N的不同取值的比较,N取18时,量化出的指标构建的策略更有效。

基于斜率方法,构建策略:

  1. 计算 RSRS 斜率。
  2. 如果斜率大于 1,则买入持有。
  3. 如果斜率小于 0.8,则卖出手中持股平仓。

策略源代码

#当日斜率指标计算方式,线性回归
def cal_nbeta(df,n):
    nbeta = []
    trade_days = len(df.index)
    
    df['position'] = 0
    df['flag'] = 0
    position = 0
    
  #计算斜率值
    for i in range(trade_days):
        if i < (n-1):
            #n-1为配合接下来用iloc索引
            continue
        else:    
            x = df['low'].iloc[i-n+1:i+1]
            #iloc左闭右开
            x = sm.add_constant(x)
            y = df['high'].iloc[i-n+1:i+1]
            regr = sm.OLS(y,x)
            res = regr.fit()
            beta = round(res.params[1],2)#斜率指标          
            nbeta.append(beta)    
    df1 = df.iloc[n-1:]
    df1['beta'] = nbeta
    
  #执行交易策略
    for i in range(len(df1.index)-1):
        #此处-1是为了避免最后一行
        if df1['beta'].iloc[i] > 1 and position == 0:
            df1['flag'].iloc[i] = 1 #开仓标志
            df1['position'].iloc[i+1] =1 #仓位不为空
            position = 1
        elif df1['beta'].iloc[i] < 0.8 and position == 1:
            df1['flag'].iloc[i] = -1 #平仓标志
            df1['position'].iloc[i+1] = 0 #仓位为空
            position = 0
        else:
            df1['position'].iloc[i+1] = df1['position'].iloc[i]
    #计算净值序列     
    df1['net_asset_value'] = (1+df1.close.pct_change(1).fillna(0)*df1.position).cumprod()
    return df1

策略净值曲线

图片

策略的统计指标

统计量斜率策略
净值10.66
收益率965.73%
年化收益率21.92%
夏普比率1.16
最大回撤-50.26%
持仓天数1184
交易次数21
平均持仓天数56
盈利天数747
亏损天数575
胜率(按天)56.51%
平均盈利率(按天)1.31%
平均亏损率(按天)-1.25%
平均盈亏比(按天)1.05
盈利次数16
亏损次数5
单次最大盈利170%
单次最大亏损-12%
胜率(按次)76.19%
平均盈利率(按次)25%
平均亏损率(按次)-3%
平均盈亏比(按次)7.86

3.2.2斜率方法的优化——斜率标准分

使用斜率指标构建策略时,需要参考斜率指标在历史上的均值和标准差以选择合适的开仓、平仓阈值。

但随时市场的变化,不同时期数据的均值与标准差可能会发生变化。同时交易者也可能更关心在当前市场在近期的环境中处在什么样的位置,或者接下来一段时间市场相比于目前将会有怎么的发展。所以相较于直接使用斜率在整个历史上的均值和标准差来帮助选择阈值,根据斜率在最近一定周期内(600个交易日)的标准分确定阈值可以更加灵活地适应近期的整体市场基本状态。

斜率标准分计算方法:

  1. 取前 M 日的斜率时间序列。
  2. 以此样本计算当日斜率的标准分。
  3. 将计算得到的标准分 z 作为当日 RSRS 标准分指标值。

构建标准分策略:

1.根据斜率计算标准分(参数 N=18,M=600)。
2.如果标准分大于 S(参数 S=0.7),则买入持有。
3.如果标准分小于-S,则卖出平仓。

策略源代码

#标准分策略
def cal_stdbeta(df,n):
    
    df['position'] = 0
    df['flag'] = 0
    position = 0
    
    df1 = cal_nbeta(df,n)
    pre_stdbeta = df1['beta']
    pre_stdbeta = np.array(pre_stdbeta)
    #转化为数组,可以对整个数组进行操作
    sigma = np.std(pre_stdbeta)
    mu = np.mean(pre_stdbeta)
    #标准化
    stdbeta = (pre_stdbeta-mu)/sigma
    
    df1['stdbeta'] = stdbeta
    
    for i in range(len(df1.index)-1):
        #此处-1是为了避免最后一行
        if df1['stdbeta'].iloc[i] > 0.7 and position == 0:
            df1['flag'].iloc[i] = 1
            df1['position'].iloc[i+1] =1
            position = 1
        elif df1['stdbeta'].iloc[i] < -0.7 and position == 1:
            df1['flag'].iloc[i] = -1
            df1['position'].iloc[i+1] = 0
            position = 0
        else:
            df1['position'].iloc[i+1] = df1['position'].iloc[i]
            
    df1['net_asset_value'] = (1+df1.close.pct_change(1).fillna(0)*df1.position).cumprod()
    return df1
#stdbeta是数组 beta是列表

净值曲线图

图片

策略的统计指标

统计量标准分策略
净值13.93
收益率1292.70%
年化收益率25.07%
夏普比率1.28
最大回撤-50.26%
持仓天数1298
交易次数67
平均持仓天数19
盈利天数741
亏损天数557
胜率(按天)57.09%
平均盈利率(按天)1.32%
平均亏损率(按天)-1.25%
平均盈亏比(按天)1.06
盈利次数40
亏损次数26
单次最大盈利91%
单次最大亏损-41%
胜率(按次)60.61%
平均盈利率(按次)18%
平均亏损率(按次)-9%
平均盈亏比(按次)2.05

3.2.3再优化——修正标准分:考虑到线性拟合的程度

使用线性回归拟合直线的斜率或其标准分作为相对强弱程度时,可能出现斜率或标准分的绝对值很大,但直线本身的拟合效果并不好,使得斜率或斜率的标准分本身不能很好的体现出相对强弱程度的问题。需要构建相对强弱程度指标时可以考虑到线性模型拟合结果的好坏。

在线性回归中,R 平方值(决定系数)可以理解成线性拟合效果的程度。

因此,使用

修正标准分=标准分*R 平方值(决定系数

来量化相对强弱程度,可以削弱直线拟合效果对指标效果的影响。

构建修正标准分策略

  1. 计算修正标准分(N=16,M=300)。
  2. 如果修正标准分大于 S(S=0.7),则买入持有。
  3. 如果修正标准分小于-S,则卖出平仓。

策略源代码

#RSRS 标准分指标优化,修正标准分
def cal_better_stdbeta(df,n):
    nbeta = []
    R2 = []
    trade_days = len(df.index)
    for i in range(trade_days):
        if i < (n-1):
            #n-1为配合接下来用iloc索引
            continue
        else:
    
            x = df['low'].iloc[i-n+1:i+1]
            #iloc左闭右开
            x = sm.add_constant(x)
            y = df['high'].iloc[i-n+1:i+1]
            regr = sm.OLS(y,x)
            res = regr.fit()
            beta = round(res.params[1],2)
            
            R2.append(res.rsquared)
            nbeta.append(beta)
            
    prebeta = np.array(nbeta)
    sigma = np.std(prebeta)
    mu = np.mean(prebeta)
    stdbeta = (prebeta-mu)/sigma
    
    r2 = np.array(R2)
    better_stdbeta = r2*stdbeta#修正标准分
    
    df1 = df.iloc[n-1:]
    df1['beta'] = nbeta
    df1['flag'] = 0
    df1['position'] = 0
    position = 0
    df1['better_stdbeta'] = better_stdbeta
    
    for i in range(len(df1.index)-1):
        #此处-1是为了避免最后一行
        if df1['better_stdbeta'].iloc[i] > 0.7 and position == 0:
            df1['flag'].iloc[i] = 1
            df1['position'].iloc[i+1] =1
            position = 1
        elif df1['better_stdbeta'].iloc[i] < -0.7 and position == 1:
            df1['flag'].iloc[i] = -1
            df1['position'].iloc[i+1] = 0
            position = 0
        else:
            df1['position'].iloc[i+1] = df1['position'].iloc[i]
    df1['net_asset_value'] = (1+df1.close.pct_change(1).fillna(0)*df1.position).cumprod()
    return df1

策略净值曲线
图片

策略指标

修正标准分策略
净值12.15
收益率1115.40%
年化收益率23.47%
夏普比率1.19
最大回撤-51.28%
持仓天数1397
交易次数46
平均持仓天数30
盈利天数790
亏损天数607
胜率(按天)56.55%
平均盈利率(按天)1.30%
平均亏损率(按天)-1.25%
平均盈亏比(按天)1.05
盈利次数32
亏损次数14
单次最大盈利76%
单次最大亏损-18%
胜率(按次)69.57%
平均盈利率(按次)11%
平均亏损率(按次)-3%
平均盈亏比(按次)3.3

3.2.4再再优化——右偏标准分:在实践过程中的猜想

原研报在分析比较标准分和修正标准分对后市的相关性时,发现右侧(即z>0)的标准分对后市收益有较好的预测性,而左侧的标准分则失去了预测性,因为左侧的标准分占了整体的大部分,所以整体标准分与后市收益相关性较低。而修正标准分右侧的取值范围扩大了(相对于左侧而言,并非绝对的值域),修正标准分整体上呈现了更好的预测性。

因此猜测:是否右侧的取值范围越广(相对于左侧而言,并非绝对的值域范围),指标的预测性更好?

为了验证该猜想,构建右偏标准分

右偏标准分=修正标准分*斜率

构建右偏标准分策略

  1. 计算右偏标准分(N=16,M=300)。
  2. 如果右偏标准分大于 S(S=0.7),则买入持有。
  3. 如果右偏标准分小于-S,则卖出平仓。

策略源代码

#右偏标准分 此时N取16
def cal_right_stdbeta(df,n):
    
    df1 = cal_better_stdbeta(df,n)
    df1['position'] = 0
    df1['flag'] = 0
    df1['net_value'] = 0  
    position = 0
    
    df1['right_stdbeta'] = df1['better_stdbeta']*df1['beta']        
    #修正标准分与斜率值相乘能够达到使原有分布右偏的效果
    
    for i in range(len(df1.index)-1):
        #此处-1是为了避免最后一行
        if df1['right_stdbeta'].iloc[i] > 0.7 and position == 0:
            df1['flag'].iloc[i] = 1
            df1['position'].iloc[i+1] =1
            position = 1
        elif df1['right_stdbeta'].iloc[i] < -0.7 and position == 1:
            df1['flag'].iloc[i] = -1
            df1['position'].iloc[i+1] = 0
            position = 0
        else:
            df1['position'].iloc[i+1] = df1['position'].iloc[i]
    df1['net_asset_value'] = (1+df1.close.pct_change(1).fillna(0)*df1.position).cumprod()    
    return df1

净值曲线图
图片

策略指标

统计量右偏标准分
净值17.67
收益率1667.22%
年化收益率27.88%
夏普比率1.29
最大回撤-51.16%
持仓天数1638
交易次数37.5
平均持仓天数43
盈利天数928
亏损天数710
胜率(按天)56.65%
平均盈利率(按天)1.27%
平均亏损率(按天)-1.22%
平均盈亏比(按天)1.04
盈利次数26
亏损次数11
单次最大盈利91%
单次最大亏损-17%
胜率(按次)70.27%
平均盈利率(按次)15%
平均亏损率(按次)-3%
平均盈亏比(按次)4.6

3.3 结合市场状态的优化

基于上文介绍的四种阻力支撑相对强弱程度指标RSRS构建出的交易策略都大幅度地跑赢了基准收益,但也都有一个共同的缺陷:净值在08年股灾期间都出现了大幅的回撤

图片

这是因为按照阻力支撑相对强弱指标的逻辑,策略大概率是在左侧开仓、左侧平仓。(这里的左侧是指股价呈现“V”字型时的下跌阶段,并不是上文讨论右偏标准分时提到的左侧)。但当市场处在大熊市状态时,如果开仓预测失误,就会造成严重的亏损。

因此,我们期望在保证收益的同时,尽可能降低熊市错误开仓的几率。

简单的想法是:先判断市场状态是处在上升还是下跌趋势,再结合RSRS构建买入、卖出策略。

3.3.1 结合均线指标的优化

有很多指标帮助我们判断近期市场状态,如MA,MACD等。在这里我们使用当日 20 日均线值与 3 日前 20 日均线值的相对大小来判断近期市场状态。

优化后的交易策略为:

1.计算 RSRS 标准分指标买卖信号。

  1. 如果指标发出买入信号,同时满足前一日 MA(20)的值大于前三日MA(20)的值,则买入。
  2. 如果指标发出卖出信号,则卖出手中持股。

策略代码

RSRS 指标配合价格数据优化策略
def cal_ma_beta(df,n):
    df1 = cal_stdbeta(df,n)
    df1['position'] = 0
    df1['flag'] = 0
    df1['net_asset_value'] = 0
    position = 0
    
#beta是前17天没有数据(n=18) ma20是前20天没有数据
    for i in range(5,len(df1.index)-1):
        if df1['stdbeta'].iloc[i] > 0.7 and df1['ma20'].iloc[i-1]>df1['ma20'].iloc[i-3] and position == 0:
            df1['flag'].iloc[i] = 1
            df1['position'].iloc[i+1] = 1
            position = 1
        elif df1['stdbeta'].iloc[i] < -0.7 and df1['ma20'].iloc[i-1]<df1['ma20'].iloc[i-3] and position == 1:
            df1['flag'].iloc[i] = -1
            df1['position'].iloc[i+1] = 0
            position = 0
        else:
            df1['position'].iloc[i+1] = df1['position'].iloc[i]
    df1['net_asset_value'] = (1+df1.close.pct_change(1).fillna(0)*df1.position).cumprod()          
    return df1

净值曲线
图片

策略指标

统计量均值优化标准分策略
净值16.91
收益率1591.22%
年化收益率27.36%
夏普比率1.48
最大回撤-23.61%
持仓天数1638
交易次数37.5
平均持仓天数43
盈利天数714
亏损天数470
胜率(按天)60.30%
平均盈利率(按天)1.24%
平均亏损率(按天)-1.24%
平均盈亏比(按天)1
盈利次数26
亏损次数11
单次最大盈利91%
单次最大亏损-17%
胜率(按次)70.27%
平均盈利率(按次)15%
平均亏损率(按次)-3%
平均盈亏比(按次)4.6

3.3.2 结合交易量相关性的优化

除却直接从近期历史价格来确认当下市场趋势状态,很多发表的研究表明市场涨跌与交易量有明显的正相关性。借鉴类似的想法,我们尝试用交易量与修正标准分之间的相关性来过滤误判信号。只有在相关性为正的时刻给出的交易信号,我们才认为是合理的信号。

优化后的策略为

  1. 计算 RSRS 标准分指标买卖信号。
  2. 如果指标发出买入信号,同时满足前 10 日交易量与修正标准分之间的相关性为正,则买入。
  3. 如果指标发出卖出信号,则卖出手中持股。

策略代码

#基于 RSRS 指标与交易量相关性的优化
def cal_vol_beta(df,n):
    df1 = cal_stdbeta(df,n)
    
    df1['position'] = 0
    df1['flag'] = 0
    df1['net_asset_value'] = 0  
    position = 0
    
    for i in range(10,len(df1.index)-1):
        
        pre_volume = df1['volume'].iloc[i-10:i]
        series_beta = df1['stdbeta'].iloc[i-10:i]
        #计算相关系数需要数据为series格式
        corr = series_beta.corr(pre_volume,method = 'pearson')
        if df1['stdbeta'].iloc[i] > 0.7 and corr > 0 and position == 0:
            df1['flag'].iloc[i] = 1
            df1['position'].iloc[i+1] = 1
            position = 1
        elif df1['stdbeta'].iloc[i] < -0.7 and position == 1:
            df1['flag'].iloc[i] = -1
            df1['position'].iloc[i+1] = 0
            position = 0
        else:
            df1['position'].iloc[i+1] = df1['position'].iloc[i]
            
    df1['net_asset_value'] = (1+df1.close.pct_change(1).fillna(0)*df1.position).cumprod()
    return df1

净值曲线
图片

策略指标

统计量成交量优化标准分策略
净值13.97
收益率1296.64%
年化收益率25.10%
夏普比率1.57
最大回撤-22.29%
持仓天数916
交易次数40
平均持仓天数22
盈利天数548
亏损天数368
胜率(按天)59.83%
平均盈利率(按天)1.29
平均亏损率(按天)-1.16
平均盈亏比(按天)1.11
盈利次数27
亏损次数13
单次最大盈利79%
单次最大亏损-16%
胜率(按次)67.50%
平均盈利率(按次)13%
平均亏损率(按次)-4%
平均盈亏比(按次)3.71

3.4 策略结果汇总

现在给出所有RSRS策略的净值曲线和统计数据

图片

统计量斜率标准分修正标准分右偏标准分均值优化标准分成交量优化标准分
净值10.6613.9312.1517.6716.9113.97
收益率965.73%1292.70%1115.40%1667.22%1591.22%1296.64%
年化收益率21.92%25.07%23.47%27.88%27.36%25.10%
夏普比率1.161.281.191.291.481.57
最大回撤-50.26%-50.26%-51.28%-51.16%-23.61%-22.29%
持仓天数11841298139716381638916
交易次数21674637.537.540
平均持仓天数561930434322
盈利天数747741790928714548
亏损天数575557607710470368
胜率(按天)56.51%57.09%56.55%56.65%60.30%59.83%
平均盈利率(按天)1.31%1.32%1.30%1.27%1.24%1.29
平均亏损率(按天)-1.25%-1.25%-1.25%-1.22%-1.24%-1.16
平均盈亏比(按天)1.051.061.051.0411.11
盈利次数164032262627
亏损次数52614111113
单次最大盈利170%91%76%91%91%79%
单次最大亏损-12%-41%-18%-17%-17%-16%
胜率(按次)76.19%60.61%69.57%70.27%70.27%67.50%
平均盈利率(按次)25%18%11%15%15%13%
平均亏损率(按次)-3%-9%-3%-3%-3%-4%
平均盈亏比(按次)7.862.053.34.64.63.71

4.总结

本文基本复现了【光大证券-基于阻力支撑相对强度(RSRS)的市场择时】的研究内容,同时得到了与原研报相近的结果。

本文的不足:

1.没有考虑交易成本。原研报同时给出了在不同交易成本下各策略的结果,净值有略微的下降。

2.没有给出选取不同N、M时策略的表现情况。

5.本文作者

蔡金航 哈尔滨工业大学威海校区 计算机科学与技术学院

何百圣 哈尔滨工业大学威海校区 经济管理学院

写在最后

我们是国内普通高校的在校学生,同时也是量化投资的初学者。我们的学校不是清北复交,也没有金融工程实验室,同时地处三线小城,因此我们在校期间较难获得量化实习机会,但我们期待与业界进行沟通、交流。

蔡金航同学是我们其中的一员。其在寻找暑期量化实习时,收到了几家私募和券商金工组的笔试邀请,笔试内容皆为在给定时间内复现出一篇金工研报。蔡同学受到启发,发觉复现金工研报是我们学习量化策略、锻炼程序设计能力同时也是与业界交流的很好的途径。

在蔡同学的建议下,我们开启研报复现系列的创作,记录我们的学习过程,并将我们的创作内容分享出来,与读者们一起交流、学习、进步。

我们的水平有限,创作的内容难免会有错误或不严谨的内容,我们欢迎读者的批评指正。

如果您对我们的内容感兴趣,请联系我们:cai_jinhang@foxmail.com

  • 28
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
### 回答1: 光大证券RSRS是一种以多只基金为基础的产品。自上市以来,该产品一直保持着稳定的表现和广泛的关注度。作为一种实现一定风险分散的投资手段,光大证券RSRS为广大投资者提供了更多的选择和灵活性。 在过去的几年中,光大证券RSRS一直秉持着"安全、稳健、低风险"的投资理念,深受广大投资者的信任。其稳健的表现不仅得益于光大证券的优秀管理团队和严谨的风控措施,也与中国金融市场的稳定发展密切相关。 目前,光大证券RSRS的产品线已相当丰富,涵盖了股票型、债券型、货币型、混合型等多个品种。不同类型的基金在光大证券RSRS中将根据风险偏好和预期收益率来进行配置,以实现投资多元化和风险控制。 总的来说,光大证券RSRS是一种值得投资者信任的产品。它既稳健、安全,同时又可以通过多样化的配置实现较高的收益。对于那些寻求明智投资建议的投资者来说,光大证券RSRS是一个值得考虑的选择。 ### 回答2: 光大证券rsrs是指光大证券关注的重点股票,RSRS即Relative Strength Ranking System,是一种相对强度排名系统。该系统将市场中的股票按照相对强度进行排名,选出表现最佳的股票,以寻找投资机会。这种方式已经被证明是一种有效的选股方法。 光大证券rsrs回顾可以从两个角度来看待。首先,从投资者角度来看,光大证券rsrs对于投资者的投资决策和股票选择具有一定的参考价值。其次,从光大证券自身的角度来看,其推出的RSRS系统是其持续创新的一种体现,进一步提高了公司的核心竞争力。 在实际应用中,光大证券rsrs系统已经广泛运用。与传统的投资方法相比,使用RSRS系统可以更加精准地捕捉市场行情,对于制定投资策略和风险控制都有很大的帮助。同时,也可以减少因为盲目跟风而造成的损失。 总之,光大证券rsrs系统是光大证券多年积累和实践的经验总结,对于投资者选股和光大证券提高核心竞争力都具有重要意义。在未来的应用中,它还将继续发挥其独特优势,为投资者和证券公司创造更大的价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值