可转债市场因子挖掘和量化策略(一)——正股涨跌停因子

作者会陆续更新整理自己在可转债市场量化的一些心得和想法。

一、可转债市场数据和预处理

对于可转债,由于有日频和分钟频等不同策略,因此数据需要分钟频和日频两种。

日频数据已经清洗干净,但需要注意同花顺对于沪深分钟频可转债数据的单位并不一致。沪市单位为“张”(10手)。

将单位统一为手。 

mmkt=all_data_mkt_bond.copy()
mmkt.loc[mmkt['bondcode'].str.startswith('11'),
        'vol_b']=mmkt.loc[mmkt['bondcode'].str.startswith('11'),
        'vol_b']*10 #单位统一为1手

二、市场因子

由于我国可转债市场成熟程度较低,在市场流动性、市场深度、市场广度等方面均远远低于股票市场。在可转债市场进行量化策略交易时几大关键点之一就是市场情况,否则很容易出现“写了一个回测很好的策略,但实盘时买卖单无人接,最终超额没吃到,反而吃到一大波回撤”的情况。

同样的,从市场容量、市场流动性等市场因子角度研究策略也会带来更适应可转债市场的视角。

策略框架简介

一个简单的策略框架是,每日开盘买入“好”债,在接下来3日内寻高卖出,3日后仍未清盘的可转债则直接清仓。

当然,针对不同因子情况,也可以简化为,以open/close买入,在x日(持仓不超过4天)以open/close卖出。

1.正股涨跌停因子

让我们先来看个情绪因子。

核心问题:正股涨停对可转债涨跌影响——正股涨停的可转债三日内是否多数赚?跌停后三日是否多数跌?

1.0 先说结论

1.正股涨停次日可转债……

        (1)96.7%的概率会上涨,综合最大涨幅较大(5.9%左右),最大回撤较大(5.3%)

        (2)开板后热情和波动均消退(斩半),但这主要是因为该信号的效果消退快,不看是否开板而只看隔日,效果就已经斩半了。

        (3)构建策略:正股涨停当日(第0日)以close买入可转债,第4日以open卖出,可以获得平均70%的年化收益,回撤仅为19.8%,夏普比例高达3.6,且策略信号持续稳定有效,是最优秀的一个策略。

2.正股跌停次日可转债……

        (1)反转效应明显:97.7%的概率会上涨,综合涨幅较大(5.7%左右),最大回撤很低(2.9%,对比全市场来看3日最大回撤:1.9%)

        (2)同样,开板后热情和波动均消退,但这主要是因为该信号的效果消退快,不看是否开板而只看隔日,效果就已经斩半了。

        (3)构建策略:

        如果希望稳健一些,正股涨停当日(第0日)以close买入可转债,第1日以open卖出,可以获得平均20%的年化收益,回撤仅为8.6%,夏普比例为2.3。

        如果希望激进一些,正股涨停当日(第0日)以close买入可转债,第4日以open卖出,可以获得平均76%的年化收益,回撤约为29.3%,夏普比例为2.59。

1.1 因子构造如下

#除去未交易(退市/未上)的可转债
df=df[~(df['volume']==0)]
dmkt=df
dmkt=dmkt.rename(columns={'thscode':'bondcode'})

dmkt['Up']=0
dmkt['Down']=0
dmkt.loc[((((dmkt['stockbond'].str.startswith('3'))|(dmkt['stockbond'].str.startswith('68')))&
           (dmkt['stockpct'].round(0)==20))|((~((dmkt['stockbond'].str.startswith('3'))|
                                              (dmkt['stockbond'].str.startswith('68'))))&(dmkt['stockpct'].round(0)==10))),'Up']=1
dmkt.loc[((((dmkt['stockbond'].str.startswith('3'))|(dmkt['stockbond'].str.startswith('68')))&
           (dmkt['stockpct'].round(1)==-20))|((~((dmkt['stockbond'].str.startswith('3'))|
                                               (dmkt['stockbond'].str.startswith('68'))))&(dmkt['stockpct'].round(1)==-10))),'Down']=1

dmkt['date']=pd.to_datetime(dmkt['date'])
dmkt=dmkt.sort_values(by='date')
dmkt=dmkt.set_index('date')

#持仓时间内(未来3日)可达到的最大收益和最大回撤
dmkt['3D_up']=dmkt.groupby('bondcode')['high'].transform(lambda x:x.rolling(3).max().shift(-3))
dmkt['3D_up_pct']=dmkt['3D_up']/dmkt['open'] #3d_up: 最大收益
dmkt['3D_down']=dmkt.groupby('bondcode')['low'].transform(lambda x:x.rolling(3).min().shift(-3))
dmkt['3D_down_pct']=dmkt['3D_down']/dmkt['open'] #3d_down: 最大回撤


print('The all market return of all bonds: ')
print(pd.DataFrame(dmkt[['3D_up_pct','3D_down_pct']].mean()))
print('-·'*50)

print('The all market number of rising bonds: ')
print(pd.DataFrame({'Rising-bond numbers':dmkt.loc[dmkt['3D_up_pct']>1,['3D_up_pct']].count(),
                   'Rising-bond return':dmkt.loc[dmkt['3D_up_pct']>1,['3D_up_pct']].mean()}))
print()
print('The all market number of going-down bonds: ')
print(pd.DataFrame({'Going-down-bond numbers':dmkt.loc[dmkt['3D_up_pct']<=1,['3D_up_pct']].count(),
                   'Going-down-bond return':dmkt.loc[dmkt['3D_up_pct']<=1,['3D_up_pct']].mean()}))
print('-·'*50)


dmkt['pro_up']=0 #前日正股涨停则为1
dmkt['pro_down']=0
dmkt.loc[dmkt.groupby('bondcode')['Up'].shift(1)==1,'pro_up']=1
dmkt.loc[dmkt.groupby('bondcode')['Down'].shift(1)==1,'pro_down']=1
dmkt['prev_close']=dmkt.groupby('bondcode')['close'].transform(lambda x: x.shift(1))

dt_D_Up=dmkt.loc[dmkt['pro_up']==1,['bondcode','open','high','low','close',
                                                   'changeRatio','3D_up','3D_up_pct','3D_down','3D_down_pct']]
dt_D_Down=dmkt.loc[dmkt['pro_down']==1,['bondcode','open','high','low','close',
                                                   'changeRatio','3D_up','3D_up_pct','3D_down','3D_down_pct']]
print('The average return 3 days after Limit Up is: ')
print(pd.DataFrame(dt_D_Up.groupby('bondcode')[['3D_up_pct','3D_down_pct']].mean()).head(10))
print('-·'*50)
print('The average return 3 days after Limit Down is: ')
print(pd.DataFrame(dt_D_Down.groupby('bondcode')[['3D_up_pct','3D_down_pct']].mean()).head(10))

1.2 涨跌幅情况统计

1.1.1 正股涨跌停后可转债情况

首先,我们先观察全市场在回测区间内的涨跌幅情况。

统计3日内最高价、最低价,来计算3日内最大涨幅和最大跌幅,以观察债市走向。

得出结论:全市场平均涨跌幅度相当,平均3日内最高收益可达2.5%,最大回撤约为1.9%。注意,这里3D_up_pct为未来3日最大收益,即未来3日最高债价/今日开盘价;3D_down_pct是指未来3日最大回撤,即未来3日最低债价/今日开盘价。

然后,我们接着统计前一日正股涨跌停后的可转债收益情况:

这是前一日正股涨停后3日对应可转债的情况

 这是前一日正股跌停后3日对应可转债的情况

可以看到,正股涨停后可转债97%的情况下3日内有平均最高6%的上涨幅度,但波动也较大,最大回撤平均为5.3%。总体来说,平均来看,3日后可实现最大收益平均为5.9%。

正股跌停后可转债表现也较好,在98%的情况下3日内有平均最高5.9%的上涨幅度,但是回撤非常低,最大回撤仅3%,远低于正股涨停情况。

因此看来,可转债市场追涨热情高,杀跌恐慌较低,在正股大跌时反转效应较为显著。

1.1.2 正股涨跌停后开板日影响

进一步提出假设:若次日为开板日,是否会造成不同的影响?

代码如下:

#开板判别:开板则为1
dt_Dk_Up=dmkt.loc[(dmkt['pro_up'].shift(1)==1)&(dmkt['Up'].shift(1)==0)&(dmkt['Down'].shift(1)==0),['bondcode','open','high','low','close',
                                                   'changeRatio','3D_up','3D_up_pct','3D_down','3D_down_pct']]
dt_Dk_Down=dmkt.loc[(dmkt['pro_down'].shift(1)==1)&(dmkt['Up'].shift(1)==0)&(dmkt['Down'].shift(1)==0),['bondcode','open','high','low','close',
                                                   'changeRatio','3D_up','3D_up_pct','3D_down','3D_down_pct']]

得到以下结果: 

这是两日前正股涨停、前一日正股开板的可转债情况 

这是两日前正股跌停、前一日正股开板的可转债情况

相比刚刚的条件,此时最大收益略微下降,最大回撤也有所减少。值得注意的是在「两日前正股跌停、前一日正股开板」的条件下,可转债上涨的概率有所增加,从97.7%上升至98.4%,这可能说明「两日前正股涨停、前一日正股开板」的当日开盘价将低于前一日开盘价。

1.1.3 正股涨跌停信号消退迅速

但这会不会是因为过了一日之后激情消退的原因呢?

事实上,如果不考虑开板,但考虑「两日前正股涨跌停、前一日任意情况」的可转债情况,可以发现和「两日前正股涨停、前一日正股开板」情况几乎一样。说明开板与否并不影响市场接下来3日的变动。

  

「两日前正股涨停、前一日任意情况」的可转债情况 

「两日前正股跌停、前一日任意情况」的可转债情况

1.1.4 补充在研究中发现的有趣现象
  • 1.假设改变策略为,条件次日开盘买入,当日不做操作,然后在第2-4日寻高卖出,情况则与上述不同。似乎避开了信号第二日的兵荒马乱之后,市场表现出更强的下跌反转效应,但对于上涨反应平平。结论如下:

1.「两日前正股涨停、前一日任意情况」下,可转债在接下来4日上涨概率、上涨情况和「两日前正股涨停、前一日正股开板」几乎一样。

        📍这说明开板并未带来太大恐慌/热情消退。

2.「两日前正股跌停、前一日任意情况」下,最大涨幅低于、最大回撤高于「两日前正股涨停、前一日正股开板」。

        📍开板意味着下跌的结束,这似乎让投资者大感宽心,可转债市场小幅回暖。

  • 2. 并不修改策略。观察正股连跌的可转债。正股连跌三天的可转债效应最为明显,3日最高首日竟能达到7%,同时最大回撤也仅1.4%。可惜这样的时机非常少,仅占全部正股跌停次数的6.64%。

1.1.5 总结1.1节结论/猜测

目前我们可以得到以下结论(猜测):

1.涨停次日

        (1)96.7%的概率会上涨,综合最大涨幅较大(5.9%左右),最大回撤较大(5.3%)

        (2)开板后热情和波动均消退(斩半),但这主要是因为该信号的效果消退快,不看是否开板而只看隔日,效果就已经斩半了。

2.跌停次日

        (1)反转效应明显:97.7%的概率会上涨,综合涨幅较大(5.7%左右),最大回撤很低(2.9%,对比全市场来看3日最大回撤:1.9%)

        (2)同样,开板后热情和波动均消退,但这主要是因为该信号的效果消退快,不看是否开板而只看隔日,效果就已经斩半了。

为了具体理解正股涨跌停对可转债价格的影响,划分如下几个子内容:涨跌停当日close、次日open、次日high、次日close、第3日close、第4日close、第5日close。猜测正股涨跌停给可转债市场带来的影响是:次日开盘价较高,当日会冲击较高价格;再次日开盘价稍低,随后3日均处上升趋势。

由此,我们关注如下几件事:

1.正股涨跌停当日close买入、后几日close卖出是否有较为显著的收益

2.正股涨跌停当日close买入、后几日open卖出是否有较为显著的收益

3.正股张跌停次日开盘价是否普遍比第3日开盘价高

1.3 检验上述猜想

1.正股涨跌停当日close买入、次日close卖出是否有较为显著的收益

涨停情况下,可以看到收益均值均小于1。

跌停情况下,平均来看,反转效应持续时间长且效应明显——第4日close平均比正股跌停当日的close高2.4%。

仔细考察第4日close/当日close情况如下。可以看到,如果采用「正股跌停当日买入(第1日),第4日close卖出」的策略,70%的情况下可以获得5.6%的收益,30%的情况下将承受3.8%的亏损。

跌停情况下,后几日open/当日close 的情况和 后几日close/当日close的情况差不多,差异主要在于:「正股跌停次日open/跌停当日close」平均值远小于「正股跌停次日close/跌停当日close」平均值,波动也更小。

同样考察第4日open/第0日close,该策略也有较好收益,效果和第4日close/第0日close接近。

2.正股涨跌停当日close买入、多日后open卖出是否有较为显著的收益

涨停情况下,只有「当日close买入、次日后open卖出」策略可以获得正收益,其余均为负收益。

跌停情况下,时间越长远,反弹效果越好,当然波动性也更大。

和close/close相比,open/close 的情况差异主要在于:「1open/0close」平均值远小于「1close/0close」平均值,波动也更小。

正股涨停日以close买入(第0日),第4日以close卖出,可以获得最大收益,其中70%的概率可以获得平均5.6%的收益,30%的情况下承受3.8%的亏损。这或许可以构造出一个简单但好用的策略。

3.正股张跌停次日close是否普遍比第3日open高

这个问题实际上已经由前面的分析解答了:可以通过比较「3日open/0日close」和「1日open/0日close」大小,得出结论是:随着时间的推移,反转效应越发明显,即正股涨停后可转债呈下跌趋势;正股跌停后可转债呈上涨趋势。

1.4 构建简单策略

构建一个正股涨跌停当日close买入,后x日close/open卖出的策略。

1.3.1 正股跌停日close买入,后1日close/open卖出

更进一步观察该策略净值走势,发现「正股跌停当日close买入其可转债,次日close卖出」年化收益可达16.5%,但2023年中回撤高达近40%。 对比来看,「正股跌停当日close买入其可转债,次日open卖出」更为稳健,除了2023年年中的回撤之外,回撤均很小,年化收益也有12.2%。

而2023年中的回撤主要因为蓝盾转债(‌123015.SZ)面临强制退市带来的,关于这支可转债的情况可以简要看下面作者搜寻百度时截的图。这给我们带来的启示或许是,不要买卖ST股的可转债。

在删除这支“首个强退”股之后策略净值走势非常稳健,以「正股跌停当日close买入其可转债,次日open卖出」策略为例,最大回撤仅为8.4%,夏普比例高达2。但是策略在2023-2024年表现一般,这或许是因为在不同牛熊周期中信号的差异表现,进一步的研究可以拓展股市/债市情绪对策略信号有效性的影响。

1.3.2 正股跌停日close买入,后4日close/open卖出

考虑到「4日open/0日close」在之前的计算中拥有最高的平均收益,构建简单策略「正股跌停当日close买入(第0日),第4日open卖出」,策略表现非常亮眼——40倍,最大回撤为29.3%。

但是,策略「4日close/0日close」表现则比较逊色,最大回撤也高达38.9%。

1.3.3 正股涨停日close买入,后1日open卖出

由于涨停的其余情况下收益均值均为负,基本不可能产生好策略,故不考虑,只考虑「正股涨停日close买入,后1日open卖出」策略。

该策略最大回撤为19.7%,年化收益高达70%,夏普比例高达3.6,且策略信号持续稳定有效,是一个非常优秀的策略,甚至可以说是这5个策略中最好的一个。

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值