基于胜率的趋势交易策略整理转分享

  • 简单构建了一个基于胜率的趋势交易策略。认为过去一段时间(N天)内胜率较高、信息比率较高的股票会在紧随其后的几天有较好的表现1)先根据胜率要求筛选出过去N天胜率高的股票作为预选股票(benchmark可以是定义的确定阈值,或者是某个指数相应的收益率),用aprior算法进行快速筛选。第i只股票胜率的计算方式如下:

    winRate(i) = sum([sign(ret(i,t)-ret(bm,t))==1]/N)|t~(t-N,t)
    *ret(i,t): i股票在第t天的收益率;
    *ret(bm,t): benchmark在第t天的收益率;

    2)从筛选出的股票中选择过去N天信息比率(收益率/波动率)高的部分股票构建备选投资组合;
    3)依据被选投资组合做买入操作,使用可用资金的50%~70%;
    4)设定股票止损位在收益下跌至0.95,止损时将仓位调整至原仓位的40%~60%;
    5)调仓频率为5天,股票池为沪深300。

import lib.aprior as libAprimport numpy as npimport DataAPIfrom CAL.PyCAL import *#################################################################################    Back Test Functions################################################################################def initialize(account):                   # 初始化虚拟账户状态    pass####init the univese of the choosen stockdef universeInit():    stockComponent = DataAPI.MktTickRTSnapshotIndexGet(securityID=u"000300.XSHG",field=u"lastPrice,shortNM")    stockCount = len(stockComponent)    stockTicker = stockComponent['ticker']    stockExchgID = stockComponent['exchangeCD']    stockID = []    for index in range(stockCount):        stockID.append(stockTicker[index] + '.' + stockExchgID[index])    return stockID####deal with the trading signalsdef handle_data(account):                  # 每个交易日的买入卖出指令    ####Presettings    histLength = 10    stockDataThres = 0        ####Dictionary of the return Rate     closePrice = account.get_attribute_history('closePrice',histLength)    retRate = {}    for index in account.universe:        retRate[index] = ((closePrice[index][1:] - closePrice[index][:-1])/closePrice[index][:-1]).tolist()        ####ret list of the benchmark    # calendar = Calendar('China.SSE')    # startDate = calendar.advanceDate(account.current_date,'-'+str(histLength)+'B').toDateTime()    # benchmark = DataAPI.MktIdxdGet(ticker = "000300",    #             field = "closeIndex",    #             beginDate = startDate,    #             endDate = account.current_date,pandas = '1')    # bmClose = benchmark['closeIndex'].tolist()    # bmRet = []    # for index in range(len(bmClose)-1):    #     bmRet.append((bmClose[1:][index]-bmClose[:-1][index])/bmClose[:-1][index])        ####List of transactions    transactions = []    for index in range(histLength-1):        tmpt = []        for stock in account.universe:            if retRate[stock][index] > stockDataThres:            # if retRate[stock][index] > bmRet[index]:                tmpt.append(stock)        transactions.append(tmpt)            ####List of hot stocks    hotStock = []    hotStockDict,hotStockList = libApr.apriori(transactions,0.95)    for index in hotStockList:        for stock in index:            if stock not in hotStock:                hotStock.append(stock)        ####List of the portfolio    retRate = {}    fluctRate = {}    sharpRate = {}    for index in hotStock:        retRate[index] = ((closePrice[index][-1] - closePrice[index][0])/closePrice[index][0])        fluctRate[index] = np.std(closePrice[index])          sharpRate[index] = retRate[index]/fluctRate[index]        portfolio = [index[0] for index in sorted(sharpRate.items(),key = lambda sharpRate:sharpRate[1])[-len(sharpRate)/2:]]            ####Stop loss at -0.05    validSecHist = account.get_attribute_history('closePrice',2)    for index in account.valid_secpos:        if (validSecHist[index][-1] - validSecHist[index][0])/validSecHist[index][0] < -0.05:            order_to(index,0.45*account.valid_secpos[index])        ####Buy portfolio    for index in portfolio:        amount = 0.65*account.cash/len(hotStock)/account.referencePrice[index]        order(index,amount)    return#################################################################################    Back Test Presetting################################################################################start = '2011-01-01'                       # 回测起始时间end = '2015-11-01'                         # 回测结束时间benchmark = 'HS300'                        # 策略参考标准universe = set_universe('HS300')# universe = universeInit()                # 证券池,支持股票和基金capital_base = 100000                      # 起始资金freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测refresh_rate = 5                           # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟

策略表现

* 策略能产生一定的alpha;* 策略表现与起点强相关,sharpRatio不稳定;* 策略表现会受到自身参数设定的影响,例如胜率选择周期、筛选阈值、调仓频率、建仓头寸、止损仓位等,需要依据表现对其进行优化;* 策略在2011年4月至12月、2015年6月到11月有相对好的表现,可见其相对较适用于趋势下跌的市场环境。

问题探讨

因子选股模型的流程应该是怎样的?    一般来说,认为构建因子选股的模型需要有如下过程:        *1 大类配置:根据宏观判断市场,进行市场判断(根据不同市场选择不同因子)、资产配置(不同风险性证券的配比选择➡️不同热度的行业配比选择)和策略选择(市场中性、单边做多等);        *2 选股-alpha端:对选股因子进行有效性分析,包括单因子的预测性、因子间相关性,构建多因子模型使得选股有尽可能高的alpha;        *3 选股-风险端:对alpha端的多因子模型进行风险评估,根据风险因子优化模型,使模型尽可能达到有效边界;        *4 择时-买卖时点:对根据因子模型选出的股票进行择时分析,进一步筛选投资组合中的股票及判断作何操作。

本策略的注意点:对调仓频率很敏感,前面两年调仓都是月度的,大概筛选阈值再设低点儿比较好;换手率有些低,当时考虑的是策略中没设置清仓,止损也只是减仓,所以每次调仓的待选股要少,不然资产组合中成分股可能会一直增加至全部成分股都入池。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/321276
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 1小时前
下一篇 28分钟前

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注