1. 原理

1.1 因子投资

提到量化策略,总是绕不开因子投资。自CAPM模型提出以来,因子投资不断发展壮大,成为市场广泛关注的领域。市面上的策略很大一部分都是基于各种各样的因子创造的,因子在股票和债券市场上的应用也取得了不小的成就。

到底什么是因子投资?

20世纪60年代,资本资产定价模型(Capital Asset Pricing Model)提出,揭示了资产的预期收益率(预期超额收益率)与风险之间的关系,第一次给出了资本资产定价的直观表达式。

其中Rm表示市场预期收益率,β表示市场的风险暴露。

该公式指出资产的预期超额收益率由资产对市场风险的暴露大小决定,也就是说,资产的超额预期收益率可以完全由 市场因子 解释。

随着市场异象不断出现,人们发现资产的收益率并非只由市场因子决定,还受到其他因子的影响。1976年,Ross提出了无套利定价理论,构建了多因子定价模型,表达式为:

其中λ是因子预期收益率,β是对应的因子暴露,α表示误差项。

该公式指出资产的预期收益率是由 一系列因子 及其因子暴露加上误差项决定的。而因子投资的目的就是寻找到能够解释资产收益率的因子。

既然资产预期收益率是由众多因子决定的,什么是因子?怎么寻找因子?

根据《因子投资方法与实践》一书中的定义,“一个因子描述了众多资产共同暴露的某种系统性风险,该风险是资产收益率背后的驱动力,因子收益率正式这种系统性风险的风险溢价或风险补偿,它是这些资产的共性收益。”翻译过来就是,想要作为因子,必须能够解释多个资产的收益情况,并且能够带来正收益。

再来看式2,可以发现,资产预期收益率是由两部分组成的,除了λ以外,还有一个α项,称之为误差项,表示资产预期收益率中λ无法解释的部分。α的出现可能有以下两个原因,一种是因为模型设定错误,右侧遗漏了重要的因子;一种是由于选用样本数据可能存在一定偏差,导致在该样本数据下出现了α项。

为了确定α的出现是哪种原因,需要利用统计检验进行判断。

如果α显著为零,说明α的出现只是偶然,并不能说明定价模型存在错误;
如果α显著为零,说明α的出现只是偶然,并不能说明定价模型存在错误;

如果α显著不为零,说明资产预期收益里尚存在定价模型未能完全解释的部分。这种情况,就成为 异象
因此,因子大体上可分为两种,一种是 定价因子 ,也就是λ部分;一种是 异象因子 ,也就是α部分。

1.2 规模因子

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

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

2. 策略逻辑

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

回测期:2005-01-01 到 2020-10-01
股票池:所有A股股票
回测初始资金:100万

3. 策略代码

# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from gm.api import *
from datetime import timedelta
小市值策略
本策略每个月触发一次,计算当前沪深市场上市值最小的前30只股票,并且等权重方式进行买入。
对于不在前30的有持仓的股票直接平仓。
回测时间为:2005-01-01 08:00:00 到 2020-10-01 16:00:00 
def init(context):
    # 每月第一个交易日的09:40 定时执行algo任务(仿真和实盘时不支持该频率)
    schedule(schedule_func=algo, date_rule='1m', time_rule='09:40:00')
    # 使用多少的资金来进行开仓。
    context.ratio = 0.8
    # 定义股票池数量
    context.num = 30
    # 通过get_instruments获取所有的上市股票代码
    context.all_stock = get_instruments(exchanges='SHSE, SZSE', sec_types=[1], skip_suspended=False,
                                skip_st=False, fields='symbol, listed_date, delisted_date',
                                df=True)
def algo(context):
    # 获取筛选时间:date1表示当前日期之前的100天,date2表示当前时间
    date1 = (context.now - timedelta(days=100)).strftime("%Y-%m-%d %H:%M:%S")
    date2 = context.now.strftime("%Y-%m-%d %H:%M:%S")
    # 上市不足100日的新股和退市股和B股
    code = context.all_stock[(context.all_stock['listed_date'] < date1) & (context.all_stock['delisted_date'] > date2) &
                     (context.all_stock['symbol'].str[5] != '9') & (context.all_stock['symbol'].str[5] != '2')]
    # 剔除停牌和st股
    df_code = get_history_instruments(symbols=code['symbol'].to_list(), start_date=date2, end_date=date2, df=True)
    df_code = df_code[(df_code['is_suspended'] == 0) & (df_code['sec_level'] == 1)]
    # 获取所有股票市值
    fundamental = get_fundamentals_n('trading_derivative_indicator', df_code['symbol'].to_list(),
                                     context.now, fields='TOTMKTCAP', order_by='TOTMKTCAP', count=1, df=True)
    # 对市值进行排序(升序),并且获取前30个。 最后将这个series 转化成为一个list即为标的池
    trade_symbols = fundamental.reset_index(
        drop=True).loc[:context.num - 1, 'symbol'].to_list()
    print('本次股票池有股票数目: ', len(trade_symbols))
    # 计算每个个股应该在持仓中的权重
    percent = 1.0 / len(trade_symbols) * context.ratio
    # 获取当前所有仓位
    positions = context.account().positions()
    # 平不在标的池的仓位
    for position in positions:
        symbol = position['symbol']
        if symbol not in trade_symbols:
            order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,
                                 position_side=PositionSide_Long)
            print('市价单平不在标的池的', symbol)
    # 将标中已有持仓的和还没有持仓的都调整到计算出来的比例。
    for symbol in trade_symbols:
        order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,
                             position_side=PositionSide_Long)
        print(symbol, '以市价单调整至权重', percent)
if __name__ == '__main__':
    strategy_id策略ID,由系统生成
    filename文件名,请与本文件名保持一致
    mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
    token绑定计算机的ID,可在系统设置-密钥管理中生成
    backtest_start_time回测开始时间
    backtest_end_time回测结束时间
    backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
    backtest_initial_cash回测初始资金
    backtest_commission_ratio回测佣金比例
    backtest_slippage_ratio回测滑点比例
    run(strategy_id='13a64e72-e900-11eb-b05f-309c2322ba62',
        filename='main.py',
        mode=MODE_BACKTEST,
        token='2b62e7651c9897d0cdd4a6cd818a7ba8488af710',
        backtest_start_time='2005-01-01 08:00:00',
        backtest_end_time='2020-10-01 16:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=1000000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001)

4. 回测结果和稳健性分析

设定初始资金100万,手续费率为0.01%,滑点比率为0.01%。回测结果如图所示:

回测期累计收益率为447.16%,年化收益率为28.38%,沪深300指数收益率为366.77%,策略整体跑赢指数。
为了检验策略的稳健性,改变回测期和标的股票数量,得到结果如下:

从长期来看,小市值策略能够带来一定的收益,但同时也伴随着较大的回撤水平。
从短期来看,策略收益跑输大盘。收益率低,回撤小,整体效益较差。

注:本文来自掘金量化教程

20世纪60年代,资本资产定价模型(Capital Asset Pricing Model)提出,揭示了资产的预期收益率(预期超额收益率)与风险之间的关系,第一次给出了资本资产定价的直观表达式。其中Rm表示市场预期收益率,β表示市场的风险暴露。该公式指出资产的预期超额收益率由资产对市场风险的暴露大小决定,也就是说,资产的超额预期收益率可以完全由。
前言:在Barra的10个风格因子中,size( 市值 )因子引起了很多人的关注。其中就包括著名的小 市值 因子。 有的人将小 市值 股票 定义为,按照 市值 排序,后50%的 股票 是小 市值 股票 。 而本文中,将 股票 按照每日收盘价的 市值 排序,令后30%的 股票 是小 市值 股票 。 设计一个简单的投资 策略 ,检验小 市值 因子的有效性。 每日收盘前,以收盘价等权重买入当日流通 市值 最小的30% 股票 。 第二日收盘前,立刻卖出前一日的 股票 仓...
随着 量化 投资在国内的兴起,越来越多的人开始研究 量化 投资。可其中有不少人在学习代码、研究 策略 的过程中败下阵来,但 量化 投资其实也可以很简单。 今天,我们以经典的小 市值 因子 策略 为例,为大家演示如何借助掘金 量化 终端(以下简称“掘金终端”)入门 量化 投资! 开始编写前,先确认我们的交易标的、交易时间以及交易逻辑,这里设置如下: 交易标的:全市场A股 股票 (剔除停牌、ST股、次新股) 交易时间:每月第一个交易日,调仓换股 交易逻辑:等权买入 市值 最小的N只 股票 接着,打开掘金终端,在“ 量化 研究”的板块下新建一个 策略
近期在学习数据分析,在课程最后老师讲了一下通过 量化 分析选择 股票 的案例,感觉挺有意思的,恰好周围也有人在炒 股票 ,干脆自己做一个软件来实践一下学到的知识。课程上主要用 python 相关库来处理比特币的数据,数据量也不大,但是理解原理之后我们可以举一反三。 首先来回顾一下主要的知识点,选择 股票 的时候会用到两个重要的指标RSV、KDJ。他们的定义见下面的课件截图,具体的内容我就不阐述了,因为我是非金融专业的,对这些词汇解释起来有点吃力。我们只要记住这两个指标如何计算,以及后面如何使用即可 KDJ指标定义
很抱歉,作为一个 语言 模型,我并不能为您编写完整的代码。但是,我可以提供一些指导,帮助您实现选股的功能。 首先,您需要从数据源获取 股票 的历史数据,例如 股票 的价格,成交量等。可以使用如pandas这样的数据处理库来帮助您读取和处理数据。 接下来,您需要编写一些选股 策略 。例如,您可以使用均线 策略 ,即选择近期价格移动平均值(例如20日移动平均值)大于长期价格移动平均值(例如200日移动平均值)的 股票
Python 股票 量化 分析是一种利用 Python 编程 语言 进行 股票 交易分析的方法。它利用 Python 的数据处理和统计分析能力,结合各种金融数据源,对 股票 市场进行深入分析和预测,以实现更高的投资回报。 Python 股票 量化 分析通常包含以下步骤: 1. 数据收集:利用 Python 爬虫技术,从各种金融数据源(如雅虎财经、东方财富等)获取 股票 数据,包括 股票 价格、成交量、 市值 等。 2. 数据清洗:对获取的数据进行清洗和预处理,去除错误数据和异常值,使数据更加准确可靠。 3. 数据分析:利用 Python 的数据分析和统计分析库,对 股票 市场进行深入分析,包括技术分析(如均线、MACD等)、基本面分析(如财务报表分析)、市场情绪分析等。 4. 策略 设计:根据分析结果,设计适合自己的交易 策略 ,包括买入卖出时机、止损止盈等。 5. 回测模拟:利用 Python 的模拟交易框架,对 策略 进行回测模拟,评估 策略 的有效性和稳定性。 6. 实盘交易:根据回测结果,进行实盘交易,实现投资回报。 Python 股票 量化 分析是一种高效、准确、可靠的 股票 交易分析方法,尤其适合对 股票 市场进行深入研究和预测的投资者。