One - One Code All

Blog Content

RSRS阻力支撑相对强度策略

Python 智能投研   2018-02-10 10:08:25


RSRS阻力支撑相对强度策略


一、阻力支撑相关概念

阻力位又称压力位,是指价格上涨到某个价位附近时,价格停止上涨甚至回落;其指指标价格上涨时可能遇到的压力,即交易者认为卖方力量开始反超买方,从而价格难以继续上涨或从此回调下跌的价位;支撑位则是交易者认为买方力量开始反超卖方,从而止跌或反弹上涨的价位。


常见的确定阻力支撑位的方法有,布林带上下轨突破策略(突破上轨建仓买入,突破下轨卖出平仓)和均线策略(如超过20日均线建仓买入,低于20日均线卖出平仓)。然而,布林带突破策略在震荡期间出现了持续亏损,均线策略交易交易成本巨大,且在震荡期间的回撤很大。


二、阻力支撑相对强度(RSRS)

阻力支撑相对强度(Resistance Support Relative Strength, RSRS)是另一种阻力位与支撑位的运用方式,它不再把阻力位与支撑位当做一个定值,而是看做一个变量,反应了交易者对目前市场状态顶底的一种预期判断。


我们按照不同市场状态分类来说明支撑阻力相对强度的应用逻辑:

1.市场在上涨牛市中:

如果支撑明显强于阻力,牛市持续,价格加速上涨

如果阻力明显强于支撑,牛市可能即将结束,价格见顶


2.市场在震荡中:

如果支撑明显强于阻力,牛市可能即将启动

如果阻力明显强于支撑,熊市可能即将启动


3.市场在下跌熊市中:

如果支撑明显强于阻力,熊市可能即将结束,价格见底

如果阻力明显强于支撑,熊市持续,价格加速下跌

每日最高价和最低价是一种阻力位与支撑位,它是当日全体市场参与者的交易行为所认可的阻力与支撑。一个很自然的想法是建立最高价和最低价的线性回归,并计算出斜率。即:


high=α+β·low+ϵ,ϵ∼N(0,δ2)


当斜率值很大时,支撑强度大于阻力强度。在牛市中阻力渐小,上方上涨空间大;在熊市中支撑渐强,下跌势头欲止。

当斜率值很小时,阻力强度大于支撑强度。在牛市中阻力渐强,上涨势头渐止;在熊市中支撑渐送,下方下跌空间渐大。


可参考光大研究报告。


三、阻力支撑相对强度(RSRS)指标择时策略

第一种方法是直接将斜率作为指标值。当日RSRS斜率指标择时策略如下:

1、取前N日最高价与最低价序列。(N = 18)

2、将两个序列进行OLS线性回归。

3、将拟合后的 β值作为当日RSRS斜率指标值。

4、当RSRS斜率大于 Sbuy时,全仓买入,小于 Ssell时,卖出平仓。(Sbuy=1,Ssell=0.8)


由于市场处于不同时期时,斜率的均值有比较大的波动。因此,直接采用斜率均值作为择时指标并不太合适。我们尝试下面的方法。


第二种方法是在斜率基础上进行标准化,取标准分作为指标值。RSRS斜率标准分指标择时策略如下:

1、取前M日的RSRS斜率时间序列。(M = 600)

2、计算当日RSRS斜率的标准分 RSRSstd:

 

 RSRSstd=RSRS−μMσM


其中 μM 为前M日的斜率均值,σM为前M日的标准差。

3、若 RSRSstd大于 Sbuy,则全仓买入;若 RSRSstd小于 Ssell,则卖出平仓。(Sbuy=0.7,Ssell=−0.7)

注:benchmark和标的股票均为沪深300指数,尝试N取自10-30,M取自400-800,发现N=18,M=600时收益率最高。


N,M,Sbuy 的取值范围:18,252,0.6 , 或者:16,300,0.7


该策略从2010-01-01至2017-12-15,开平仓35次,总收益186.67%,年化收益14.58%,胜率0.556,盈亏比4.568,最大回撤20.031%。

# 导入函数库
import statsmodels.api as sm

# 初始化函数,设定基准等等
def initialize(context):
    # 设定上证指数作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    # 输出内容到日志 log.info()
    log.info('初始函数开始运行且全局只运行一次')
    # 过滤掉order系列API产生的比error级别低的log
    # log.set_level('order', 'error')
    
    ### 股票相关设定 ###
    # 股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    ## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
      # 开盘前运行
    run_daily(before_market_open, time='before_open', reference_security='000300.XSHG') 
      # 开盘时运行
    run_daily(market_open, time='open', reference_security='000300.XSHG')
      # 收盘后运行
    run_daily(after_market_close, time='after_close', reference_security='000300.XSHG')

    # 设置RSRS指标中N, M的值
    g.N = 18
    g.M = 600
    g.init = True
    
    # 要操作的股票:平安银行(g.为全局变量)
    g.security = '000300.XSHG'
    
    # 买入阈值
    g.buy = 0.7
    g.sell = -0.7
    g.ans = []
    
    # 计算2005年1月5日至回测开始日期的RSRS斜率指标
    prices = get_price(g.security, '2005-01-05', context.previous_date, '1d', ['high', 'low'])
    highs = prices.high
    lows = prices.low
   
    for i in range(len(highs))[g.N:]:
        data_high = highs.iloc[i-g.N+1:i+1]
        data_low = lows.iloc[i-g.N+1:i+1]
        X = sm.add_constant(data_low)
        model = sm.OLS(data_high,X)
        results = model.fit()
    #    print("params is :",results.params)
    #    print("params.low is:",results.params['low'])
        g.ans.append(results.params['low'])
    
## 开盘前运行函数     
def before_market_open(context):
    # 输出运行时间
    log.info('函数运行时间(before_market_open):'+str(context.current_dt.time()))


    
## 开盘时运行函数
def market_open(context):
    log.info('函数运行时间(market_open):'+str(context.current_dt.time()))
    security = g.security
    # 取得当前的现金
    cash = context.portfolio.available_cash

    # 填入各个日期的RSRS斜率值

    security = g.security
    
    if g.init:
        g.init = False
    else:
        # RSRS斜率指标定义
        prices = attribute_history(security, g.N, '1d', ['high', 'low'])
        highs = prices.high
        lows = prices.low
        X = sm.add_constant(lows)
        model = sm.OLS(highs, X)
        beta = model.fit().params[1]
        g.ans.append(beta)

    
    # 计算标准化的RSRS指标
    # 计算均值序列    
    section = g.ans[-g.M:]
    # 计算均值序列
    mu = np.mean(section)
    # 计算标准化RSRS指标序列
    sigma = np.std(section)
    zscore = (section[-1]-mu)/sigma    

    # 如果上一时间点的RSRS斜率大于买入阈值, 则全仓买入
    if zscore > g.buy:
        # 记录这次买入
        log.info("标准化RSRS斜率大于买入阈值, 买入 %s" % (security))
        # 用所有 cash 买入股票
        order_value(security, cash)
    # 如果上一时间点的RSRS斜率小于卖出阈值, 则空仓卖出
    elif zscore < g.sell and context.portfolio.positions[security].closeable_amount > 0:
        # 记录这次卖出
        log.info("标准化RSRS斜率小于卖出阈值, 卖出 %s" % (security))
        # 卖出所有股票,使这只股票的最终持有量为0
        order_target(security, 0)
 
## 收盘后运行函数  
def after_market_close(context):
    log.info(str('函数运行时间(after_market_close):'+str(context.current_dt.time())))
    #得到当天所有成交记录
    trades = get_trades()
    for _trade in trades.values():
        log.info('成交记录:'+str(_trade))
    log.info('一天结束')
    log.info('##############################################################')



上一篇:量化科技2017年上半年营收70万元 业绩亏损325万元
下一篇:【转载】利用知识图谱技术,智能投研公司「 文因互联」对金融数据进行结构化提取和智能化分析

The minute you think of giving up, think of the reason why you held on so long.