三分钟入门量化(九):小市值策略(本地)

hello,我是毛豆。本系列用最精简的代码和案例带你快速入门量化,只讲最干的干货,想要学习量化又不知道该如何上手的小伙伴赶紧看过来!

前期回顾:

三分钟入门量化(一):行情数据获取&绘制k线图

三分钟入门量化(二):Tushare Pro数据接口介绍

三分钟入门量化(三):计算收益率

三分钟入门量化(四):行情数据统计分析

三分钟入门量化(五):收益率的推断统计

三分钟入门量化(六):相关性分析

三分钟入门量化(七):回归分析

三分钟入门量化(八):资本资产定价模型

自CAPM模型提出以来,因子模型不断发展壮大,小市值策略正是其中最简单、最经典的模型。小市值策略采用了市值因子,其思路是投资市场上市值最小的那一批股票。一般来说,小市值的公司股票价格相对较低,但是具有较高的成长性和投资价值。

小市值策略在很长一段时间内表现非常好,但任何因子如果被大量使用,其收益都会被不断稀释,因此最近几年小市值策略的收益也大不如前。

本期内容将介绍如何用python在本地实现小市值策略。毛豆在每周末都会更新这个系列,建议大家收藏起来方便学习。

小市值策略本地实现

假定策略每个月初筛选出市值在20-30亿的股票,然后全仓买入其中市值最小的10只股票,月底(以20天为一个周期)全部卖出,并再次选择市值最小的10只股票买入,如此循环往复。我们以今年以来的行情为例,看看策略的收益如何。

首先导入相关的包,并认证Tushare Pro账号。

import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
​
​pro = ts.pro_api('your token')

获取今年以来的交易日历:

df = pro.trade_cal(start_date='20230101', end_date='20230708')
trade_date_list=list(df.cal_date)

如果tushare积分不够调用trade_cal接口,可以用如下方式获取:

df_sh=ts.get_k_data('sh',start='2023-01-01',end='2023-07-08')#上证指数
trade_date_list=list(df_sh.date)

我们先以一个月为例,实现市值选股逻辑与当月收益率计算。每只股票的市值数据可以用bak_daily接口获取。

#设定每一期的持仓时间,假定每20天调仓换股
#期初
adj_date_start_raw=trade_date_list[0]
adj_date_start=''.join(adj_date_start_raw.split('-'))
#期末
adj_date_end_raw=trade_date_list[0+19]
adj_date_end=''.join(adj_date_end_raw.split('-'))
#筛选出总市值在20-30之间,市值最小的10只个股
df_start=pro.bak_daily(trade_date=adj_date_start)
df_start=df_start.loc[(df_start['total_mv']>=20) & (df_start['total_mv']<=30)]
df_start=df_start.sort_values(by='total_mv')[:10]
#计算一期的收益率
security_ret_dict={}#持股期间收益率字典
​df_info=pd.DataFrame()#持股信息
for k,v in df_start.iterrows():
    df_end=pro.daily(ts_code=v.ts_code,trade_date=adj_date_end)#获取期末股价
    ret=(df_end['close'].values[0]-v.close)/v.close#持股期间收益率=(期末股价-期初股价)/期初股价
    info=[v.trade_date,adj_date_end,v.ts_code,v['name'],v.total_mv,v.close,df_end['close'].values[0],ret]
    df_info=pd.concat([df_info,pd.DataFrame(info).T])
    security_ret_dict[v.ts_code]=ret
df_info.rename(columns={0:'开仓日期',1:'清仓日期',2:'股票代码',3:'股票名称',4:'期初市值',5:'期初股价',6:'期末股价',7:'本期收益'},inplace=True)
print('{}-{} 平均收益率:{}'.format(adj_date_start,adj_date_end,np.mean(list(security_ret_dict.values()))))
df_info

打印如下:

一月份策略恰好选中了年初的妖股通达动力,其单月股价翻倍,因此本月的收益达到14.9%,非常高,但有一定的运气成分。

以此类推,我们可以写一个循环来计算每个月的收益率。

#计算多期的收益率
#设定每一期的持仓时间,假定每20天调仓换股
date_ret_dict={}#存放每一期收益
for i in range(0,len(trade_date_list),20):
    try:
        #期初日期
        adj_date_start_raw=trade_date_list[i]
        adj_date_start=''.join(adj_date_start_raw.split('-'))
        #选股
        df_start=pro.bak_daily(trade_date=adj_date_start)
        df_start=df_start.loc[(df_start['total_mv']>=20) & (df_start['total_mv']<=30)]
        df_start=df_start.sort_values(by='total_mv')[:10]
        #期末日期
        adj_date_end_raw=trade_date_list[i+19]
        adj_date_end=''.join(adj_date_end_raw.split('-'))
        #计算当期收益
        security_ret_dict={}#持股期间收益率字典
        df_info=pd.DataFrame()#持股信息
        for k,v in df_start.iterrows():
            df_end=pro.daily(ts_code=v.ts_code,trade_date=adj_date_end)#获取期末股价
            ret=(df_end['close'].values[0]-v.close)/v.close#持股期间收益率=(期末股价-期初股价)/期初股价
            security_ret_dict[v.ts_code]=ret
        print('{}-{} 平均收益率:{}'.format(adj_date_start,adj_date_end,np.mean(list(security_ret_dict.values()))))
        #将当期收益保存在字典中
        date_ret_dict[adj_date_end]=np.mean(list(security_ret_dict.values()))
        time.sleep(20)
    except:
        break

打印如下:

绘制收益曲线:

#累计收益率
total_ret=1#初始累计收益率
total_ret_list=[]#每期结束后统计累计收益率
for date,ret in date_ret_dict.items():
    total_ret=total_ret*(1+ret)
    total_ret_list.append(total_ret)
    #print(date,total_ret)
#解决中文乱码
plt.rcParams['font.sans-serif']=['Arial Unicode MS']#用于mac
#plt.rcParams['font.sans-serif']=['SimHei']#用于windows
plt.rcParams['axes.unicode_minus'] = False
#可视化
plt.figure(figsize=(8,5))
ax=plt.subplot(1,1,1)
plt.plot(total_ret_list)
plt.xticks(np.arange(0,len(total_ret_list)))
ax.set_xticklabels(date_ret_dict.keys(),rotation=45)
plt.title('累计收益率')
plt.savefig('fig1.png',dpi=400,bbox_inches='tight')

返回如下:​

可以看到,该策略半年以来收益接近20%,还是挺不错的。

当然,这样的计算方式比较粗糙,有很多问题没有考虑到,比如每只股仓位不可能完全一样,没有考虑到交易手续费、滑点等等问题。如果想要更精准地计算策略的收益,我们可以利用第三方量化平台来做策略回测,毛豆将在下一期教程中介绍。

以上是今天的全部干货内容,毛豆会在每周末更新这个系列,也会在每个交易日继续和大家分享旋风冲锋量化策略的实盘情况,欢迎大家点赞关注。

猜你喜欢

转载自blog.csdn.net/weixin_37475278/article/details/131610589