量化投资策略与技术学习PART2:量化选股之风格轮动

市场上的投资者是有偏好的,有时候偏好于价值股,有时候偏好于成长股,有时偏于大盘,有时又偏于小盘,由于投资者的这种不同的交易行为,形成了市场风格,本节主要研究如何判断市场风格,以及如何利用风格的轮动构建投资策略以获取超额收益。

一、基本概念

投资风格是针对股票市场而言,只投资于某类具有共同收益特征或共同价格行为的股票,由于投资风格的存在,从而产生一种叫做风格动量的效应,即在过去较短时期内收益率较高的股票,在未来的中短期收益也较高。
市场的有效性程度不是一成不变的,会随着时间不断变化,也就是说,追逐这些市场失效现象能获取超额投资收益。所以风格投资从本质上来说是通过执行各种投资决策,从某些特定分割的市场或从某类错误定价的股票中获得超额收益。

1、风格鉴别方法

国外投资风格鉴别技术一般可分为两种,一种是持股特征基础的投资风格鉴别方法,包括晨星公司的风格箱法、罗素公司的风格分类系统等;另一种是收益率基础的投资风格鉴别法,如夏普的鉴别方法等。

(1)持股基础鉴别法

晨星风格箱法是一个3*3的矩阵,从大盘和小盘、价值型和成长型来对基金风格进行划分,介于大盘和小盘之间的为中盘,介于价值型和成长型之间的为混合型,共有9种风格

价值型混合型成长型
大盘大盘价值大盘混合大盘成长
中盘中盘价值中盘混合中盘成长
小盘小盘价值小盘混合小盘成长

(1)规模指标:市值。通过比较基金持有股票的市值中值来划分,市值中值小于10亿美金为小盘;大于50亿美金为大盘,10~50亿美金为中盘。
(2)估值指标:平均市盈率、平均市净率。基金所持有股票的市盈率、市净率用基金投资于该股票的比例加权求平均,然后把两个加权指标和标普500成分股的市盈率、市净率的相对比值相加,对于标普500来说,这个比值和是2.如果最后所得比值和小于1.75,则为价值型,大于2.25为成长型,介于1.75~2.25之间为混合型。

(2)夏普收益率基础的投资风格鉴别

(1)将标普500指数成分股按净市比(B/P)排序分为两类,分界点是两类股票的总市值大小一样,高B/P的股票为价值股,其余为成长股,更新频次是6个月。
(2)将非标普500指数成分股按照市值高低分为两类,从高到底排序后总市值前80%的股票为中市值股,剩下的则为小市值股

股票风格
标普500成分股价值股/成长股
非标普500成分股中市值股/小市值股

二、策略模型

(1)传统的风格预测方法

实施风格轮换策略,在不同的风格类别之间进行切换,需要对各类风格的收益特征有较好的把握和对未来走势有较准确的判断。风格评估和预测的方法可分为相对价值法和场景预测法两类。

(2)风格轮动的定量预测

由于市场风格轮动,保持单一的投资风格并不一定是最佳的投资策略,积极的风格转换策略有助于提高投资业绩,风格轮动主要涉及两个问题,即在何时进行风格转换,以及风格转换能够弥补交易成本。

3、中国市场风格投资的特点

(1)积极的风格管理能创造出超额收益

1、如果一个投资者能偶准确进行风格选时,就能创造出显著的超额收益;
2、进行大盘/小盘风格选时潜在获利能力强于价值/成长;
3、对大盘/小盘轮动的选时频率可以频繁进行,一年内可以多次进行,但价值/成长轮动频繁转换意义不大,适合进行年度或者更长时间周期的选时即轮动;

(2)建立风格选时的量化模型,操作难度较大

虽然通过运用支持向量机方法可以进行风格选时的预测,但结果差强人意,主要原因如下:
1、中国股市与宏观经济指标的关联性差;
2、数据来源受限,无法得到一些风格指数的成分数据。

(3)风格动量效应不明显,持续时间短
(4)中期风格反转效应较明显

3个月的风格效应容易出现反转,即密切观测以3个月为一个周期的风格动量具有比较强的现实意义。对于积极风格管理者来说,不妨以三个月为周期进行风格反转操作,建议持有期在3个月以上。

(5)积极风格管理的适用对象为中短期投资者,长期的风格收益差,而且风格动量并不十分明显。

三、实战演习

掘金量化终端中有现成的程序,其策略如下:
以上证50、沪深300、中证500作为市场三个风格的代表,每次选取表现做好的一种风格,买入其成分股中最大市值的N只股票,每月月初进行调仓换股。
我们便以此为基础看一下风格轮动策略的收益如何
测试代码如下:

# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from gm.api import *import datetime
import numpy as np
import pandas as pd'''
示例策略仅供参考,不建议直接实盘使用。风格轮动策略
逻辑:以上证50、沪深300、中证500作为市场三个风格的代表,每次选取表现做好的一种风格,买入其成分股中最大市值的N只股票,每月月初进行调仓换股
'''def init(context):# 待轮动的风格指数(分别为:上证50、沪深300、中证500)context.index = ['SHSE.000016', 'SHSE.000300', 'SZSE.399625']# 用于统计数据的天数context.days = 20# 持股数量context.holding_num = 10# 每日定时任务schedule(schedule_func=algo, date_rule='1d', time_rule='09:30:00')def algo(context):# 当天日期now_str = context.now.strftime('%Y-%m-%d')# 获取上一个交易日last_day = get_previous_n_trading_dates(exchange='SHSE', date=now_str, n=1)[0]# 判断是否为每个月第一个交易日if context.now.month != pd.Timestamp(last_day).month:return_index = pd.DataFrame(columns=['return'])# 获取并计算指数收益率for i in context.index:return_index_his = history_n(symbol=i, frequency='1d', count=context.days + 1, fields='close,bob',fill_missing='Last', adjust=ADJUST_PREV, end_time=last_day, df=True)return_index_his = return_index_his['close'].valuesreturn_index.loc[i, 'return'] = return_index_his[-1] / return_index_his[0] - 1# 获取指定数内收益率表现最好的指数sector = return_index.index[np.argmax(return_index)]print('{}:最佳指数是:{}'.format(now_str, sector))# 获取最佳指数成份股symbols = list(stk_get_index_constituents(index=sector, trade_date=last_day)['symbol'])# 过滤停牌的股票stocks_info = get_symbols(sec_type1=1010, symbols=symbols, trade_date=now_str, skip_suspended=True,skip_st=True)symbols = [item['symbol'] for item in stocks_info ifitem['listed_date'] < context.now and item['delisted_date'] > context.now]# 获取最佳指数成份股的市值,选取市值最大的N只股票fin = stk_get_daily_mktvalue_pt(symbols=symbols, fields='tot_mv', trade_date=last_day, df=True).sort_values(by='tot_mv', ascending=False)to_buy = list(fin.iloc[:context.holding_num]['symbol'])# 计算权重percent = 1.0 / len(to_buy)# 获取当前所有仓位positions = get_position()# 平不在标的池的股票(注:本策略交易以开盘价为交易价格,当调整定时任务时间时,需调整对应价格)for position in positions:symbol = position['symbol']if symbol not in to_buy:# 开盘价(日频数据)new_price = \history_n(symbol=symbol, frequency='1d', count=1, end_time=now_str, fields='open', adjust=ADJUST_PREV,adjust_end_time=context.backtest_end_time, df=False)[0]['open']# # 当前价(tick数据,免费版本有时间权限限制;实时模式,返回当前最新 tick 数据,回测模式,返回回测当前时间点的最近一分钟的收盘价)# new_price = current(symbols=symbol)[0]['price']order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Limit,position_side=PositionSide_Long, price=new_price)# 买入标的池中的股票(注:本策略交易以开盘价为交易价格,当调整定时任务时间时,需调整对应价格)for symbol in to_buy:# 开盘价(日频数据)new_price = \history_n(symbol=symbol, frequency='1d', count=1, end_time=now_str, fields='open', adjust=ADJUST_PREV,adjust_end_time=context.backtest_end_time, df=False)[0]['open']# # 当前价(tick数据,免费版本有时间权限限制;实时模式,返回当前最新 tick 数据,回测模式,返回回测当前时间点的最近一分钟的收盘价)# new_price = current(symbols=symbol)[0]['price']order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Limit,position_side=PositionSide_Long, price=new_price)def on_order_status(context, order):# 标的代码symbol = order['symbol']# 委托价格price = order['price']# 委托数量volume = order['volume']# 目标仓位target_percent = order['target_percent']# 查看下单后的委托状态,等于3代表委托全部成交status = order['status']# 买卖方向,1为买入,2为卖出side = order['side']# 开平仓类型,1为开仓,2为平仓effect = order['position_effect']# 委托类型,1为限价委托,2为市价委托order_type = order['order_type']if status == 3:if effect == 1:if side == 1:side_effect = '开多仓'else:side_effect = '开空仓'else:if side == 1:side_effect = '平空仓'else:side_effect = '平多仓'order_type_word = '限价' if order_type == 1 else '市价'print('{}:标的:{},操作:以{}{},委托价格:{},委托数量:{}'.format(context.now, symbol, order_type_word, side_effect,price, volume))def on_backtest_finished(context, indicator):print('*' * 50)print('回测已完成,请通过右上角“回测历史”功能查询详情。')if __name__ == '__main__':'''strategy_id策略ID,由系统生成filename文件名,请与本文件名保持一致mode实时模式:MODE_LIVE回测模式:MODE_BACKTESTtoken绑定计算机的ID,可在系统设置-密钥管理中生成backtest_start_time回测开始时间backtest_end_time回测结束时间backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POSTbacktest_initial_cash回测初始资金backtest_commission_ratio回测佣金比例backtest_slippage_ratio回测滑点比例backtest_match_mode市价撮合模式,以下一tick/bar开盘价撮合:0,以当前tick/bar收盘价撮合:1'''run(strategy_id='自己的策略ID',filename='fengge_lundong_test.py',mode=MODE_BACKTEST,token='自己的token码',backtest_start_time='2021-03-01 09:00:00',backtest_end_time='2023-03-01 15:00:00',backtest_adjust=ADJUST_PREV,backtest_initial_cash=10000000,backtest_commission_ratio=0.0001,backtest_slippage_ratio=0.0001,backtest_match_mode=1)

在这里插入图片描述
从回测的数据看,整体效果并不是很好,超额收益率竟然是-4.27%,同时回撤也达到了-38%以上。
我们再看看我们选择的这几个指数在2021年3月到2023年3月的整体运行情况:

上证50沪深300中证500
在这里插入图片描述在这里插入图片描述在这里插入图片描述

从数据看,三个都是单边下跌的市场,怪不得数据这么差。
我们再重新选择一个时间段吧,这三个指数起伏各不相同的时候,看是否能获得不错的收益
在这里插入图片描述
所以我又尝试了一下2018年3月到2020年3月的数据,看起来还是跑赢了3个指数,说明这个还是需要在有指数上升有指数下降的时候才有一定效果,而A股市场有的时候完全无轮动,都是一起上升一起下降,该策略发挥不出来用处,所以在下一节中我们将尝试一些行业轮动策略,A股毕竟是一个炒题材炒概念的市场,也许行业轮动策略能发挥不错的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/396565.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】预处理详解(下)

文章目录 前言6. 宏和函数的对比7. #和##7.1 #运算符7.2 ##运算符&#xff08;运用较少&#xff0c;了解即可&#xff09; 8. 命名的约定9. #undef &#xff08;了解即可&#xff09;10. 条件编译&#xff08;重点&#xff09;11. 头文件的包含11.1 头文件被包含的方式&#xf…

House of Rabbit

House of Rabbit 介绍&#xff1a; House of rabbit 是一种伪造堆块的技术&#xff0c;早在 2017 年已经提出&#xff0c;但在最近两个月才在 CTF 比赛中出现。我们一般运用在 fastbin attack 中&#xff0c;因为 unsorted bin 等其它的 bin 有更好的利用手段。 原理&#x…

接口基础知识6:详解http request body(一篇讲完常见请求体)

课程大纲 一、定义 HTTP请求体&#xff08;HTTP Request body&#xff09;&#xff1a;HTTP请求消息的可选部分&#xff0c;仅在请求方法支持且需要发送数据时使用。 POST方法、PUT方法有请求体&#xff0c;GET和HEAD方法没有请求体。 请求头和请求体之间会有一个空行&#…

【C++】面向对象三大特性之—— 继承 | 详解

目录 继承的概念 继承语法格式 继承方式 隐藏 继承下来的成员和父类是不是同一份 隐藏 基类和派生类对象赋值转换 继承中的作用域 派生类的默认成员函数 构造 拷贝构造 赋值重载 析构 继承与友元 继承与静态成员 菱形继承及菱形虚拟继承 多继承 菱形继承 菱形…

探索Linux -- 冯诺依曼体系、初始操作系统、初始进程、fork函数

一、冯诺依曼体系结构 1、概念 冯诺依曼结构也称普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起的存储器结构。 最早的计算机器仅内含固定用途的程序。若想要改变此机器的程序&#xff0c;就必须更改线路、更改结构甚至重新设计此机器。当然最早的计…

三防平板满足多样化定制为工业领域打造硬件解决方案

在当今工业领域&#xff0c;数字化、智能化的发展趋势日益显著&#xff0c;对于高效、可靠且适应各种复杂环境的硬件设备需求不断增长。三防平板作为一种具有坚固耐用、防水防尘防摔特性的工业级设备&#xff0c;正以其出色的性能和多样化的定制能力&#xff0c;为不同行业的应…

8.7 Day15 匿名用户访问FTP与日志查看

查看配置文件 vsftpd是一个认证文件&#xff0c;意味着ftp是通过vsftpd这个认证文件来对我们输入的用户名和密码进行认证的&#xff0c;那么这个认证文件在哪里呢&#xff1f; 所在位置如下&#xff1a; 查看文件配置内容 默认通过系统来验证&#xff0c;但现在我们欲做一个类…

Flink-DataWorks第二部分:数据集成(第58天)

系列文章目录 数据集成 2.1 概述 2.1.1 离线&#xff08;批量&#xff09;同步简介 2.1.2 实时同步简介 2.1.3 全增量同步任务简介 2.2 支持的数据源及同步方案 2.3 创建和管理数据源 文章目录 系列文章目录前言2. 数据集成2.1 概述2.1.1 离线&#xff08;批量&#xff09;同步…

VulnHub靶场-VulnOS:2

1.环境准备 下载地址&#xff1a;VulnOS: 2 ~ VulnHub 前言&#xff1a;由于我们下载的靶场是vdi文件&#xff0c;而我使用的是虚拟机&#xff0c;我们需要安装VirtualBox将vdi文件转换成虚拟机的vmdk文件vdi转vmdk VirtualBox与VMware硬盘格式转换及使用方法-CSDN博客 虚拟…

【中等】 猿人学web第一届 第2题 js混淆 动态cookie 1

目录 调试干扰Hook Function 加密参数定位hook Cookie AST 解混淆字符串解密还原解密函数AST 配合解密函数还原字符串 ASCII 编码字符串还原字符串相加花指令(对象)剔除无用代码虚假 if剔除无引用代码剔除无引用的对象数值还原 switch 还原完整的 AST 代码代码注意 还原加密 请…

pygame小游戏

代码存在一些bug&#xff0c;感兴趣可自行修改&#xff0c;游戏运行后玩法与吃金币游戏类似。&#xff08;代码及结果比较粗糙&#xff0c;仅供参考&#xff09; 注&#xff1a;&#xff08;图片、音乐、音效文件老是上传上传不上&#xff0c;想要可私&#xff0c;也可以自己找…

如何在银河麒麟操作系统上搭建 Electron (含 Electron 打包指南)

本次教程所用版本 Eletron版本&#xff1a;31.3.1 Electron-packager版本&#xff1a;17.1.2 VScode版本&#xff1a;1.92.0 Node版本&#xff1a;18.19.0 npm版本&#xff1a;10.2.3 前言&#xff1a; 随着跨平台应用开发的需求日益增长&#xff0c;Electron 和 Qt 成为…

Midjourney入门-提示词基础撰写与公式

​ 前言 在前几篇教程里我们已经可以初步使用Midjourney进行出图了。 包括也了解了Midjourney的指令与参数。 但如果你想用Midjourney去生成各种各样高质量的图片&#xff0c; 并且生成的图片是你想要的画面内容&#xff0c;也就是更好控制生成图片的画面内容与风格&#xf…

书生大模型实战营闯关记录----第八关:书生大模型全链路开源开放体系

书生大模型全链路开源开放体系 一、概述 书生大模型&#xff0c;即InternLM系列模型&#xff0c;是由上海人工智能实验室书生团队开发的一系列大语言模型。这些模型以其强大的功能而著称&#xff0c;涵盖了从基础的语言理解到复杂的数学解题和图文创作等多个领域。 发展历程…

【每日面经】快手面经

ConcurrentHashMap和HashMap的区别&#xff1f;使用场景&#xff1f; 线程安全性 concurrentHashMap是线程安全的&#xff0c;HashMap不是线程安全的锁机制 ConcurrentHashMap采用的是分段锁&#xff08;Sagment&#xff09;机制&#xff0c;降低所得粒度提高了并发性能 Curr…

4章4节:临床数据科学中如何用R来进行缺失值的处理

在临床科研中,由于失访、无应答或记录不清等各种原因,经常会遇到数据缺失的问题。本文将深入探讨医学科研中数据缺失的成因、分类、影响以及应对方法,结合R语言的实际应用,为医学研究人员提供全面的解决方案。 一、认识缺失数据 其实,很多医学的纵向研究因获取数据资料时…

38.【C语言】指针(重难点)(C)

目录: 8.const 修饰指针 *修饰普通变量 *修饰指针变量 9.指针运算 *指针或-整数 *指针-指针 *指针关系运算 往期推荐 承接上篇37.【C语言】指针&#xff08;重难点&#xff09;&#xff08;B&#xff09; 8.const 修饰指针 const 全称 constant adj.不变的 *修饰普通变量 #…

java.lang.NoClassDefFoundError: ch/qos/logback/core/util/StatusPrinter2

1、问题 SpringBoot升级报错&#xff1a; Exception in thread "main" java.lang.NoClassDefFoundError: ch/qos/logback/core/util/StatusPrinter2 类找不到&#xff1a; Caused by: java.lang.ClassNotFoundException: ch.qos.logback.core.util.StatusPrinter22、…

HDFS写入数据的流程图

1.客户端向namenode发送请求&#xff0c;请示写入数据 2.namenode接受请求后&#xff0c;判断这个用户是否有写入权限&#xff0c;如果不具备直接报错&#xff1b;如果有写入权限&#xff0c;接着判断在要写入的目录下是否已经存在这个文件&#xff0c;如果存在&#xff0c;直…

PHP语言特性漏洞汇总【万字详解】

文章目录 任意文件下载PHP弱类型比较字符比较绕过代码示例过程 SHA1比较绕过MD5比较绕过SESSION比较绕过STRCMP比较绕过科学计算法绕过概念复现复现2 json_decode&#xff08;&#xff09;绕过概念源码分析 ereg绕过概念复现复现2 array_search强相等绕过概念复现 文件包含生成…