一天中买入股票的最佳时机,python 买卖股票的最佳时机

  

  文章来自量化小白的评分,作者量化小白h   

  

  看完前面的铺垫,写点可以实践的东西。本文给出了编写时序策略回测的详细步骤,并用代码展示了整个过程。代码是用python写的,后台“择时”检索数据和代码,可以自己测试。   

  

  择时策略   

  

  根据百度百科的解释,择时交易是指运用某种方法判断大势,无论是上涨还是下跌,还是盘整。如果判断是上涨,买入持有;如果判断为下跌,卖出清仓;如果是盘整,可以高抛低吸。   

  

  从定量的角度来说,择时就是通过资产的数据构造一个买卖信号,然后根据这个买卖信号进行交易。回测就是实现全过程。   

  

  本文以最简单的双均线策略为例进行回测。具体规则如下:   

  

  短均线下穿长均线(金叉),目前没有仓位:买入;短均线下穿长均线(死叉),目前持有卖出;其他情况下,保持之前的位置;可以考虑控制回撤,单笔亏损超过一定范围就平仓。   

  

  回测评价   

  

  对于策略的评价,一般分为收益和风险两个方面,或者将两者结合起来,列出一些常用的评价指标。   

  

  年化收益   

  

  回测从起点到终点的累计收益可以年化,可以计算复利或单利。复利假设策略的利润也会用于投资,所以复利计算结果会更好看。   

  

  夏普比   

  

  夏普比率=(战略预期收益率-无风险收益率)/战略波动率   

  

  Sharpie是应用最广泛的指数,综合衡量收益和风险。   

  

  胜率   

  

  要统计中签率,首先要统计交易笔数,然后计算盈利笔数在所有交易中所占的比例。   

  

  最大回撤率   

  

  回撤是策略从前期最高点到当前点的损失,最大回撤是所有回撤的最大值,反映了策略可能的最大损失。   

  

  单次最大亏损   

  

  所有单笔交易中最大的损失   

  

  策略阶段性表现   

  

  划分战略时间段,统计上述指标在各个时间段的变化。本文以年为单位进行划分,统计年收益率和相对于基准的超额收益率。   

  

  其他   

  

  此外,还有各种指标,如波动性、下行风险、交易比率等。python里有专门的模块,可以计算各种指标。这里我们自己算算各种指标,供参考。   

  

  另外,还要测试策略的稳定性,扰动策略中的参数,测试策略的灵敏度。一个好的策略应该对参数不敏感。   

  

     

  

  回测说明   

  

  回测标的:沪深300指数   

  

  回测区间: 2010年1月至2019年3月   

  

  代码说明:后面的测试代码分为两部分,一部分是策略函数(Strategy),另一部分是评估函数(http://www . Sina . com/)。策略函数通过指数收盘价构造信号,计算策略净值,统计策略每笔交易的情况。评价函数根据策略的净值和策略每笔交易的情况计算策略的上述指标。   

  

  Performance   

  

  策略代码   

  

  def策略(pdatas,win_long,win_short,loss ratio=999): # pdatas=datas . copy();win _ long=12win _ short=6;lossratio=999pma:计算均线的价格序列。win:窗口宽度损失率:止损率。默认值为0 ' ' pdatas=pdatas . copy()pdatas[' LMA ']=pdatas . close . rolling(win _ long,Min _ periods=0)。mean()pdata s[' SMA ']=pdata s . close . rolling(win _ short,min _ periods=0)。Mean () pdatas ['position']=0 #记录位置pdatas['flag']=0 #记录   

_in = 1 for i in range(max(1,win_long),pdatas.shape[0] - 1): # 当前无仓位,短均线上穿长均线,做多 if (pdatas.sma[i-1] < pdatas.lma[i-1]) & (pdatas.sma[i] > pdatas.lma[i]) & (pdatas.position[i]==0): pdatas.loc[i,'flag'] = 1 pdatas.loc[i + 1,'position'] = 1 date_in = pdatas.DateTime[i] price_in = pdatas.loc[i,'CLOSE'] pricein.append([date_in,price_in]) # 当前持仓,下跌超出止损率,止损 elif (pdatas.position[i] == 1) & (pdatas.CLOSE[i]/price_in - 1 < -lossratio): pdatas.loc[i,'flag'] = -1 pdatas.loc[i + 1,'position'] = 0 priceout.append([pdatas.DateTime[i],pdatas.loc[i,'CLOSE']]) # 当前持仓,死叉,平仓 elif (pdatas.sma[i-1] > pdatas.lma[i-1]) & (pdatas.sma[i] < pdatas.lma[i]) &(pdatas.position[i]==1): pdatas.loc[i,'flag'] = -1 pdatas.loc[i+1 ,'position'] = 0 priceout.append([pdatas.DateTime[i],pdatas.loc[i,'CLOSE']]) # 其他情况,保持之前仓位不变 else: pdatas.loc[i+1,'position'] = pdatas.loc[i,'position'] p1 = pd.DataFrame(pricein,columns = ['datebuy','pricebuy']) p2 = pd.DataFrame(priceout,columns = ['datesell','pricesell']) transactions = pd.concat([p1,p2],axis = 1) pdatas = pdatas.loc[max(0,win_long):,:].reset_index(drop = True) pdatas['ret'] = pdatas.CLOSE.pct_change(1).fillna(0) pdatas['nav'] = (1 + pdatas.ret*pdatas.position).cumprod() pdatas['benchmark'] = pdatas.CLOSE/pdatas.CLOSE[0] stats,result_peryear = performace(transactions,pdatas) return stats,result_peryear,transactions,pdatas


说明

  1. lma,sma为通过收盘价计算的均线,position是持仓标记,flag是开仓标记;
  2. 策略考虑了止损,超出阈值lossratio止损,默认情况为不止损,设置lossratio = 0.01对应止损率1%,即下跌超过1%平仓;
  3. transcations中记录每笔交易的买卖价格和日期,用于统计胜率;
  4. performance函数为策略评价函数;
  5. 没有考虑手续费;


评价函数

def performace(transactions,strategy): # strategy = pdatas.copy(); N = 250   # 年化收益率 rety = strategy.nav[strategy.shape[0] - 1]**(N/strategy.shape[0]) - 1  # 夏普比 Sharp = (strategy.ret*strategy.position).mean()/(strategy.ret*strategy.position).std()*np.sqrt(N)   # 胜率 VictoryRatio = ((transactions.pricesell - transactions.pricebuy)>0).mean() DD = 1 - strategy.nav/strategy.nav.cummax() MDD = max(DD)   # 策略逐年表现  strategy['year'] = strategy.DateTime.apply(lambda x:x[:4]) nav_peryear = strategy.nav.groupby(strategy.year).last()/strategy.nav.groupby(strategy.year).first() - 1 benchmark_peryear = strategy.benchmark.groupby(strategy.year).last()/strategy.benchmark.groupby(strategy.year).first() - 1  excess_ret = nav_peryear - benchmark_peryear result_peryear = pd.concat([nav_peryear,benchmark_peryear,excess_ret],axis = 1) result_peryear.columns = ['strategy_ret','bench_ret','excess_ret'] result_peryear = result_peryear.T  # 作图 xtick = np.round(np.linspace(0,strategy.shape[0] - 1,7),0) xticklabel = strategy.DateTime[xtick]   plt.figure(figsize = (9,4)) ax1 = plt.axes() plt.plot(np.arange(strategy.shape[0]),strategy.benchmark,'black',label = 'benchmark',linewidth = 2) plt.plot(np.arange(strategy.shape[0]),strategy.nav,'red',label = 'nav',linewidth = 2) plt.plot(np.arange(strategy.shape[0]),strategy.nav/strategy.benchmark,'orange',label = 'RS',linewidth = 2) plt.legend() ax1.set_xticks(xtick) ax1.set_xticklabels(xticklabel)      maxloss = min(transactions.pricesell/transactions.pricebuy - 1) print('------------------------------') print('夏普比为:',round(Sharp,2)) print('年化收益率为:{}%'.format(round(rety*100,2))) print('胜率为:{}%'.format(round(VictoryRatio*100,2))) print('最大回撤率为:{}%'.format(round(MDD*100,2))) print('单次最大亏损为:{}%'.format(round(-maxloss*100,2))) print('月均交易次数为:{}(买卖合计)'.format(round(strategy.flag.abs().sum()/strategy.shape[0]*20,2)))  result = {'Sharp':Sharp, 'RetYearly':rety, 'WinRate':VictoryRatio, 'MDD':MDD, 'maxlossOnce':-maxloss, 'num':round(strategy.flag.abs().sum()/strategy.shape[0],1)}  result = pd.DataFrame.from_dict(result,orient='index').T  return result,result_peryear


说明

  1. 计算了年化收益、夏普比、最大回撤、胜率、逐年收益率、单次最大亏损等指标;
  2. 收益都用复利;


回测结果


「手把手教你」用Python写一个择时策略回测

「手把手教你」用Python写一个择时策略回测

nav为策略净值,benchmark为基准净值,RS为相对强弱曲线,可以看出,策略表现并不稳定。


transcation中记录每笔交易的买卖时点和价格

「手把手教你」用Python写一个择时策略回测


result_peryear中是策略的逐年表现情况,也并不会比基准好多少

「手把手教你」用Python写一个择时策略回测


综上,是一个完整的策略回测和评价过程,当然实际操作中还有许多需要细化的地方,仅供参考,欢迎指正!


关于Python金融量化



专注于分享Python在金融量化领域的应用。加入知识星球,可以免费获取量化投资视频资料、量化金融相关PDF资料、公众号文章Python完整源码、量化投资前沿分析框架,与博主直接交流、结识圈内朋友等。

「手把手教你」用Python写一个择时策略回测

相关文章