从小市值因子策略入手,带你入门量化投资 (附年化收益率77.83%策略)

随着量化投资在国内的兴起,越来越多的人开始研究量化投资。可其中有不少人在学习代码、研究策略的过程中败下阵来,但量化投资其实也可以很简单。

今天,我们以经典的小市值因子策略为例,为大家演示如何借助掘金量化终端(以下简称“掘金终端”)入门量化投资!

开始编写前,先确认我们的交易标的、交易时间以及交易逻辑,这里设置如下:

  • 交易标的:全市场A股股票(剔除停牌、ST股、次新股)
  • 交易时间:每月第一个交易日,调仓换股
  • 交易逻辑:等权买入市值最小的N只股票


接着,打开掘金终端,在“量化研究”的板块下新建一个策略。

点击后,弹出策略模板,其中最左侧可选择编程语言,支持Python、C++、C#和Matlab,此处默认为Python。

第二栏为策略模板类型,可以选择“空策略”、“事件驱动”、“数据研究”或者示例策略等,这里我们选择“定时任务”模板;

右侧为策略名称及其代码,将名称修改为“小市值因子策略”并确认,随后点击“策略编辑”即可进入策略编辑页面。


这里为大家介绍下基本的策略编程框架。

策略编程界面如下图所示,左侧为策略文件,即资源管理器,在这里可以获取本策略的存储地址,右侧为main.py文件的内容,也是本策略的主文件。

文件主要包含四大内容:

  • 策略模块:本策略所需的模块;
  • 策略初始化:初始化init()函数仅在策略刚开始运行时运行一遍;
  • 策略主体:策略逻辑的实现;
  • 策略基础参数:可调整回测的起始时间、复权方式、初始资金、佣金费率和滑点等。

了解框架后,我们开始编写策略。


1、调整策略基础参数;

策略的回测区间修改为2021年至今(2021-01-01 08:00:00至2022-02-17 16:00:00)。

策略资金改为100W,其余参数基于默认参数,暂不做修改。

PS:''' '''为区域注释,用于注释内容,便于程序编写与阅读。


2、修改策略初始化;

 Schedule()函数为定时任务配置函数,可以指定时间自动执行策略算法,其中schedule_func参数指定目标定时函数,date_rule参数设定定时频率,time_rule参数设定函数的具体执行时间。

在此我们设定为1个月(date_rule=1m),具体时间为09:30:00(time_rule=09:30:00)。定义一个股票池数量的变量:context.num = 10


3、设计策略主体逻辑;

1)获取全A股票代码:

我们可以通过掘金SDK中的get_instrumentinfos()函数查询交易标的基本信息,以此获取股票代码;该函数中的sec_types参数,可以指定股票、期货、基金可转债等标的类别。

# 获取当前全A股票代码
symbol_info = get_instrumentinfos(sec_types=SEC_TYPE_STOCK, fields='symbol,listed_date,delisted_date', df=True)

2)剔除高风险可交易股票(退市股、未上市股票、ST股票、停牌股、B股):

在上述函数中,我们进一步获取了股票代码(symbol)、上市日期(listed_date)和退市日期(delisted_date)。将回测的当前时间context.now与上市日期、退市日期做比较,可以剔除退市股和未上市股票。

# 剔除未上市、已退市的股票
symbol_info = symbol_info[(symbol_info['listed_date']<context.now) & (symbol_info['delisted_date']>context.now)] 

3)剔除ST股票、停牌股:

掘金终端已经将这列信息集成在get_history_instruments()函数,在返回的数据中心,sec_level=1代表正常状态,sec_level=2代表ST股,is_suspended=0表示非停牌股票。

 # 剔除ST股票、停牌股
symbol_info = get_history_instruments(symbols=list(symbol_info['symbol']), start_date=context.now, end_date=context.now, fields='symbol,sec_level,is_suspended', df=True)
symbol_info = symbol_info[(symbol_info['sec_level']==1) & (symbol_info['is_suspended']==0)]

4)剔除B股股票:

这里可以直接通过过股票代码来判断,其中B类股票是以9和2开头的。

# 剔除B股
symbols = [code for code in list(symbol_info['symbol']) if code[:6]!='SHSE.9' and code[:6]!='SZSE.2']

5)获取标的股票市值,并按升序排序:

这里就要用到股票的基本面数据了,掘金终端的get_fundamentals_n()函数提供了基本面数据查询功能。在财务数据文档中查询所需要的基本面数据,这里总市值为’TOTMKTCAP’字段,再将该字段所在的表名、待查询的股票代码、查询时间和查询数量填入该函数,即可方便地获取股票市值。

排序功能以sort_values()实现,默认为从小到大排序。

# 获取所有股票市值,并按升序排序
fundamental = get_fundamentals_n(table='trading_derivative_indicator',symbols=symbols,end_date=last_date,count=1,fields='TOTMKTCAP',df=True).sort_values(by='TOTMKTCAP')

6)获取上一个交易日:

在上述函数中,我们需要在盘前获取股票市值的数据,为此需要先查询上一个交易日的日期。这里我们使用get_previous_trading_date()函数,就能便捷地获取指定日期的上一个交易日。

# 上一交易日
last_date = get_previous_trading_date(exchange='SZSE', date=context.now)

7)获取最小市值的前N只股票:

由于前文获取了从小到大排序的市值数据,所以此处仅需截取该数据的前N只股票即可,调用初始化函数中设置的股票数量context.num。

# 获取前N只股票
to_buy = list(fundamental.iloc[:context.num,:]['symbol'])
print('本次股票池有股票数目: ', len(to_buy))

8)交易逻辑_买入:

获取了待买入股票池,下一步即可设置买入逻辑的程序编写。这里我们可以循环遍历股票池,逐只买入股票。

掘金提供了多种交易方式的函数,包括指定总量委托、指定价值委托、指定百分比委托等方式。由于我们是全仓等额买入股票,这里用指定百分比委托的方式更便捷。

首先,计算每只股票的权重。

# 获取股票的权重
percent = 1 / len(to_buy)

再循环买入,调用指定百分比委托order_target_percent()函数,其中order_type参数主要包括市价委托和限价委托两种方式,此处我们用市价委托OrderType_Market,同时此处为买入建仓,所以position_side参数设定为做多,PositionSide_Long。在这里,我们添加了一个buy_symbols列表变量来记录买入的股票,并打印输出。

# 买在标的池中的股票
buy_symbols = []
for symbol in to_buy:
order_target_percent(symbol=symbol,percent=percent,order_type=OrderType_Market,position_side=PositionSide_Long)
buy_symbols.append(symbol)
print('{},市价单买入股票:{}'.format(context.now,buy_symbols)

9)交易逻辑_卖出:

卖出逻辑与买入逻辑相类似,都是以循环的方式,逐只卖出股票。我们首先要获取当前持仓的股票。

# 当前持仓
positions = context.account().positions()

循环遍历持仓股,判断持仓股是否在待买入股票池中,若不在待买入股票池,则卖出该股票。

此处调用的卖出函数,用的也是指定百分比委托order_target_percent()函数,将预期该股票占总资产比例设置为0,同时订单类型设置为市价委托OrderType_Market,多仓类型PositionSide_Long。同时添加sell_symbols列表变量来记录卖出股票,并打印输出。

# 平不在标的池的股票
sell_symbols = []
for position in positions:
    symbol = position['symbol']
    if symbol not in to_buy:
       order_target_percent(symbol=symbol,percent=0,order_type=OrderType_Market,position_side=PositionSide_Long)
       sell_symbols.append(symbol)
print('{},市价单卖出股票:{}'.format(context.now,sell_symbols))

4、历史回测;

编写完策略后,我们就可以进行回测了。

在策略编辑页面,点击页面右上角的“运行回测”,掘金终端会自动弹出cmd窗口,自动运行回测,当cmd窗口中出现“请按任意键继续...”时,代表回测结束。

5、查看策略回测绩效。

当回测完成后,掘金终端会生成一份回测绩效报告。查看的方法有两种:第一种是在策略编辑界面,点击右上角的“回测历史”查看。

第二种是返回到“我的策略”页面,点击对应策略右侧的“回测次数”,即可进入“回测历史”页面,查看历史所有回测。


历史回测列表中有该回测的绩效概述,包括运行回测的时间、回测的开始日期和截止日期、回测的累计收益率、最大回测、夏普比率、回测进度、耗时和备注,及删除按钮。点击该回测,即可进入回测的详情页面,如下图:

 在回测详情页面,可以查询策略的历史回测表现,信号分析、交易明细、每日持仓等信息。那么,这次的策略表现如何呢?

从报告中可见,2021年01月01日至2022年02月17日期间,策略累计收入88.06%,最大回撤为23.43%,年化收益率为77.83%,同期的沪深300基准指数的收益率-12.12%。

策略远远跑赢市场,对比当前明星基金动辄二三十的回撤来看,小市值策略依旧稳健!

对此感兴趣的朋友,可以通过掘金社区获取策略源码自行研究~

相信通过今天的内容,大家对量化投资以及掘金终端的使用方法也有了一定的了解,下一步就自己动手,建立你的第一个量化策略吧!

- End -

欢迎下载掘金量化终端,免费使用量化投研功能。

官网:https://www.myquant.cn/

策略源码:https://bbs.myquant.cn/topic/2740

声明:本内容由掘金量化原创,仅供学习、交流、演示之用,不构成任何投资建议!如需转载请联系掘金小Q(VX:myquant2018)授权,否则作侵权处理!

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值