【量化】量化交易入门系列4:经典的量化交易策略(下)

作者:悠悠做神仙

来源: 恒生LIGHT云社区

量化交易入门系列,策略第一篇文章 量化交易入门系列2:经典的量化交易策略(上) ,介绍了经典量化策略, 均线策略 海龟交易策略 ;策略第二篇文章 量化交易入门系列3:经典的量化交易策略(中) 分享经典的交易策略-- 布林线均值回归策略 ;那么本篇将继续分享2个经典的交易策略-- 多因子选股策略 小市值策略

多因子选股策略

多因子策略是最广泛应用的策略之一。资本资产定价模型CAPM(Capital Asset Pricing Model)模型【关于CAPM模型附件会放一张比较详细的解释图,感兴趣的可以下载】的提出为股票的收益提供了解释,但随着各种市场异象的出现,使得人们发现股票存在超额收益,这种收益不能为市场因子所解释,因此,出现了多因子模型。

多因子模型最早是由Fama-French提出,包括三因子和五因子模型。

Fama-French三因子模型概述

Fama和French 1992年对美国股票市场决定不同股票回报率差异的因素的研究发现,股票的市场的beta值不能解释不同股票回报率的差异,而上市公司的市值、账面市值比、市盈率可以解释股票回报率的差异。Fama and French认为,上述超额收益是对CAPM 中β未能反映的风险因素的补偿。”

Fama-French三因子模型的表达式

Fama和French 1993年指出可以建立一个三因子模型来解释股票回报率。模型认为,一个投资组合(包括单个股票)的超额回报率可由它对三个因子的暴露来解释,这三个因子是:市场资产组合(Rm − Rf)、市值因子(SMB)、账面市值比因子(HML)。

这个多因子均衡定价模型可以表示为:

其中E[R_i]代表股票i的预期收益率,R_f代表无风险收益率,E[R_m]为市场组合预期收益率,E[R_SMB]和E[R_HML]分别为规模因子收益率和价值因子预期收益率。

为构建价值因子和规模因子,Fama选择BM和市值两个指标进行双重排序,将股票分为大市值组B和小市值组S;按照账面市值比将股票分为BM高于70%分位数的H组,BM低于30%分位数的L组,BM处于二者之间的记为M组。

如表所示: 得到上述分组以后,就可以构建规模和价值两个因子。

上述式子解释一下可以发现,规模因子是三个小市值组合的等权平均减去三个大市值组合的等权平均;价值因子是两个高BM组合的等权平均减去两个低BM组合的等权平均。

市场上常用的多因子模型包括如下几个:

模型 出处 所含因子
Fama-French三因子 Fama and Farench(1993) 市场、规模、价值
Carhart四因子 Carhart(1997) 市场、规模、价值、动量
Novy-Marx四因子 Novy-Marx(2013) 市场、规模、价值、盈利
Fama-French五因子 Fama and Farench(2015) 市场、规模、价值、盈利、投资
Hou-Xue-Zhang四因子 Hou et al 市场、规模、盈利、投资
Stambaugh-Yuan四因子 Stambaugh and Yuan(2017) 市场、规模、管理、表现
Daniel-Hirshleifer-Sun三因子 Daniel et al(2020) 市场、长周期行为、短周期行为

随着市场的发展,出现许多三因子模型难以解释的现象。因此,Fama又提出了五因子模型,加入了盈利水平、投资水平因子。

本问主要以Fama提出的三因子模型作为策略基础。

策略设计思路(假设三因子模型是完全有效的)

在用三因子模型估算股票预期收益率时,经常会发现并非每只股票都能严格吻合式1,大部分股票都会存在一个alpha截距项。当存在alpha截距项时,说明股票当前价格偏离均衡价格。基于此,可以设计套利策略。

alpha < 0时,说明股票收益率低于均衡水平,股票价格被低估,应该买入。 alpha > 0时,说明股票收益率高于均衡水平,股票价格被高估,应该卖出。

因此,可以获取alpha最小并且小于0的10只的股票买入开仓。

策略步骤

第一步:获取股票市值以及账面市值比数据。 第二步:将股票按照各个因子进行排序分组,分组方法如上表所示。 第三步:依据式2式3,计算SMB、HML因子。 第四步:因子回归,计算alpha值。获取alpha最小并且小于0的10只的股票买入开仓。

由于该策略在国外和国内存在一定的应用差异,故这里仅做介绍,对于中国版优化的三因子投资策略,可以参考文章进行了解: 中国版的 Fama-French 三因子模型,了解一下

小市值策略

小市值策略是一个相对来说比较简单的策略,如同字面意思,就是选择市值比较小的股票,进行投资。本质来讲, 市值越小的股票,那么未来上涨的概率就越大 。很多人可能对此感觉不屑一顾,其实这是经过时间验证过的一个经验策略,无论是在过去10年的A股,还是过去100年的美国股市,确实让很多人因此赚了很多钱。

在介绍了多因子选股模型后,那么其实市值也是三因子模策略的一个因子。

1981年Banz基于纽交所长达40年的数据发现,小市值股票月均收益率比其他股票高0.4%。其背后的原因可能是投资者普遍不愿意持有小公司股票,使得这些小公司价格普遍偏低,甚至低于成本价,因此会有较高的预期收益率。由此产生了小市值策略,即投资于市值较小的股票。市值因子也被纳入进大名鼎鼎的Fama三因子模型和五因子模型之中。

A股市场上规模因子是否有效?研究发现,2016年以前,A股市场上规模因子的显著性甚至超过了欧美等发达国家市场。但到了2017-2018年期间,大市值股票的表现明显优于小市值股票,使得规模因子在A股市场上的有效性存疑。

策略逻辑

第一步:确定调仓频率,以每月第一天调仓为例 第二步:确定股票池股票数量,这里假设有30支 第三步:调仓日当天获取前一个月的历史数据,并按照市值由小到大排序 第四步:买入前30支股票

回测期:2021-01-01 到 2021-12-01 股票池:所有A股股票 回测初始资金:10万

策略代码参考

'''
筛选出市值介于20-30亿的股票,选取其中市值最小的三只股票,
每天开盘买入,持有五个交易日,然后调仓。
'''

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # True为开启动态复权模式,使用真实价格交易
    set_option('use_real_price', True) 
    # 设定成交量比例
    set_option('order_volume_ratio', 1)
    # 股票类交易手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, \
                             open_commission=0.0003, close_commission=0.0003,\
                             close_today_commission=0, min_commission=5), type='stock')
    # 持仓数量
    g.stocknum = 3 
    # 交易日计时器
    g.days = 0 
    # 调仓频率
    g.refresh_rate = 5
    # 运行函数
    run_daily(trade, 'every_bar')

## 选出小市值股票
def check_stocks(context):
    # 设定查询条件
    q = query(
            valuation.code,
            valuation.market_cap
        ).filter(
            valuation.market_cap.between(20,30)
        ).order_by(
            valuation.market_cap.asc()
        )

    # 选出低市值的股票,构成buylist
    df = get_fundamentals(q)
    buylist =list(df['code'])

    # 过滤停牌股票
    buylist = filter_paused_stock(buylist)

    return buylist[:g.stocknum]
  
## 交易函数
def trade(context):
    if g.days%g.refresh_rate == 0:

        ## 获取持仓列表
        sell_list = list(context.portfolio.positions.keys())
        # 如果有持仓,则卖出
        if len(sell_list) > 0 :
            for stock in sell_list:
                order_target_value(stock, 0)

        ## 分配资金
        if len(context.portfolio.positions) < g.stocknum :
            Num = g.stocknum - len(context.portfolio.positions)
            Cash = context.portfolio.cash/Num
        else: 
            Cash = 0

        ## 选股
        stock_list = check_stocks(context)

        ## 买入股票
        for stock in stock_list:
            if len(context.portfolio.positions.keys()) < g.stocknum:
                order_value(stock, Cash)

        # 天计数加一
        g.days = 1
    else:
        g.days += 1

# 过滤停牌股票
def filter_paused_stock(stock_list):
    current_data = get_current_data()
    return [stock for stock in stock_list if not current_data[stock].paused]

模拟效果

策略收益 27.55%

策略年化收益 31.69%

超额收益 37.23%

基准收益 -7.05%

阿尔法 0.294

贝塔 0.143

小市值.jpg

不到一年的时间,在本金也不是很大的基础上,可能效果也没有很夸张,这个也取决于当前A股市场的一个情况,毕竟今年股市还是有点难做的。

最后,常说的一句话:入市有风险,投资需谨慎。本文仅供学习参考,不做任何投资指导!


想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?

恒生LIGHT云社区 ,由恒生电子搭建的金融科技专业社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。

扫描下方小程序二维码,加入我们!

猜你喜欢

转载自blog.csdn.net/weixin_44433834/article/details/122619949