克隆策略
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])