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

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

戴维斯效应简述:

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

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

公式:股价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 = 1
        df['lc'] =df['收盘价_复权'] - df['收盘价_复权'].shift(1)
        df['lc0'] =0
        a =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)* 100
        df['前一日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年的走势对比,其中橙色的为上证指数,蓝色的为戴维斯双击策略改进版曲线。

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

总结

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

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

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
第一太平戴维斯城市更新白皮书是一份由第一太平戴维斯房地产咨询公司整理和发布的城市更新研究报告。该白皮书主要关注城市更新领域的市场趋势和发展前景,通过对市场数据的分析和案例的研究,提供了对城市更新项目的综合评估和指导。 随着城市化进程的推进和城市发展的需求,城市更新成为许多城市面临的重要课题。第一太平戴维斯城市更新白皮书通过搜集和整理相关的市场数据和案例研究,为政府、开发商和投资者等利益相关方提供了重要的市场信息和参考意见。 在该白皮书中,第一太平戴维斯详细分析了城市更新项目的市场潜力和投资回报率。通过对城市更新项目的各个环节进行详细的解析,包括项目选址、规划设计、市场需求和销售预测等,提供了专业的市场评估和指导建议。 此外,第一太平戴维斯城市更新白皮书还关注了城市更新项目的可持续发展和社会效益。通过对城市更新的生态环境、社会效益和经济可行性等方面的研究,提出了一系列促进城市更新发展的政策建议和实施方案。 总的来说,第一太平戴维斯城市更新白皮书是一份权威的研究报告,对于城市更新领域的相关行业从业者和投资者具有很高的参考价值。它提供了全面的市场分析和专业的建议,为城市更新项目的规划和实施提供指导,同时也有助于推动城市更新领域的可持续发展。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值