戴维斯双击策略的实现与验证

article/2025/10/15 10:00:52

戴维斯双击策略的实现与验证

戴维斯效应简述:

戴维斯双击和戴维斯双杀:

戴维斯效应,就是有关市场预期与上市公司价格波动之间的双倍数效应。也就是说当一个公司利润持续增长使得每股收益提高,同时市场给予的估值也提高,股价得到了相乘倍数的上涨,这就叫戴维斯双击;相反,当一个公司业绩下滑时,每股收益减少或下降,市场给予的估值也下降,股价得到相乘倍数的下跌,这就叫戴维斯双杀。

公式:股价P=每股收益EPS*市盈率PE

比如,A公司2017年股价20元,每股收益2元,市盈率10PE,假设该公司每年净利润增长10%,那么3年后每股收益EPS=2*(1+0.1)3次方=2.66元,在市盈率不变的情况下3年后公司的股价为P=2.6610=26.6元(这只是单击),但是由于该公司业绩持续增长,使人们对公司的未来产生更乐观的预期,于是给它更高的估值比如15PE,这时候用公式算一下3年之后的股价应该是P=2.6615=39.9元(这就形成戴维斯双击)。

相反,一些公司在近期的财报披露中揭开了“高成长”的伪装,比如创业板某公司,在中报预告中预亏损,那么它相应的每股收益也会相应下滑,同时人们对它的预期也下降,于是给予的市盈率估值下降,因此股价会得到相乘倍数的下降,这就是戴维斯双杀。

戴维斯效应的应用:

比如以10PE买入业绩每年增长10-15%的公司,五年后市场会给这公司更高的预期,便会以13PE甚至15PE买入,此时的股价已经形成戴维斯双击,卖出就会获得相当可观利润。相反,很多人以30PE买入期望每年增长30%以上的所谓成长股,六年后的获利率只有前者的一半不到,如果成长股增长达不到预期或者业绩变脸,形成戴维斯双杀,亏损更为严重。

python实现戴维斯双击策略:

01数据获取:

由于实现该策略需要用到财务报告中的数据,财务数据中包含的的字段有许多,最主要是一下图片中包含的这些字段。
在这里插入图片描述
图一:某只股票财务数据中的一些字段。其中还有许多字段就不一一展示出来了。
在这里插入图片描述
图二:财务数据部分展示。由于历史原因,有些在90年代数据会有所缺失。

注:以上谈到的数据是邢不行股票量化课程、策略分享会专用 ,由邢不行整理,微信:xbx9025。数据不公开,感谢邢大提供这么优质的数据。

02策略构建:

满足戴维斯双击的条件:
1、单季净利润的同比增速为正,且前期净利润大于300万;
2、上一期单季净利润的同比增速为正;
3、上一期单季营收为正或者上季_营业收入(单季),上季_营业总收入(单季)为正;
4、当期的单季度净利润同比增速大于20%且小于100%;
5、当期单季净利润的同比增速和上一期单季净利润的同比增速,并对 2 个增速环比计算二阶增速,要求二阶增速为正,即 2 个季度加速增长;

其中还可以添加限定的条件进行进一步地过滤选股。

python代码块:

# 戴维斯双击策略
p = '归母净利润(单季)'
t = '均值'# 条件筛选
# 条件0:剔除上市不满1年的新股。
cond = df['上市至今交易天数'] >= 250# 条件1:单季净利润的同比增速为正,且前期净利润大于300万;cond &= (df[p + '_' + t + '_同比'] > 0) & (df['上季_' + p] > 3000000)# 条件2:上一期单季净利润的同比增速为正
cond &= df['上季_' + p + '_同比'] > 0# 条件3:上一期单季营收为正。
# 有两个字段可以使用,都可以试一下:上季_营业收入(单季),上季_营业总收入(单季)
cond &= df['上季_营业收入(单季)'] > 0# 条件4 分别计算当期单季净利润的同比增速和上一期单季净利润的同比增速,并对 2 个增速环比计算二阶增速,要求二阶增速为正,即 2 个季度加速增长;
# df['二阶增速'] = df[p + '_同比'] - df['上季_' + p + '_同比']
df['二阶增速'] = df[p + '_' + t + '_同比'] - df['上季_' + p + '_同比']
cond &= df['二阶增速'] > 0# 条件6:进一步要求样本股票估值小于50倍
cond &= df['市盈率_归母净利润(ttm)'] <= 45
cond &= df['市盈率_归母净利润(ttm)'] > 0
# 条件7:我们进一步要求当期的单季度净利润同比增速大于20%且小于100%cond &= (df[p + '_' + t + '_同比'] > 0.2)
cond &= (df[p + '_' + t + '_同比'] < 1)# 筛选
df = df[cond]
df.reset_index(drop=True, inplace=True)# 因子
df['因子'] = 1 / df['二阶增速']
df['因子2'] = df['市盈率_归母净利润(ttm)'] / df['二阶增速']  # 改良因子

根据构建的因子排名,然后选择5个票进行买卖。

# 根据选股因子对股票进行排名
df['排名'] = df.groupby('交易日期')['因子'].rank()
df = df[(df['排名'] <= select_stock_num)]  # 选取排名靠前的股票# 按照开盘买入的方式,修正选中股票在下周期每天的涨跌幅。
# 即将下周期每天的涨跌幅中第一天的涨跌幅,改成由开盘买入的涨跌幅
df['下日_开盘买入涨跌幅'] = df['下日_开盘买入涨跌幅'].apply(lambda x: [x])
df['下周期每天涨跌幅'] = df['下周期每天涨跌幅'].apply(lambda x: x[1:])
df['下周期每天涨跌幅'] = df['下日_开盘买入涨跌幅'] + df['下周期每天涨跌幅']

回测周期 :2010/01/19 --2020-09-01
回测股票池:全体A股,剔除ST与上市不满一年的票
调仓周期:每季度调仓一次,即三个月调仓一次
持仓股票数量:5只

最终戴维斯双击策略模型输出持仓日记如下:
在这里插入图片描述
图三:戴维斯双击策略模型输出持仓日志。

在这里插入图片描述
图四:戴维斯双击策略收益曲线与上证指数在2010-2020年的走势对比,其中橙色的为上证指数,蓝色的为戴维斯双击策略曲线。

在这里插入图片描述
图五:戴维斯双击策略收益的具体参数。
在这里插入图片描述
图六:戴维斯双击策略每年收益数据。

改进与优化的思路:
1、以上只是最简化版的戴维斯双击策略,构建因子的方式也很简单,改进的思路可以利用更多的因子来构造戴维斯双击指标。
2、在原来的戴维丝策略选股条件上,可以增加了多个选股条件,从股票的走势、活性、企业发展潜力等方面对股票进行筛选。

改进思路与代码实现:
1、在原来的戴维丝策略选股条件上,增加了5个选股条件,从股票的走势、活性、企业发展潜力等方面对股票进行筛选。

# 条件7:均价大于60日均线,确保股票走势不坏
cond &= df['chl均价']>=  df['ma_60']
#df['chl均价'] = (df['收盘价_复权'] + df['最高价_复权'] + df['最低价_复权']) / 3
#  条件8:确保股票的活性
cond &= df['成交比例'] > 0.525
# df['成交比例'] = df['成交额'] / df['流通市值'] * 100 
# 条件9:
cond &= df['量价相关系数_20_排名'] < 0.75
# 条件10:降低回测有作用
cond &= df['均线_10_排名'] > 0.15
# 条件11:考虑企业发展潜力
cond &= df['成长性_排名'] >= 0.30
# df['成长性'] = df['研发费用'] / df['市盈率_净利润(ttm)']

2、在数据整理方面,增加了三个选股因子,实现把超卖的股票、近期换手率降低而股价走高、股价曲线斜率向上的股票给选出来的问题。

第一个因子:RSI,选出超卖的股票,这是我们所需要的股票。
这是根据股票软件上的RSI公式改的
LC:=REF(CLOSE,1);
RSI1:SMA(MAX(CLOSE-LC,0),N1,1)/SMA(ABS(CLOSE-LC),N1,1)*100;
RSI2:SMA(MAX(CLOSE-LC,0),N2,1)/SMA(ABS(CLOSE-LC),N2,1)*100;
RSI3:SMA(MAX(CLOSE-LC,0),N3,1)/SMA(ABS(CLOSE-LC),N3,1)*100;

     # 计算代码for n in [ 3,27,33]:m = 1df['lc'] =df['收盘价_复权'] - df['收盘价_复权'].shift(1)df['lc0'] =0a =df[["lc","lc0"]].max(axis=1).ewm(alpha=m / n, adjust=False).mean()b =  abs(df['lc']).ewm(alpha=m / n, adjust=False).mean()df['RSI%s_%s' % (n, m)] = (a / b)* 100df['前一日RSI%s_%s' % (n, m)] = df['RSI%s_%s' % (n, m)].shift()df.drop(['lc','lc0'],axis=1, inplace=True)extra_agg_dict['RSI%s_%s' % (n, m)] = 'last'extra_agg_dict['前一日RSI%s_%s' % (n, m)] = 'last'

第二个因子:换手率变动率因子,逻辑是股价破新高,换手率比前值低。

 # 换手率降低率因子 股价破新高,换手率比前值低n = 1 #因为是按季选股,大致筛选了下,取1效果要好些df['前%d日最高收盘价' % n] = df['收盘价_复权'].rolling(n, min_periods=1).max()df.loc[n - 1:, '前%d日最高收盘价当日换手率' % n] = df.loc[df['收盘价_复权'].rolling(n).apply(np.argmax)[n - 1:].astype(int) + range(len(df) - (n - 1)), '换手率'].to_list()condition1 = df['收盘价_复权'] >= df['前%d日最高收盘价' % n].shift(1)condition2 = df['换手率'] < df['前%d日最高收盘价当日换手率' % n].shift(1)df['换手率变动率_%s' % n] = np.where(condition1 & condition2,(df['前%d日最高收盘价当日换手率' % n].shift(1) - df['换手率']) / df['前%d日最高收盘价当日换手率' % n].shift(1),    0)extra_agg_dict['换手率变动率_%s' % n] = 'last'

第三个因子是:斜率因子,目的是找出k线趋势较好的股票。

 # =计算alpha21# 公式:REGBETA(MEAN(CLOSE,6),SEQUENCE(6))"""REGBETA(A, B, n) :前n期样本A对B做回归所得回归系数MEAN(A, n) : 序列A过去n天均值SEQUENCE(n) :生成1n的等差序列Alpha_21因子本质上是计算过去6天的收盘价均值在固定数列上的斜率, 斜率越大,上涨趋势越好,斜率越小,上涨趋势越差。"""# 计算代码n = 6  #选6是经验值df['mean_%s' % n] = df['收盘价_复权'].rolling(n).mean()df['斜率21_%s' % n] = df['mean_%s' % n].rolling(n).apply(lambda x: np.polyfit([1, 2, 3, 4, 5, 6], x.tolist(), deg=1)[0])extra_agg_dict['斜率21_%s' % n] = 'last'#增加了选股因子组合:# 因子df['二阶增速'] = 1 / df['二阶增速']df['二阶增速_排名'] = df.groupby('交易日期')['二阶增速'].rank(pct=True)df['rsi差'] =abs( df['RSI27_1']- df['RSI33_1'])df['rsi差_排名'] = -df.groupby('交易日期')['rsi差'].rank(pct=True)df['斜率21_6_排名'] =-df.groupby('交易日期')['斜率21_6'].rank(pct=True)df['换手率变动率_1_排名'] =-df.groupby('交易日期')['换手率变动率_1'].rank(pct=True)df['因子'] = df['二阶增速_排名']+df['rsi差_排名'] +df['换手率变动率_1_排名']+df['斜率21_6_排名']

回测设计:
回测周期:2010/1/8 --2020/11/27
选股数量:3
调仓周期:1周
投资标的:全体A股,剔除ST与上市不满一年的票
费用设计:(买入时手续费万分之三,卖出时手续费万分之三加千分之一印花税)

回测结果如下:

在这里插入图片描述
图七:戴维斯双击策略改进版模型输出持仓日志(部分)。

在这里插入图片描述
图八:戴维斯双击策略改进版收益曲线与上证指数在2010-2020年的走势对比,其中橙色的为上证指数,蓝色的为戴维斯双击策略改进版曲线。

在这里插入图片描述
图九:戴维斯双击策略改进版收益的具体参数。

总结

戴维丝选股策略是一个不错的、很稳健的选股策略。本文简单得实现一下最初版的戴维斯双击策略,并且在简单版中进行优化改进,分享一下。感兴趣的同学可以尝试往跟多不同改进思路去魔改策略。

最后欢迎大家批评指正,有什么好的思路也可以一起交流。谢谢大家!


http://chatgpt.dhexx.cn/article/fDuEoPrs.shtml

相关文章

如何在Github上建立自己的个人博客网站详细教程

概述 之前闲着没事,就利用Github建了一个个人博客网站,效果还不错,今天就来分享一下. 建立自己个人博客网站的好处: 1.面试装逼,这个不必多说… 2.把平时积累的知识和项目记录下来,方便日后查看使用 3.不受其他博客平台的限制 准备工作 开始之前,先大致介绍一下用到的技术和…

怎么创建自己的博客网站

怎么创建自己的博客网站最简单的方法还是使用wordpress系统来搭建&#xff0c;使用者不需要掌握很多的专业知识就能独立操作。 首先&#xff0c;在wordpress官网上&#xff08;https://wordpress.org/&#xff09;下载wordpress-5.1.zip这个压缩包。 其次&#xff0c;登录空间…

新手如何自己搭建一个属于自己的博客网站?

网站开发技术新手建立一个属于自己的个人博客站点&#xff0c;其实是挺容易。现在各类企业、博客、商城类的网站框架比比皆是&#xff0c;也都有对应的操作文档&#xff0c;仔细看一遍文档&#xff0c;操作起来也是非常简单的。那么下面 德阳SEO优化就带着各位准站长操作一下如…

十分钟教你搭建个人博客

估计很多小伙伴都想要一个专属于自己的个人博客&#xff0c;拥有自己的网页&#xff0c;设计好看的背景&#xff0c;插画&#xff0c;图片等。下面我们来一起实践一下吧。 我的博客&#xff1a;http://www.sweetdumpling.cn/ 文章目录 1.准备需要&#xff08;该操作针对的是阿里…

建立自己的博客(记录-不推荐)

环境安装&#xff1a; w10系统安装 第一步&#xff1a;安装git Git 官网: https://git-scm.com/ 第二步&#xff1a;安装Node.js Node.js官网&#xff1a;https://nodejs.org/zh-cn/ 使用cmd检测&#xff1a; node -v 第三步&#xff1a;安装Hexo Hexo官网&#xff1a;htt…

如何搭建一个属于自己的博客网站?(小白教程)

如何搭建一个属于自己的博客网站&#xff1f;&#xff08;小白教程&#xff09; 一、准备阶段二、搭建阶段1、服务器阶段2、宝塔面板阶段3、WordPress阶段 三、结尾语 欢迎大家访问我的个人博客&#xff1a;endeavorchuan.com 很多人包括我在内&#xff0c;都希望能有一个自己…

查看android端BKS类型的证书库

查看android端BKS类型的证书库 查看bks证书库&#xff0c;使用bcprov-jdk15on-164.jar&#xff0c;cd到对应的目录下&#xff1a; keytool -list -v -keystore "xxx.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcpro…

P12证书转BKS证书

安卓 识别的证书格式是bks ,而我之前生成的证书格式是p12 所以需要转换一下&#xff0c;至于怎么生成p12&#xff0c;请看我转载的的文章 Nginx https 双向认证。 1.请先下载第三方转换工具protecle&#xff0c;配置java环境 &#xff08;需要的话可以留言&#xff0c;&…

p12或者jks证书转换为bks

2019独角兽企业重金招聘Python工程师标准>>> 如果是p12先转换为jks&#xff08;jks可以直接转换使用&#xff09; 如果不知道证书别名&#xff0c;需要查询别名&#xff08;4a1b1是密码&#xff09; keytool -list -v -keystore file.jks -storepass 4a1b1 p12转换为…

android https cer证书转换BKS

使用环境&#xff1a; 项目联网需要防止泄漏重要数据&#xff0c;使用https证书 转换方法&#xff1a; keytool -importcert -v -trustcacerts -alias xx -file E:\bks\xx.cer -keystore E:\bks\xx.bks -storetype BKS -providerclass org.bouncycastle.jce.provider.BouncyC…

crt、cer类型证书转换成bks

Https证书crt或者cer转换成bks文件 1、下载bcprov-jdk15on-165.jar&#xff1a; http://www.bouncycastle.org/latest_releases.html 2、打开cmd执行命令&#xff1a; keytool -importcert -v -trustcacerts -alias 位置1 -file 位置2 -keystore 位置3 -storetype BKS -provi…

Android BKS 格式证书制作,JKS 制作 BKS,解决 java.security.KeyStoreException: JKS not found 问题

Server端提供以下两个 jks 格式的证书&#xff0c;由于Android无法直接使用 jks 格式的证书&#xff0c;所以需要转换为 bks 格式。 工具 Portecle 下载 https://jaist.dl.sourceforge.net/project/portecle/v1.11/portecle-1.11.zip 待转换的 JKS 文件 1.client.jks (客户…

SSlSocket和SSLServerSocket的学习 jks,bks的使用

1. 生成bks与jks密钥证书 1.1 jks证书生成 1.1.1 生成服务端JKS秘钥与证书指令 keytool -genkeypair -alias myserver -keystore myserver.jks1.1.2 服务器导出证书server.cer keytool -exportcert -alias myserver -keystore myserver.jks -file trust.cer 1.1.3从证书导…

Android——.pem格式证书转换为.bks

第一步&#xff1a;先下载“bcprov-ext-jdk xxx.jar”&#xff0c;下载地址&#xff1a;https://www.bouncycastle.org/latest_releases.html 第二步&#xff1a;将下载好的jar文件放到“C:\Program Files (x86)\Java\jre1.8.0_321\lib\ext”路径中 第三步&#xff1a;在“C:…

android 生成bks_Android Https证书crt或者cer转换成bks文件

一&#xff1a;下载bcprov-jdk15on-160.jar 下载bcprov-jdk15on-160.jar 二&#xff1a;打开命令行 keytool -importcert -v -trustcacerts -alias 位置1 \ -file 位置2 \ -keystore 位置3 -storetype BKS \ -providerclass org.bouncycastle.jce.provider.BouncyCastleProvide…

Win系统下将CER文件转成BKS文件

如何在Win下转换CER证书文件&#xff1f; 通过JDK1.8 实现CER文件转BKS文件 通过JDK文件的keytool.exe文件进行转换。原本我使用的是JDK11&#xff0c;发现居然没有 jre文件夹 于是我使用了 CMD 命令 需要以 管理员权限才能够生成 bin\jlink.exe --module-path jmods --add-mod…

java不支持bks,java不支持bks

java不支持bks [2021-02-08 08:35:23] 简介: php去除nbsp的方法&#xff1a;首先创建一个PHP代码示例文件&#xff1b;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推荐&#xff1a;《PH…

生成.bks格式文件

最近公司项目需要换成https请求&#xff0c;负责服务器的同事给了我证书&#xff0c;搞了一天都没成功&#xff0c;老是挂掉。&#xff08;如果不太清楚可以先搜索下SSL握手&#xff09;后来在网上才看到&#xff0c;android不支持jdk默认编译的“JKS”格式&#xff0c;只支持“…

贝塔分布,伽玛分布和指数分布的关系

统计计算课本36面。 统计计算课本155面 https://www.zhihu.com/question/45397840 https://blog.csdn.net/tangwing/article/details/87006687

【理解】Beta贝塔分布

贝塔分布是概率的概率分布&#xff0c;在不知道某一事件具体概率是多少时&#xff0c;它给出了所有概率出现的可能性。 举个例子&#xff1a;对于抛硬币&#xff0c;我们知道硬币正面朝上是服从二项分布的 X ∼ b ( n , p ) X \sim b(n, p) X∼b(n,p)&#xff0c;我们为了用大量…