前言

本篇是量化系列的第一篇文章。《量化十万个为什么》系列旨在讨论一些自己心中的疑问,并且通过尝试解答这些问题来提升自己对于市场的认知水平。

PS:博主水平很辣鸡,请大家轻喷,多多指教!

一、为什么提这个问题?

对于一个策略来说,到底持仓多久才是比较合适的?这个恐怕是一个挺难回答的问题,那我们是否可以反向来看一看,到底超越指数的分位数到底是多少呢?

二、分析

我们选取2018年至2020年的股票数据,以沪深300作为基准,看一看持仓不同的天数,跑赢基准的概率是多少。

# 先获取股票

start_date = '20180101'

end_date = '20201231'

year_lst = assistant.GetinnerYearLst(start_date=start_date,end_date=end_date)

data_dic = assistant.ReadDayBarYear(year_lst=year_lst)

# 从 tushare 上获取 沪深300 数据

benchmark_df = pro.index_daily(ts_code='399300.SZ', start_date=start_date, end_date=end_date)

benchmark_df = benchmark_df.sort_values(by='trade_date').reset_index(drop=True)

benchmark_date_se = pd.to_datetime(benchmark_df['trade_date'].astype(str))

benchmark_date_se.name = 'datetime'

benchmark_df.index = benchmark_date_se

# 选取持仓天数为 1,2,3,5,10,20,30

test_day_num_lst = [1,2,3,5,10,20,30]

answer_dic = {}

for past_day_num in test_day_num_lst:

benchmark_price = benchmark_df['close']

benchmark_return = (benchmark_price - benchmark_price.shift(past_day_num))/benchmark_price.shift(past_day_num)

total_answer_df = pd.DataFrame(index=benchmark_date_se)

for stock_name in data_dic.keys():

stock_df = copy.copy(data_dic[stock_name])

close_price = stock_df['Close']*stock_df['Adj_Factor']

stock_return = (close_price - close_price.shift(past_day_num))/close_price.shift(past_day_num)

# 把结果合并比较

tmp_df = pd.DataFrame(columns=['result','stockreturn','bmreturn'],index=benchmark_date_se)

tmp_df['bmreturn'] = benchmark_return

tmp_df.loc[stock_return.index,'stockreturn'] = stock_return

stock_higher_index = tmp_df[tmp_df['stockreturn'] > tmp_df['bmreturn']].index

stock_lower_index = tmp_df[tmp_df['bmreturn'] > tmp_df['stockreturn']].index

tmp_df.loc[stock_higher_index,'result'] = 1

tmp_df.loc[stock_lower_index,'result'] = 0

total_answer_df[stock_name] = tmp_df['result']

total_merge_df = copy.copy(total_answer_df).T

tmp_se = total_merge_df.fillna(0).sum()/(len(total_merge_df) - total_merge_df.isnull().sum())

answer_dic.update({past_day_num:tmp_se})

我们来看一下结果:

先看看持仓一天的情况

看上去基本上是一个稳定的随机数列

其分布如下图:

均值为 0.4572 ,方差为 0.1716,所以实际上对于A股来说,随便取一只股票,持仓一天,都会有45%的概率跑赢沪深300。

持有5天的情况和1天的情况类似,分布如下图

但是,随着持仓时间的增加,概率出现了某种周期性

可以看到,30天的持仓,似乎出现了某种周期?可以看到30日持仓的周期为5-6个月。我们结合指数看看都发生了什么事

结合沪深300的走势图来看,似乎处于周期底部之后,沪深300会下跌(和沪深300走势呈负相关)?但是似乎周期的时机抓得不是特别好?我们换一个持仓20个交易日的情况来看

效果也似乎不是特别的好,我们换回持仓30个交易日的数据,求diff之后,再和指数未来一天的return求相关性。

se = answer_dic[30].diff()

bm_furt = (benchmark_price.shift(-1) - benchmark_price)/benchmark_price

pd.DataFrame({'Dif':se,'BmFurt':bm_furt}).corr()

可以看到相关性大约有-0.06,其实还是有一些关系的。也许可以做一个股指期货的因子?

最后我们来看一下不同的持仓周期跑赢指数的概率均值是多少

for k in answer_dic.keys():

print(k,answer_dic[k].mean(),answer_dic[k].std())

结果如下:

持仓周期均值方差1 日0.4570.1722 日0.4510.1753 日0.4480.1775 日0.4420.17710 日0.4340.17320 日0.4240.17530 日0.4170.17总结

由上面的表格可以看出,方差总体上都差不多,实际上即使拉长了持仓周期,获得超额收益的概率也并没有降低很多,从45.7%变为41.7%,即为任何持仓周期下,跑赢沪深300的概率都差不多。