事件驱动之ST扭亏摘帽分析

策略分享
st扭亏
摘帽扭亏
标签: #<Tag:0x00007fcf62cc9488> #<Tag:0x00007fcf62cc9348> #<Tag:0x00007fcf62cc9208>

(lilong) #1
  1. ST摘帽事件逻辑
    被实施ST的股票往往存在较为严重的财务问题或其他异常状况,股票风险较大;但是,当上市公司上述异常状况消除后,公司应当在董事会审议通过年度报告后及时向交易所报告并披露年度报告,同时可以申请撤销对其股票实施的退市风险警示,即“摘帽”。ST股票摘帽是一个利好事件,我们试图在其中挖掘超额收益。由于上市公司需定期披露财务报告和业绩预告,所以对财务原因被实施风险警示的股票的摘帽进行预测具有较好的操作性,本报告主要研究对财务原因被实施风险警示的股票的预测和潜伏。

  2. 已有研究成果
    这方面主要有如下两篇研报:
    【海通证券】事件驱动策略之十六:ST扭亏 2016.04.26
    【天风证券】潜伏系列之二:潜伏ST摘帽 2017.03.06
    海通证券的主要研究结论:
    (1) 在扭亏预告发布时提前介入非常有必要性;
    (2) 应挑选主营业务改善而扭亏的股票,避开资产重组或者借壳的股票;
    (3) 较好的操作方式为:在扭亏预告发布后买入,持有50个交易日后卖出。
    天风证券的主要研究结论:
    (1) 摘帽事件的盈利性主要集中在摘帽前,摘帽后样本较大幅度负的相对收益;
    (2) 较好的操作方式为:扭亏预告日开盘价买入,年报发布后日开盘价卖出。

  3. 分析方案
    (1) 分析对象
    针对 * ST股票
    由于业绩较差被实施退市风险警示的都是* ST,这部分公司在扭亏后存在较大的摘帽可能;而被实施其他风险警示ST的股票往往是监管机构认为公司存在严重问题,即使盈利也未必能脱帽,典型如000403 ST生化,由于债务问题,虽然连续多年盈利仍未脱帽。
    (2) 具体事件
    营业收入>1000万元,净利润>0,扣非后净利润>0
    前两条为脱帽的必要条件,对扣非后净利润的限制,主要是排除政府补贴、出售资产等扭亏情况,聚焦经营性业务改善导致的扭亏。
    (3) 时间点
    2月1日,财报发布日,摘帽日
    按照规定,发生扭亏情况需要发布业绩预告,而业绩预告通常在1月底发布,因此对三个时间区间的超额收益进行分析:2月1日~财报发布日,财报发布日~摘帽日,摘帽日~摘帽日之后10个交易日。
    如果6月1日前仍未摘帽,则对两个时间区间的超额收益进行分析:2月1日~财报发布日,财报发布日~6月1日。

  4. 分析程序

克隆策略
In [1]:
stocktobuy = pd.DataFrame(columns=['year','instrument','publish_date','tm_date','fs_net_profit','fs_deducted_profit','open0','open1','open2','open3','bench_open0','bench_open1','bench_open2','bench_open3'])
# 分别为:年份,股票,财报日,脱帽日(若没脱帽:NAN),净利润,扣非后净利润,2月1日(或之后最近交易日)开盘价,财报日开盘价,摘帽日开盘价,摘帽后第11个交易日开盘价,基准的2月1日开盘价,基准的财报日开盘价,基准的摘帽日开盘价,基准的摘帽后第10个交易日开盘价
for yy in range(2014,2018):
    tradeday = D.trading_days(market='CN', start_date='%d-02-01' %yy, end_date='%d-02-15' %yy)
    day0 = tradeday.iloc[0]['date']    # 获得该年份第一个交易日日期
    instruments = D.instruments(start_date='%d-02-01' %yy, end_date='%d-02-01' %yy, market='CN_STOCK_A')  # 获得股票列表
    alldata = D.history_data(instruments, start_date=day0, end_date=day0, fields=['st_status'], frequency='daily')
    ststock = alldata[alldata['st_status']==2]['instrument']  # 获得st股票列表
    
    for instrument0 in ststock:
        fData = D.financial_statements(instrument0, start_date='%d-01-01' %yy, end_date='%d-12-01' %yy,  \
                                     fields=['fs_quarter','fs_publish_date','fs_operating_revenue','fs_net_profit','fs_deducted_profit'])
        if len(fData)>0 and fData.iloc[0]['fs_net_profit']>0 and fData.iloc[0]['fs_deducted_profit']>0 and fData.iloc[0]['fs_operating_revenue']>1e7:     # 有望摘帽
            tmtime = D.history_data(instrument0, start_date='%d-02-01' %yy, end_date='%d-07-30' %yy, fields=['open','st_status','suspended'], frequency='daily')      # 获取开盘价及ST状态
            benchdata = D.history_data(instruments='000300.SHA', start_date='%d-02-01' %yy, end_date='%d-07-30' %yy, fields=['open'], frequency='daily')  # 获取基准数据           
            
            tmprow = {'year':(int)(yy),'instrument':instrument0,'publish_date':fData.iloc[0]['fs_publish_date'], \
                      'fs_net_profit':fData.iloc[0]['fs_net_profit'], \
                      'fs_deducted_profit':fData.iloc[0]['fs_deducted_profit'], \
                      'open1':tmtime[tmtime['date']>=fData.iloc[0]['fs_publish_date']].iloc[0]['open'], \
                      'bench_open1':benchdata[benchdata['date']>=fData.iloc[0]['fs_publish_date']].iloc[0]['open']}
            
            open0dates = tmtime[(tmtime['date']>='%d-02-01' %yy) & (tmtime['date']<fData.iloc[0]['fs_publish_date']) & (tmtime['suspended']==False)]
            if len(open0dates)>0:
                tmprow['open0'] = tmtime[tmtime['date']==open0dates.iloc[0]['date']].iloc[0]['open']
                tmprow['bench_open0'] = benchdata[benchdata['date']==open0dates.iloc[0]['date']].iloc[0]['open']
            else:
                tmprow['open0'] = np.nan
                tmprow['bench_open0'] = np.nan
                
            if len(tmtime[tmtime['st_status']==0])>10:  # 成功摘帽
                tmprow['tm_date'] = tmtime[tmtime['st_status']==0].iloc[0]['date']
                tmprow['open2'] = tmtime[tmtime['st_status']==0].iloc[0]['open']
                tmprow['open3'] = tmtime[tmtime['st_status']==0].iloc[10]['open']
                tmprow['bench_open2'] = benchdata[benchdata['date']>=tmtime[tmtime['st_status']==0].iloc[0]['date']].iloc[0]['open']
                tmprow['bench_open3'] = benchdata[benchdata['date']>=tmtime[tmtime['st_status']==0].iloc[10]['date']].iloc[0]['open']
            else:  # 未摘帽
                tmprow['tm_date'] = np.nan
                tmprow['open2'] = tmtime[tmtime['date']>='%d-06-01' %yy].iloc[0]['open']
                tmprow['bench_open2'] = benchdata[benchdata['date']>='%d-06-01' %yy].iloc[0]['open']
            #print(tmprow)
            stocktobuy=stocktobuy.append(tmprow,ignore_index=True)
In [2]:
stocktobuy['gain0']=np.nan
stocktobuy['gain1']=np.nan
stocktobuy['gain2']=np.nan
stocktobuy['gain0']=100*(stocktobuy['open1']/stocktobuy['open0']-1)-100*(stocktobuy['bench_open1']/stocktobuy['bench_open0']-1)   # 2月1日至财报公布日超额收益
stocktobuy['gain1']=100*(stocktobuy['open2']/stocktobuy['open1']-1)-100*(stocktobuy['bench_open2']/stocktobuy['bench_open1']-1)   # 财报公布日至摘帽日超额收益,微摘帽则为到6月1日
stocktobuy['gain2']=100*(stocktobuy['open3']/stocktobuy['open2']-1)-100*(stocktobuy['bench_open3']/stocktobuy['bench_open2']-1)   # 摘帽后10个交易日超额收益
stocktobuy = stocktobuy.dropna(subset=["open1"])
stocktobuy
Out[2]:
year instrument publish_date tm_date fs_net_profit fs_deducted_profit open0 open1 open2 open3 bench_open0 bench_open1 bench_open2 bench_open3 gain0 gain1 gain2
0 2014.0 000017.SZA 2014-04-28 2014-05-14 1.575224e+09 4.360002e+06 15.211124 16.525665 16.337875 14.942851 2187.343018 2165.772949 2175.093994 2147.467041 9.628101 -1.566733 -7.268441
1 2014.0 000403.SZA 2014-04-30 NaT 7.028026e+07 4.970497e+07 66.632233 74.940178 71.650734 NaN 2187.343018 2158.761963 2157.639893 NaN 13.775014 -4.337449 NaN
2 2014.0 000555.SZA 2014-03-26 2014-03-19 2.547188e+08 2.314446e+08 41.930191 42.473728 50.455994 37.022804 2187.343018 2181.230957 2131.282959 2166.066895 1.575719 21.083318 -28.255641
3 2014.0 000557.SZA 2014-04-29 NaT 3.581990e+06 5.096861e+06 NaN 51.297085 51.297085 NaN NaN 2134.413086 2157.639893 NaN NaN -1.088206 NaN
5 2014.0 000898.SZA 2014-03-31 2014-04-10 7.700000e+08 6.950000e+08 5.897456 6.039319 6.019053 6.100117 2187.343018 2156.053955 2241.451904 2192.769043 3.835953 -4.296413 3.518736
6 2014.0 000958.SZA 2014-03-21 2014-04-03 6.682861e+08 4.822158e+07 10.301632 14.452711 17.734455 15.952315 2187.343018 2079.871094 2188.642090 2215.878906 45.208710 17.477072 -11.293487
8 2014.0 600556.SHA 2014-04-29 2014-05-08 3.264480e+07 1.083073e+06 16.638863 21.176735 21.176735 21.176735 2187.343018 2134.413086 2132.035889 2134.086914 29.692559 0.111375 -0.096200
9 2014.0 600617.SHA 2014-03-15 2014-03-25 3.078519e+08 3.193790e+08 506.092194 564.601379 554.973267 554.973267 2187.343018 2132.792969 2170.780029 2239.791016 14.054869 -3.486388 -3.179087
11 2015.0 000755.SZA 2015-04-24 2015-05-07 5.859313e+07 2.240897e+07 NaN 13.731359 18.376921 22.586159 NaN 4682.625977 4520.817871 4768.688965 NaN 37.287273 17.422142
12 2015.0 000822.SZA 2015-03-07 2015-03-24 1.652635e+08 5.826694e+07 12.346785 15.624295 19.305882 20.203831 3360.193115 3449.696045 3980.065918 4277.450195 23.881834 8.188821 -2.820674
13 2015.0 002160.SZA 2015-03-12 2015-03-20 2.139730e+07 1.775764e+07 15.546689 17.866484 20.756052 21.020590 3305.733887 3557.686035 3852.491943 4104.671875 7.299800 7.886672 -5.271382
14 2015.0 002217.SZA 2015-03-31 2015-04-14 1.472241e+08 1.145308e+08 29.962175 37.452717 47.738243 44.468117 3458.826904 4138.884766 4432.125977 4811.318848 5.338474 20.377668 -15.405671
15 2015.0 002234.SZA 2015-03-20 2015-04-03 6.268806e+07 2.166721e+07 20.461079 27.323027 27.926046 25.534761 3360.193115 3852.491943 4104.671875 4615.034180 18.885681 -4.338889 -20.996613
17 2015.0 600282.SHA 2015-01-31 2015-02-10 2.919272e+08 1.151104e+08 NaN 20.460703 18.435946 19.128626 NaN 3360.193115 3345.076904 3579.314941 NaN -9.445974 -3.245244
18 2015.0 600598.SHA 2015-03-31 2015-04-03 7.998076e+08 2.092850e+08 25.297302 32.988190 35.996746 37.606960 3360.193115 4138.884766 4104.671875 4615.034180 7.227992 9.946722 -7.960471
20 2016.0 000059.SZA 2016-03-24 2016-04-20 3.286855e+08 2.624604e+08 8.241914 11.376594 12.997452 13.379730 2939.040039 3211.496094 3244.141846 3204.168701 28.763157 13.230779 4.173344
21 2016.0 000590.SZA 2016-03-26 2016-04-12 2.237228e+07 1.812841e+07 79.792946 107.660934 108.137306 94.989334 2939.040039 3206.953125 3227.367188 3159.770508 25.809712 -0.194082 -10.064107
22 2016.0 000799.SZA 2016-04-08 2016-04-25 8.856958e+07 8.003818e+07 25.691389 33.031784 30.651115 35.908428 2939.040039 3189.845703 3164.738281 3055.211914 20.037830 -6.420101 20.612944
23 2016.0 000892.SZA 2016-02-06 2016-02-25 1.300261e+06 1.295881e+06 37.290600 39.851223 46.662971 38.434177 2939.040039 2888.427734 3104.409668 3056.210449 8.588741 9.615456 -16.081922
24 2016.0 002192.SZA 2016-01-22 2016-02-05 8.903995e+06 6.663078e+06 NaN 81.062553 91.911530 86.954323 NaN 2939.040039 2982.056396 2942.095459 NaN 11.919843 -4.053408
25 2016.0 600217.SHA 2016-03-01 2016-03-09 1.751484e+08 1.665767e+08 33.386765 37.723881 37.497990 38.943695 2939.040039 2881.335205 3045.923828 3217.728760 14.953916 -6.311036 -1.785066
26 2016.0 600444.SHA 2016-04-15 2016-04-25 3.019732e+07 1.547025e+07 35.025105 44.379761 41.846622 34.546402 2939.040039 3279.856689 3164.738281 3055.211914 15.112243 -2.198007 -13.984350
27 2016.0 600644.SHA 2016-03-02 2016-03-10 1.155167e+08 3.008352e+07 77.838318 87.713326 88.875092 90.269211 2939.040039 2933.920898 3056.210449 3211.496094 12.860741 -2.843624 -3.512359
28 2016.0 600715.SHA 2016-03-04 2016-03-14 1.378161e+08 1.210336e+08 60.590858 80.275688 78.739311 82.580254 2939.040039 3047.537109 3039.568848 3206.953125 28.796536 -1.652410 -0.628794
29 2016.0 600779.SHA 2016-04-28 2016-05-09 8.797362e+07 8.972771e+07 61.944408 80.341896 83.005508 81.394958 2939.040039 3169.333252 3115.430176 3078.514893 21.864336 5.016117 -0.755375
30 2016.0 600870.SHA 2016-03-26 2016-04-06 1.399027e+07 3.297591e+06 47.713654 59.786777 59.786777 59.786777 2939.040039 3206.953125 3250.521484 3244.141846 16.187623 -1.358559 0.196265
33 2017.0 000408.SZA 2017-04-18 2017-05-22 9.118098e+08 9.034779e+08 82.769035 89.415131 83.997726 75.620293 3390.931396 3474.889160 3400.588135 3493.884521 5.553738 -3.920484 -12.716942
34 2017.0 000606.SZA 2017-02-28 2017-03-13 4.581831e+07 2.346286e+07 69.971519 77.187737 81.440155 75.125961 3390.931396 3445.027344 3425.672363 3488.764648 8.717765 6.071013 -9.594919
35 2017.0 000670.SZA 2017-03-14 2017-03-29 2.417171e+07 1.434842e+07 77.188034 80.719513 81.022209 72.647560 3361.781006 3456.658447 3472.966553 3516.810303 1.752926 -0.096791 -11.598668
36 2017.0 000933.SZA 2017-04-11 2017-05-02 3.421392e+08 3.578996e+08 78.734535 88.350967 84.023575 75.368782 3390.931396 3503.829346 3427.916992 3390.925049 8.884333 -2.731403 -9.221296
37 2017.0 000968.SZA 2017-04-25 2017-05-15 3.844572e+08 3.784766e+08 19.905403 26.304897 26.788580 24.184134 3390.931396 3427.732178 3391.588135 3495.072998 31.064263 2.893214 -12.773448
38 2017.0 002061.SZA 2017-02-27 2017-03-13 6.627971e+07 4.691460e+07 NaN 19.035215 19.035215 19.035215 NaN 3471.131836 3425.672363 3488.764648 NaN 1.309644 -1.841749
39 2017.0 002173.SZA 2017-03-31 2017-04-21 1.147135e+08 1.083851e+08 58.882645 60.965115 55.743847 48.289200 3390.931396 3434.822266 3461.388916 3369.108398 2.242284 -9.337804 -10.707043
40 2017.0 002379.SZA 2017-04-28 2017-05-24 1.415061e+07 1.420314e+07 61.248993 45.856575 61.730007 75.599213 3452.990479 3439.573486 3409.716797 3561.241211 -24.742330 35.483424 18.023626
41 2017.0 002513.SZA 2017-03-21 2017-04-07 1.071806e+08 9.124791e+07 45.234570 48.505974 48.505974 48.505974 3390.931396 3449.769531 3514.452148 3461.388916 5.496927 -1.874984 1.509858
42 2017.0 600212.SHA 2017-02-14 2017-02-23 4.455113e+07 4.443375e+07 NaN 27.075613 27.075613 27.075613 NaN 3438.510986 3487.574463 3442.895264 NaN -1.426881 1.281097
43 2017.0 600230.SHA 2017-03-07 2017-03-15 3.710639e+08 3.558548e+08 34.832039 45.031555 43.841362 39.592815 3390.931396 3446.162842 3452.213867 3472.966553 27.653198 -2.818608 -10.291868
44 2017.0 600390.SHA 2017-04-26 2017-05-04 1.557058e+09 7.944906e+07 63.050385 67.494469 70.364601 55.180660 3390.931396 3440.252686 3404.937988 3387.665527 5.593959 5.278911 -21.071671
45 2017.0 600603.SHA 2017-03-18 2017-03-28 2.468711e+08 2.790198e+08 1055.274780 1316.982910 1343.076904 1204.931885 3390.931396 3449.051514 3480.249023 3500.283691 23.086012 1.076822 -10.861379
46 2017.0 600675.SHA 2017-02-22 2017-03-02 6.554582e+08 8.870032e+07 228.954987 251.818741 278.493103 243.562378 3390.931396 3483.200684 3463.482910 3472.269287 7.265075 11.158766 -12.796447
49 2017.0 601918.SHA 2017-03-17 2017-03-27 2.417364e+08 3.033473e+07 6.992698 8.442588 8.759751 7.294759 3390.931396 3485.311279 3488.764648 3514.572266 17.951035 3.657626 -17.463869
In [5]:
print(stocktobuy.mean()[-3:])
print(stocktobuy.std()[-3:])
gain0    14.111392
gain1     3.837212
gain2    -5.919476
dtype: float64
gain0    12.336953
gain1    10.572346
gain2    10.229922
dtype: float64
In [21]:
# 胜率
np.round([len(stocktobuy[stocktobuy['gain0']>0])/len(stocktobuy[stocktobuy['gain0']>-100]),len(stocktobuy[stocktobuy['gain1']>0])/len(stocktobuy[stocktobuy['gain1']>-100]),len(stocktobuy[stocktobuy['gain2']>0])/len(stocktobuy[stocktobuy['gain2']>-100])],2)
Out[21]:
array([ 0.97,  0.49,  0.21])
  1. 结论:
    (1) 预告公布后,正式财报公布前,有较为稳定的超额收益,胜率达到了97%;
    (2) 财报公布后,摘帽公布前,涨跌互有;
    (3) 摘帽公布后,多为负收益。

(upndown) #2

抢占沙发,期待更多分享!