十字星形态的简单研究

上周看了方正金工的《夜空中最亮的星:十字星形态的选股研究》,这里简单实现一下

这里比较可惜的是得到的样本比较少,计算又超慢········

所谓十字星,就是指实体柱很短、上下影线较长的蜡烛图形态。这里认为是多空双方争夺激烈、僵持不下,前期趋势已成强弩之末,趋势反转即将来临。以底部十字星为例,在股票价格经历较长下跌之后,如果出现十字星形态,表明市场空方力量已开始衰竭,多方在逐步蓄积反攻的力量,多空博弈从空方占优演变为势均力敌,股价走势转向的可能性也迅速升高。

超额十字星的计算方法

为了定义超额十字星,我们首先需计算每只股票的超额蜡烛图(或称超额K线)。对于特定股票第T日的超额蜡烛图,其计算步骤如下:
(1)以股票第T-1日的收盘价P(T-1,Close)为基准,计算股票第T日中截止至第t分钟的累积收益率:Rs(T,t) = P(T,t)/P(T-1,Close)-1;
(2)以指数第T-1日的收盘价Q(T-1,Close)为基准,计算指数第T日中截止至第t分钟的累积收益率:Ri(T,t) = Q(T,t)/Q(T-1,Close)-1;
(3)基于上述两个变量,计算股票第T日中第t分钟的累积超额收益:Re(T,t)= Rs(T,t)-Ri_(T,t);
(4)取第T日累积超额收益的开盘值、最高值、最低值、收盘值,构成第T日的超额蜡烛图。

In [2]:
#库导入
import pandas as pd
import numpy as np
import time
import datetime
import seaborn as sns
In [3]:
#计算一支股票在一定时间内每一天的超额收益十字星
def abnormal_return(stk,index,startdate,enddate):
    tradingdates = get_trading_dates(start_date=startdate, end_date=enddate)
    for date in tradingdates:
        Tday= get_price(stk, start_date=date, end_date=date, frequency='1m', fields='ClosingPx')
        lastday = get_price(stk, start_date=get_previous_trading_date(date), end_date=get_previous_trading_date(date), frequency='1d', fields='ClosingPx')
        Rs = Tday/lastday.values-1
        index_Tday= get_price(index, start_date=date,end_date=date, frequency='1m', fields='ClosingPx')
        index_lastday = get_price(index, start_date=get_previous_trading_date(date), end_date=get_previous_trading_date(date), frequency='1d', fields='ClosingPx')
        Ri =index_Tday/index_lastday.values-1
        Re = Rs - Ri
        
        if date == tradingdates[0]:
            dates = pd.date_range(date,periods=1)
            df = pd.DataFrame(index=dates,columns=['open','close','high','low','bar','upline','downline'])
            df['high'] =  Re.max()
            df['low'] = Re.min()
            df['open'] = Re.ix[0]
            df['close'] = Re.ix[-1]
            df.ix[dates,'bar'] = abs(Re.ix[0]-Re.ix[-1])
            if Re.ix[0]>Re.ix[-1]:
                df.ix[dates,'upline'] = Re.max()-Re.ix[0]
                df.ix[dates,'downline'] = Re.ix[-1] - Re.min()
            else:
                df.ix[dates,'upline'] = Re.max()-Re.ix[-1]
                df.ix[dates,'downline'] = Re.ix[0] - Re.min()
                
        else:
            dates = pd.date_range(date,periods=1)
            df_1 = pd.DataFrame(index=dates,columns=['open','close','high','low','bar','upline','downline'])
            df_1['high'] =  Re.max()
            df_1['low'] = Re.min()
            df_1['open'] = Re.ix[0]
            df_1['close'] = Re.ix[-1]
            df_1.ix[dates,'bar'] = abs(Re.ix[0]-Re.ix[-1])
            df = pd.concat([df,df_1],axis=0)
            if Re.ix[0]>Re.ix[-1]:
                df.ix[dates,'upline'] = Re.max()-Re.ix[0]
                df.ix[dates,'downline'] = Re.ix[-1] - Re.min()
            else:
                df.ix[dates,'upline'] = Re.max()-Re.ix[-1]
                df.ix[dates,'downline'] = Re.ix[0] - Re.min()
            
    return df
        
In [4]:
#识别个股十字星
def distinguish_star(df):
    #方便计算前后收益
    df['No'] = np.arange(1, len(df)+1)
    #识别符合条件的十字星
    df_eligible = df[df.bar<0.001]
    df_eligible = df_eligible[df_eligible.upline>df_eligible.bar*3]
    df_eligible = df_eligible[df_eligible.downline>df_eligible.bar*3]
    #前20日超额涨幅
    for i in df_eligible.index:
        b=df_eligible.loc[i,'No']
        if b > 20 :
            i_20 = df[df.No == b - 20].index
            a_0 = df.loc[i,'close']
            a_20 = df.loc[i_20,'close'].values
            df_eligible.loc[i,'pre20'] = a_0 - a_20
    #前20日超额涨幅
    for i in df_eligible.index:
        b=df_eligible.loc[i,'No']
        if  b < df.ix[-1,'No']-20:
            i_20 = df[df.No == b + 20].index
            a_0 = df.loc[i,'close']
            a_20 = df.loc[i_20,'close'].values
            df_eligible.loc[i,'next20'] = a_0 - a_20
    #前后都缺一个数据,砍头去尾
    #df_eligible = df_eligible.ix[1:-1]
    return df_eligible
In [6]:
stocks = index_components('399905.XSHE')
index =  '399905.XSHE'#中证500
startdate = '2016-9-1'
enddate = '2016-11-25'
df = pd.DataFrame()
for stk in stocks:
    a = abnormal_return(stk, index,startdate,enddate)
    a = distinguish_star(a)
    df = pd.concat([df, a], axis=0)
df
Out[6]:
No bar close downline high low next20 open pre20 upline
2016-10-18 27 0.00079774 -0.003770 0.00249208 0.008187 -0.006262 -0.005002 -0.002972 0.001894 0.0111595
2016-10-21 30 0.000970781 0.001413 0.00504358 0.006563 -0.003631 0.010432 0.002383 -0.010142 0.00418013
2016-10-27 34 0.000818754 0.004157 0.00332732 0.012912 0.000829 0.013692 0.004975 0.007205 0.00793644
2016-11-15 47 0.000267991 0.001232 0.00740224 0.002138 -0.006438 NaN 0.000964 0.005002 0.000906188
2016-09-12 8 0.000636764 0.001410 0.012914 0.005389 -0.011504 -0.000744 0.002047 NaN 0.00334192
2016-09-21 13 0.000564488 -0.003969 0.00486459 0.000500 -0.008833 -0.030573 -0.003404 NaN 0.00390405
2016-10-18 27 0.000214608 0.003807 0.00628861 0.007978 -0.002696 0.011139 0.003592 0.007759 0.00417093
2016-11-01 37 0.000138128 -0.001252 0.00456401 0.005113 -0.005816 NaN -0.001114 0.015419 0.00622715
2016-11-02 38 0.000211409 -0.002675 0.0071915 -0.000543 -0.009867 NaN -0.002464 0.004020 0.00192073
2016-11-07 41 0.000305295 0.000848 0.00701669 0.005692 -0.006168 NaN 0.001154 -0.001203 0.0045387
2016-10-14 25 0.000845177 -0.000488 0.00356247 0.009963 -0.004050 0.030127 0.000357 -0.011280 0.00960517
2016-10-20 29 0.000700113 -0.003276 0.0155403 0.002995 -0.018816 -0.006919 -0.002576 0.016067 0.00557018
2016-11-24 54 0.000586006 -0.004261 0.00522788 0.001193 -0.009489 NaN -0.003675 0.018970 0.0048682
2016-09-08 6 0.000105506 -0.000450 0.00607526 0.007156 -0.006525 0.007919 -0.000344 NaN 0.00750053
2016-09-21 13 0.000564488 -0.003377 0.00545054 0.005326 -0.008828 0.010758 -0.002813 NaN 0.00813856
2016-10-14 25 0.000369214 0.004267 0.00896215 0.025011 -0.004696 -0.011524 0.004636 -0.003037 0.0203752
2016-10-20 29 0.00023063 0.000511 0.0135073 0.013321 -0.012996 -0.067991 0.000742 -0.048191 0.0125796
2016-10-24 31 0.000727063 -0.005178 0.00838323 0.001363 -0.014288 -0.005292 -0.005905 -0.036011 0.00654016
2016-10-12 23 3.48944e-05 0.000568 0.00690284 0.003820 -0.006369 -0.010141 0.000533 0.006049 0.00325187
2016-11-02 38 0.000659388 0.000575 0.00797619 0.003527 -0.008061 NaN -0.000085 0.004066 0.00295236
2016-11-11 45 0.000193605 -0.001089 0.00256766 0.003306 -0.003851 NaN -0.001283 0.007974 0.0043954
2016-11-18 50 0.000641578 0.000647 0.00764976 0.006352 -0.007644 NaN 0.000005 0.002954 0.00570539
2016-11-25 55 0.000100626 -0.004495 0.00260213 0.007634 -0.007097 NaN -0.004394 0.005382 0.0120279
2016-09-05 3 0.00020701 -0.003016 0.0043616 -0.000573 -0.007378 -0.008153 -0.002809 NaN 0.00223569
2016-09-14 10 0.000829046 0.002123 0.00548877 0.008352 -0.003366 0.006859 0.002952 NaN 0.00540016
2016-10-19 28 0.000776833 0.000612 0.00469935 0.005156 -0.004864 -0.006480 -0.000164 -0.003246 0.00454413
2016-11-07 41 0.000305295 -0.002535 0.0112942 0.003538 -0.013829 NaN -0.002229 0.034357 0.00576718
2016-11-08 42 0.000579561 -0.002164 0.00544842 0.003421 -0.007612 NaN -0.001584 0.001299 0.00500517
2016-11-09 43 0.000404826 -0.000740 0.00124617 0.010240 -0.001986 NaN -0.000335 -0.005877 0.0105754
2016-11-17 49 0.000716673 -0.002889 0.00742067 0.002564 -0.010310 NaN -0.002172 0.001174 0.00473643
2016-09-29 19 0.000405036 0.005248 0.00857541 0.009771 -0.003732 0.002637 0.004843 NaN 0.00452285
2016-10-10 21 0.000353476 -0.000871 0.00492891 0.001998 -0.005800 -0.012189 -0.000518 0.005951 0.00251583
2016-10-11 22 0.000893326 -0.002983 0.00294019 0.005045 -0.006817 0.006228 -0.003877 -0.005929 0.00802837
2016-11-01 37 0.000513696 0.003787 0.00332305 0.008657 -0.000049 NaN 0.003274 0.007069 0.0048698
2016-11-04 40 0.000221849 -0.000236 0.00261349 0.002844 -0.003072 NaN -0.000458 -0.002671 0.00308066
2016-11-21 51 0.000401302 -0.000547 0.00694253 0.003594 -0.007489 NaN -0.000146 -0.006729 0.00374009
2016-09-29 19 4.13928e-05 -0.002787 0.00617661 0.003703 -0.008964 -0.014448 -0.002746 NaN 0.00644853
2016-10-10 21 0.000586688 -0.002809 0.00825505 0.003330 -0.011651 -0.001846 -0.003396 -0.003616 0.00613935
2016-10-31 36 4.9729e-05 -0.001628 0.00403167 0.013651 -0.005709 NaN -0.001678 -0.015054 0.0152788
2016-11-01 37 0.00053519 0.002917 0.00402879 0.014210 -0.001112 NaN 0.003452 0.005603 0.0107579
2016-09-02 2 0.000854168 0.000524 0.00902901 0.004768 -0.009359 0.001063 -0.000330 NaN 0.0042435
2016-09-21 13 0.000257833 0.000035 0.00455663 0.004762 -0.004522 -0.007117 0.000293 NaN 0.00446928
2016-09-22 14 0.000494773 -0.001697 0.00362974 0.007605 -0.005327 -0.000656 -0.001202 NaN 0.00880745
2016-09-28 18 0.000565111 0.000581 0.00406779 0.005105 -0.003486 0.003188 0.001147 NaN 0.00395864
2016-09-29 19 4.13928e-05 -0.000279 0.00292331 0.009352 -0.003203 -0.002042 -0.000238 NaN 0.0095905
2016-10-10 21 0.000575985 0.002825 0.00304836 0.007299 -0.000800 0.000411 0.002249 0.014439 0.00447417
2016-10-24 31 0.000760739 -0.003781 0.00282309 0.000378 -0.007365 -0.019246 -0.004542 0.003395 0.00415886
2016-10-27 34 0.000895743 -0.001041 0.00390836 0.003683 -0.004949 -0.004304 -0.000145 0.000656 0.00382803
2016-11-03 39 0.000534562 0.001763 0.00312974 0.008293 -0.001367 NaN 0.002297 0.002042 0.00599582
2016-11-24 54 0.000213575 0.003263 0.00553358 0.005765 -0.002271 NaN 0.003477 0.004304 0.00228796
2016-09-12 8 5.17113e-05 -0.007713 0.00675064 0.005134 -0.014464 -0.047022 -0.007661 NaN 0.0127952
2016-09-19 11 0.00021113 0.002253 0.0101472 0.007446 -0.008105 -0.001974 0.002042 NaN 0.00519277
2016-09-27 17 0.000428801 -0.005663 0.00498969 0.001271 -0.011081 -0.001716 -0.006092 NaN 0.00693369
2016-09-12 8 0.000539117 -0.011235 0.00905839 -0.007475 -0.020293 -0.001961 -0.010696 NaN 0.0032207
2016-09-14 10 0.000328796 -0.001067 0.0096075 0.004199 -0.010674 0.003107 -0.000738 NaN 0.00493743
2016-10-26 33 0.000189334 0.001176 0.00405326 0.006450 -0.002877 0.010020 0.001365 0.012747 0.00508488
2016-11-01 37 0.000489511 0.001344 0.0048214 0.006146 -0.003967 NaN 0.000854 -0.013650 0.00480187
2016-11-10 44 0.000318871 -0.002922 0.00446798 0.001373 -0.007390 NaN -0.002603 -0.033727 0.00397611
2016-11-11 45 0.000504047 0.012624 0.00349084 0.038857 0.008629 NaN 0.012120 0.015919 0.0262325
2016-11-18 50 0.000674624 -0.002607 0.00560334 0.002171 -0.008211 NaN -0.001933 0.001567 0.00410374

2003 rows × 10 columns

In [8]:
len(df)
Out[8]:
22
In [7]:
#把数据存起来
df.to_csv('十字星蜡烛图.csv')
In [8]:
#读取数据
from six import StringIO
from six import BytesIO
body = get_file('十字星蜡烛图.csv')
data=pd.read_csv(BytesIO(body))
data
Out[8]:
Unnamed: 0 No bar close downline high low next20 open pre20 upline
0 2016-10-18 27 0.000798 -0.003770 0.002492 0.008187 -0.006262 -0.005002 -0.002972 0.001894 0.011159
1 2016-10-21 30 0.000971 0.001413 0.005044 0.006563 -0.003631 0.010432 0.002383 -0.010142 0.004180
2 2016-10-27 34 0.000819 0.004157 0.003327 0.012912 0.000829 0.013692 0.004975 0.007205 0.007936
3 2016-11-15 47 0.000268 0.001232 0.007402 0.002138 -0.006438 NaN 0.000964 0.005002 0.000906
4 2016-09-12 8 0.000637 0.001410 0.012914 0.005389 -0.011504 -0.000744 0.002047 NaN 0.003342
5 2016-09-21 13 0.000564 -0.003969 0.004865 0.000500 -0.008833 -0.030573 -0.003404 NaN 0.003904
6 2016-10-18 27 0.000215 0.003807 0.006289 0.007978 -0.002696 0.011139 0.003592 0.007759 0.004171
7 2016-11-01 37 0.000138 -0.001252 0.004564 0.005113 -0.005816 NaN -0.001114 0.015419 0.006227
8 2016-11-02 38 0.000211 -0.002675 0.007191 -0.000543 -0.009867 NaN -0.002464 0.004020 0.001921
9 2016-11-07 41 0.000305 0.000848 0.007017 0.005692 -0.006168 NaN 0.001154 -0.001203 0.004539
10 2016-10-14 25 0.000845 -0.000488 0.003562 0.009963 -0.004050 0.030127 0.000357 -0.011280 0.009605
11 2016-10-20 29 0.000700 -0.003276 0.015540 0.002995 -0.018816 -0.006919 -0.002576 0.016067 0.005570
12 2016-11-24 54 0.000586 -0.004261 0.005228 0.001193 -0.009489 NaN -0.003675 0.018970 0.004868
13 2016-09-08 6 0.000106 -0.000450 0.006075 0.007156 -0.006525 0.007919 -0.000344 NaN 0.007501
14 2016-09-21 13 0.000564 -0.003377 0.005451 0.005326 -0.008828 0.010758 -0.002813 NaN 0.008139
15 2016-10-14 25 0.000369 0.004267 0.008962 0.025011 -0.004696 -0.011524 0.004636 -0.003037 0.020375
16 2016-10-20 29 0.000231 0.000511 0.013507 0.013321 -0.012996 -0.067991 0.000742 -0.048191 0.012580
17 2016-10-24 31 0.000727 -0.005178 0.008383 0.001363 -0.014288 -0.005292 -0.005905 -0.036011 0.006540
18 2016-10-12 23 0.000035 0.000568 0.006903 0.003820 -0.006369 -0.010141 0.000533 0.006049 0.003252
19 2016-11-02 38 0.000659 0.000575 0.007976 0.003527 -0.008061 NaN -0.000085 0.004066 0.002952
20 2016-11-11 45 0.000194 -0.001089 0.002568 0.003306 -0.003851 NaN -0.001283 0.007974 0.004395
21 2016-11-18 50 0.000642 0.000647 0.007650 0.006352 -0.007644 NaN 0.000005 0.002954 0.005705
22 2016-11-25 55 0.000101 -0.004495 0.002602 0.007634 -0.007097 NaN -0.004394 0.005382 0.012028
23 2016-09-05 3 0.000207 -0.003016 0.004362 -0.000573 -0.007378 -0.008153 -0.002809 NaN 0.002236
24 2016-09-14 10 0.000829 0.002123 0.005489 0.008352 -0.003366 0.006859 0.002952 NaN 0.005400
25 2016-10-19 28 0.000777 0.000612 0.004699 0.005156 -0.004864 -0.006480 -0.000164 -0.003246 0.004544
26 2016-11-07 41 0.000305 -0.002535 0.011294 0.003538 -0.013829 NaN -0.002229 0.034357 0.005767
27 2016-11-08 42 0.000580 -0.002164 0.005448 0.003421 -0.007612 NaN -0.001584 0.001299 0.005005
28 2016-11-09 43 0.000405 -0.000740 0.001246 0.010240 -0.001986 NaN -0.000335 -0.005877 0.010575
29 2016-11-17 49 0.000717 -0.002889 0.007421 0.002564 -0.010310 NaN -0.002172 0.001174 0.004736
1973 2016-09-29 19 0.000405 0.005248 0.008575 0.009771 -0.003732 0.002637 0.004843 NaN 0.004523
1974 2016-10-10 21 0.000353 -0.000871 0.004929 0.001998 -0.005800 -0.012189 -0.000518 0.005951 0.002516
1975 2016-10-11 22 0.000893 -0.002983 0.002940 0.005045 -0.006817 0.006228 -0.003877 -0.005929 0.008028
1976 2016-11-01 37 0.000514 0.003787 0.003323 0.008657 -0.000049 NaN 0.003274 0.007069 0.004870
1977 2016-11-04 40 0.000222 -0.000236 0.002613 0.002844 -0.003072 NaN -0.000458 -0.002671 0.003081
1978 2016-11-21 51 0.000401 -0.000547 0.006943 0.003594 -0.007489 NaN -0.000146 -0.006729 0.003740
1979 2016-09-29 19 0.000041 -0.002787 0.006177 0.003703 -0.008964 -0.014448 -0.002746 NaN 0.006449
1980 2016-10-10 21 0.000587 -0.002809 0.008255 0.003330 -0.011651 -0.001846 -0.003396 -0.003616 0.006139
1981 2016-10-31 36 0.000050 -0.001628 0.004032 0.013651 -0.005709 NaN -0.001678 -0.015054 0.015279
1982 2016-11-01 37 0.000535 0.002917 0.004029 0.014210 -0.001112 NaN 0.003452 0.005603 0.010758
1983 2016-09-02 2 0.000854 0.000524 0.009029 0.004768 -0.009359 0.001063 -0.000330 NaN 0.004243
1984 2016-09-21 13 0.000258 0.000035 0.004557 0.004762 -0.004522 -0.007117 0.000293 NaN 0.004469
1985 2016-09-22 14 0.000495 -0.001697 0.003630 0.007605 -0.005327 -0.000656 -0.001202 NaN 0.008807
1986 2016-09-28 18 0.000565 0.000581 0.004068 0.005105 -0.003486 0.003188 0.001147 NaN 0.003959
1987 2016-09-29 19 0.000041 -0.000279 0.002923 0.009352 -0.003203 -0.002042 -0.000238 NaN 0.009590
1988 2016-10-10 21 0.000576 0.002825 0.003048 0.007299 -0.000800 0.000411 0.002249 0.014439 0.004474
1989 2016-10-24 31 0.000761 -0.003781 0.002823 0.000378 -0.007365 -0.019246 -0.004542 0.003395 0.004159
1990 2016-10-27 34 0.000896 -0.001041 0.003908 0.003683 -0.004949 -0.004304 -0.000145 0.000656 0.003828
1991 2016-11-03 39 0.000535 0.001763 0.003130 0.008293 -0.001367 NaN 0.002297 0.002042 0.005996
1992 2016-11-24 54 0.000214 0.003263 0.005534 0.005765 -0.002271 NaN 0.003477 0.004304 0.002288
1993 2016-09-12 8 0.000052 -0.007713 0.006751 0.005134 -0.014464 -0.047022 -0.007661 NaN 0.012795
1994 2016-09-19 11 0.000211 0.002253 0.010147 0.007446 -0.008105 -0.001974 0.002042 NaN 0.005193
1995 2016-09-27 17 0.000429 -0.005663 0.004990 0.001271 -0.011081 -0.001716 -0.006092 NaN 0.006934
1996 2016-09-12 8 0.000539 -0.011235 0.009058 -0.007475 -0.020293 -0.001961 -0.010696 NaN 0.003221
1997 2016-09-14 10 0.000329 -0.001067 0.009608 0.004199 -0.010674 0.003107 -0.000738 NaN 0.004937
1998 2016-10-26 33 0.000189 0.001176 0.004053 0.006450 -0.002877 0.010020 0.001365 0.012747 0.005085
1999 2016-11-01 37 0.000490 0.001344 0.004821 0.006146 -0.003967 NaN 0.000854 -0.013650 0.004802
2000 2016-11-10 44 0.000319 -0.002922 0.004468 0.001373 -0.007390 NaN -0.002603 -0.033727 0.003976
2001 2016-11-11 45 0.000504 0.012624 0.003491 0.038857 0.008629 NaN 0.012120 0.015919 0.026232
2002 2016-11-18 50 0.000675 -0.002607 0.005603 0.002171 -0.008211 NaN -0.001933 0.001567 0.004104

2003 rows × 11 columns

In [11]:
data = data[data.pre20 < 0]
data
Out[11]:
Unnamed: 0 No bar close downline high low next20 open pre20 upline
1 2016-10-21 30 0.000971 0.001413 0.005044 0.006563 -0.003631 0.010432 0.002383 -0.010142 0.004180
9 2016-11-07 41 0.000305 0.000848 0.007017 0.005692 -0.006168 NaN 0.001154 -0.001203 0.004539
10 2016-10-14 25 0.000845 -0.000488 0.003562 0.009963 -0.004050 0.030127 0.000357 -0.011280 0.009605
15 2016-10-14 25 0.000369 0.004267 0.008962 0.025011 -0.004696 -0.011524 0.004636 -0.003037 0.020375
16 2016-10-20 29 0.000231 0.000511 0.013507 0.013321 -0.012996 -0.067991 0.000742 -0.048191 0.012580
17 2016-10-24 31 0.000727 -0.005178 0.008383 0.001363 -0.014288 -0.005292 -0.005905 -0.036011 0.006540
25 2016-10-19 28 0.000777 0.000612 0.004699 0.005156 -0.004864 -0.006480 -0.000164 -0.003246 0.004544
28 2016-11-09 43 0.000405 -0.000740 0.001246 0.010240 -0.001986 NaN -0.000335 -0.005877 0.010575
32 2016-11-16 48 0.000515 0.002750 0.007597 0.011324 -0.004846 NaN 0.003265 -0.001860 0.008059
33 2016-10-18 27 0.000583 -0.012786 0.002551 0.001859 -0.015338 -0.014888 -0.012203 -0.035546 0.014062
40 2016-11-16 48 0.000469 -0.002171 0.002159 0.002625 -0.004330 NaN -0.001702 -0.005952 0.004327
45 2016-10-31 36 0.000909 -0.001988 0.009070 0.003731 -0.011059 NaN -0.001080 -0.014830 0.004811
47 2016-10-17 26 0.000013 -0.003381 0.002299 0.002578 -0.005693 -0.080159 -0.003393 -0.011641 0.005958
48 2016-11-08 42 0.000626 0.001609 0.006969 0.004473 -0.005986 NaN 0.000983 -0.002819 0.002864
49 2016-11-07 41 0.000305 -0.000963 0.002803 0.003681 -0.003767 NaN -0.000658 -0.037370 0.004339
51 2016-11-02 38 0.000897 0.004901 0.011086 0.012621 -0.007082 NaN 0.004004 -0.046719 0.007720
52 2016-11-03 39 0.000489 -0.005506 0.014324 -0.001247 -0.020319 NaN -0.005995 -0.038351 0.004260
54 2016-11-18 50 0.000249 -0.002399 0.007338 0.004994 -0.009737 NaN -0.002150 -0.012383 0.007144
58 2016-10-21 30 0.000465 -0.007672 0.007212 -0.002406 -0.014884 -0.004436 -0.007206 -0.017141 0.004800
65 2016-11-10 44 0.000187 -0.001195 0.008200 0.004600 -0.009395 NaN -0.001008 -0.002904 0.005608
67 2016-11-21 51 0.000617 -0.010909 0.002643 0.000278 -0.013552 NaN -0.010292 -0.031027 0.010570
71 2016-11-24 54 0.000018 -0.013320 0.002637 -0.006773 -0.015957 NaN -0.013302 -0.008206 0.006529
81 2016-11-03 39 0.000377 -0.002766 0.005016 0.004506 -0.007781 NaN -0.002389 -0.004435 0.006894
82 2016-11-14 46 0.000374 -0.002282 0.016615 -0.000118 -0.019271 NaN -0.002655 -0.012659 0.002163
83 2016-11-22 52 0.000475 -0.001931 0.006439 0.000791 -0.008846 NaN -0.002407 -0.021723 0.002723
92 2016-11-02 38 0.000197 0.000635 0.008563 0.002303 -0.008125 NaN 0.000438 -0.000260 0.001668
95 2016-11-21 51 0.000668 0.000946 0.003725 0.012448 -0.003446 NaN 0.000279 -0.001767 0.011502
96 2016-11-22 52 0.000439 0.001828 0.005100 0.009302 -0.003272 NaN 0.002266 -0.004495 0.007035
97 2016-11-25 55 0.000080 0.000211 0.010224 0.006349 -0.010094 NaN 0.000131 -0.001785 0.006138
103 2016-10-28 35 0.000133 0.005344 0.013268 0.011861 -0.007923 NaN 0.005477 -0.029642 0.006384
1878 2016-10-17 26 0.000861 0.008709 0.007887 0.021834 0.000822 -0.085675 0.009570 -0.005388 0.012264
1880 2016-11-21 51 0.000807 0.003567 0.012202 0.017646 -0.009442 NaN 0.002760 -0.037314 0.014079
1882 2016-11-07 41 0.000305 0.001248 0.002353 0.011023 -0.001105 NaN 0.001553 -0.002848 0.009470
1883 2016-11-14 46 0.000424 0.003397 0.009806 0.008098 -0.006833 NaN 0.002973 -0.005312 0.004700
1888 2016-11-03 39 0.000666 0.000192 0.004033 0.006258 -0.004508 NaN -0.000475 -0.007908 0.006067
1894 2016-11-23 53 0.000488 -0.003042 0.008321 -0.001185 -0.011851 NaN -0.003530 -0.020281 0.001857
1896 2016-10-14 25 0.000811 0.002365 0.003132 0.009537 -0.000767 -0.014723 0.003177 -0.019420 0.006360
1900 2016-10-11 22 0.000039 0.004456 0.013314 0.008419 -0.008857 -0.037308 0.004495 -0.000872 0.003923
1905 2016-10-13 24 0.000241 -0.002483 0.005701 0.001448 -0.008184 -0.002806 -0.002242 -0.029952 0.003691
1908 2016-10-13 24 0.000241 -0.000323 0.002504 0.002217 -0.002827 0.012599 -0.000083 -0.011070 0.002300
1915 2016-10-25 32 0.000507 -0.002262 0.004349 0.002844 -0.006611 -0.003734 -0.001755 -0.021364 0.004599
1929 2016-11-18 50 0.000070 -0.000559 0.002831 0.005383 -0.003460 NaN -0.000628 -0.007454 0.005942
1938 2016-11-02 38 0.000197 -0.003543 0.002251 0.002900 -0.005794 NaN -0.003346 -0.000717 0.006246
1941 2016-10-20 29 0.000665 0.003019 0.002862 0.007607 0.000157 0.012531 0.003685 -0.023562 0.003922
1943 2016-10-12 23 0.000007 -0.003739 0.003059 0.007798 -0.006806 -0.019094 -0.003747 -0.022097 0.011537
1946 2016-11-15 47 0.000720 -0.003210 0.004632 0.003058 -0.007841 NaN -0.002489 -0.002776 0.005547
1948 2016-10-10 21 0.000376 0.002255 0.003476 0.015210 -0.001596 0.004594 0.001880 -0.007343 0.012955
1949 2016-10-18 27 0.000876 -0.001043 0.005166 0.004163 -0.006209 -0.032124 -0.000167 -0.005427 0.004330
1950 2016-10-25 32 0.000711 -0.010319 0.006101 -0.003082 -0.017132 -0.005389 -0.011031 -0.017904 0.007237
1951 2016-10-26 33 0.000370 -0.004374 0.007323 -0.001106 -0.011697 0.001434 -0.004004 -0.012735 0.002898
1957 2016-10-20 29 0.000231 -0.000459 0.001089 0.003078 -0.001548 -0.001621 -0.000228 -0.000899 0.003306
1965 2016-11-22 52 0.000138 -0.002269 0.007186 0.003832 -0.009592 NaN -0.002407 -0.007784 0.006101
1970 2016-11-04 40 0.000206 -0.001971 0.005055 -0.000329 -0.007026 NaN -0.001765 -0.003460 0.001436
1975 2016-10-11 22 0.000893 -0.002983 0.002940 0.005045 -0.006817 0.006228 -0.003877 -0.005929 0.008028
1977 2016-11-04 40 0.000222 -0.000236 0.002613 0.002844 -0.003072 NaN -0.000458 -0.002671 0.003081
1978 2016-11-21 51 0.000401 -0.000547 0.006943 0.003594 -0.007489 NaN -0.000146 -0.006729 0.003740
1980 2016-10-10 21 0.000587 -0.002809 0.008255 0.003330 -0.011651 -0.001846 -0.003396 -0.003616 0.006139
1981 2016-10-31 36 0.000050 -0.001628 0.004032 0.013651 -0.005709 NaN -0.001678 -0.015054 0.015279
1999 2016-11-01 37 0.000490 0.001344 0.004821 0.006146 -0.003967 NaN 0.000854 -0.013650 0.004802
2000 2016-11-10 44 0.000319 -0.002922 0.004468 0.001373 -0.007390 NaN -0.002603 -0.033727 0.003976

565 rows × 11 columns

In [12]:
sns.jointplot(data['pre20'], data['next20'], kind='reg', size=12)
Out[12]:
<seaborn.axisgrid.JointGrid at 0x7fb1604b9eb8>

不太明显,只有两个月的数据样本,但是回归明显向上偏,可见因子还是有效果
下面我选择了中证500成分股中的20支来计算

In [5]:
stocks_1 = ['601886.XSHG','601126.XSHG','000099.XSHE','600466.XSHG','600587.XSHG','002353.XSHE','002293.XSHE', '002489.XSHE', '002050.XSHE', '000592.XSHE', '000550.XSHE', '002161.XSHE', '601717.XSHG', '002368.XSHE', '300043.XSHE', '300244.XSHE', '002640.XSHE','000829.XSHE','300072.XSHE',
 '002063.XSHE']
index =  '399905.XSHE'#中证500
startdate_1 = '2014-1-1'
enddate_1 = '2016-11-25'
df_1 = pd.DataFrame()
for stk in stocks_1:
    a = abnormal_return(stk, index,startdate_1,enddate_1)
    a = distinguish_star(a)
    df_1 = pd.concat([df_1, a], axis=0)
df_1
Out[5]:
open close high low bar upline downline No pre20 next20
2014-01-07 -0.001897 -0.001943 0.006458 -0.006651 4.55517e-05 0.00835467 0.00470884 4 NaN -0.001856
2014-02-07 -0.005527 -0.006007 0.013378 -0.009961 0.000480204 0.0189052 0.00395399 22 0.007638 -0.000179
2014-03-05 0.000421 0.001246 0.012940 -0.006317 0.000824954 0.0116936 0.00673872 40 0.015679 -0.003833
2014-03-25 -0.009716 -0.009470 0.013240 -0.010665 0.000246501 0.0227101 0.000949013 54 -0.025961 -0.018466
2014-04-11 0.001609 0.001562 0.007111 -0.001851 4.68696e-05 0.00550171 0.00341342 66 0.006432 0.004684
2014-04-29 -0.008551 -0.008279 0.006034 -0.012187 0.000271631 0.0143131 0.00363623 78 -0.013229 -0.004456
2014-05-12 0.002395 0.002756 0.017588 -0.004310 0.000360935 0.0148322 0.00670472 85 0.012006 0.001380
2014-05-14 0.001632 0.002367 0.006712 -0.002074 0.000734458 0.00434597 0.00370598 87 0.016891 0.009744
2014-05-23 -0.004080 -0.004345 0.000119 -0.008800 0.000265041 0.00419809 0.00445587 94 -0.013341 -0.000664
2014-05-30 0.005732 0.006018 0.016081 -0.000791 0.00028621 0.0100633 0.00652331 99 0.010092 0.015166
2014-06-03 0.001756 0.001703 0.006032 -0.003826 5.31727e-05 0.00427542 0.00552878 100 -0.018557 0.003737
2014-06-11 -0.003509 -0.003131 0.000217 -0.008075 0.000377309 0.00334814 0.00456638 106 -0.000009 0.008957
2014-07-23 -0.002892 -0.002879 0.006577 -0.005467 1.26583e-05 0.00945605 0.00257562 136 -0.009436 -0.012740
2014-11-12 -0.004968 -0.004038 0.002243 -0.008986 0.000930737 0.00628091 0.00401753 210 -0.008778 -0.024373
2014-11-13 0.020005 0.019190 0.025552 0.014111 0.000815201 0.00554659 0.00507876 211 0.028630 0.031774
2014-11-21 -0.004224 -0.004553 -0.001483 -0.009746 0.000329642 0.00274062 0.00519264 217 -0.003224 0.000472
2015-01-06 0.000965 -0.000034 0.011175 -0.012660 0.000998943 0.0102104 0.0126261 247 0.019187 0.002940
2015-01-07 -0.004445 -0.003814 0.009787 -0.012481 0.000631839 0.0136004 0.00803581 248 -0.009749 -0.002055
2015-01-12 -0.001993 -0.001395 0.003410 -0.008329 0.000597669 0.00480551 0.00633593 251 0.011189 -0.008026
2015-01-21 -0.003244 -0.004131 0.002246 -0.008659 0.000887216 0.00548921 0.00452844 258 -0.006634 -0.003735
2015-10-27 -0.030401 -0.030548 -0.003477 -0.061991 0.000146632 0.0269246 0.0314432 442 -0.038208 -0.068074
2015-12-25 -0.003435 -0.004276 0.011034 -0.009270 0.000841036 0.014469 0.00499451 485 -0.050652 -0.064786
2016-02-16 0.008519 0.009004 0.013755 -0.016159 0.000484969 0.00475163 0.0246778 516 0.019557 0.025104
2016-02-18 -0.000986 -0.000500 0.014788 -0.012698 0.000485495 0.0152881 0.0117118 518 -0.042430 -0.016038
2016-08-04 -0.002302 -0.001616 0.009708 -0.005003 0.000686598 0.0113239 0.00270023 634 -0.016891 -0.009812
2016-08-05 0.000088 0.000812 0.007674 -0.006572 0.000723881 0.00686153 0.00666059 635 0.006899 -0.003935
2016-08-12 -0.002550 -0.003317 0.015110 -0.006441 0.000767386 0.0176602 0.00312398 640 -0.022925 -0.012306
2016-08-18 0.000405 0.000585 0.028629 -0.007071 0.000179878 0.0280438 0.00747644 644 0.014234 0.007435
2016-08-24 -0.001738 -0.000990 0.002079 -0.005246 0.000748208 0.00306858 0.00350864 648 0.036781 -0.001524
2016-09-19 -0.006974 -0.006850 0.008454 -0.010255 0.00012408 0.0153043 0.00328066 664 -0.007435 -0.019789
2014-03-14 0.005339 0.004651 0.011939 -0.001552 0.000688738 0.00659919 0.00620248 47 -0.034051 0.012145
2014-03-26 -0.001957 -0.002595 0.000969 -0.004665 0.000638664 0.00292573 0.00206933 55 -0.018953 -0.013884
2014-04-02 -0.001095 -0.000655 0.001874 -0.005735 0.000440058 0.00252931 0.0046401 60 -0.002772 0.073600
2014-06-27 -0.009957 -0.009092 0.000361 -0.014798 0.000865306 0.00945291 0.00484102 118 0.046355 -0.017387
2014-07-30 0.005364 0.006136 0.008639 -0.012577 0.000771817 0.00250293 0.0179418 141 0.035309 0.054842
2014-08-18 0.001273 0.001144 0.008594 -0.005845 0.00012896 0.00732149 0.00698941 154 0.013711 0.015067
2014-09-11 0.004093 0.003650 0.014485 0.000533 0.000443532 0.010391 0.00311663 171 0.017122 -0.009726
2014-09-25 -0.004175 -0.003376 0.010172 -0.009249 0.000799809 0.0135475 0.00507392 181 0.045331 0.019990
2014-11-28 -0.004615 -0.003657 0.011943 -0.016064 0.000958095 0.0156003 0.0114492 222 0.009065 0.011809
2015-01-27 -0.006059 -0.005392 0.004997 -0.023593 0.000667311 0.0103882 0.017534 262 0.010074 0.010936
2015-04-16 -0.021033 -0.021159 0.023717 -0.039796 0.000125134 0.0447502 0.018637 313 -0.048245 -0.027740
2015-05-12 -0.011428 -0.012081 0.046723 -0.014717 0.000653123 0.0581516 0.00263569 330 -0.001851 0.011615
2015-07-23 -0.012344 -0.011370 0.000708 -0.025381 0.000973568 0.0120778 0.0130374 381 0.033617 -0.004172
2015-08-13 0.011248 0.011441 0.020079 -0.001688 0.000193306 0.00863767 0.0129358 396 -0.040084 0.042951
2015-09-02 -0.013187 -0.012656 0.027920 -0.036755 0.0005314 0.0405758 0.0235673 410 0.003805 -0.061268
2015-10-13 -0.012480 -0.012406 0.004185 -0.018233 7.38099e-05 0.016591 0.00575265 432 -0.067521 0.010086
2015-12-17 0.006922 0.007816 0.015884 -0.001925 0.000894005 0.00806864 0.00884642 479 -0.010617 0.014929
2016-02-04 0.003553 0.004552 0.014893 -0.002413 0.000998968 0.0103405 0.00596647 513 0.018235 -0.017088
2016-03-03 -0.001259 -0.001851 0.020796 -0.006639 0.00059226 0.0220553 0.0047874 528 0.003676 0.005921
2016-03-25 0.003776 0.003463 0.006021 -0.007714 0.000312261 0.00224559 0.0111773 544 0.046411 0.011860
2016-04-14 0.004278 0.003922 0.012181 -0.003184 0.000355497 0.00790288 0.00710585 557 0.005424 0.016256
2016-04-15 -0.004720 -0.004970 -0.002328 -0.011955 0.000249798 0.00239256 0.00698465 558 -0.025893 -0.013047
2016-04-26 -0.004821 -0.004057 -0.000586 -0.012377 0.000763958 0.00347106 0.00755643 565 0.005957 -0.059779
2016-06-01 -0.006262 -0.005929 0.003318 -0.013084 0.00033289 0.0092476 0.00682147 590 -0.001883 0.014125
2016-07-11 -0.001556 -0.001341 0.013781 -0.003138 0.000214684 0.0151221 0.00158217 616 -0.021395 0.000101
2016-08-18 0.000405 -0.000315 0.003329 -0.005805 0.000720212 0.00292416 0.00548998 644 -0.012813 0.001219
2016-08-30 -0.002213 -0.002587 0.006481 -0.004237 0.000373993 0.00869423 0.00165023 652 0.000442 -0.005860
2016-09-28 -0.002059 -0.002126 0.001013 -0.004687 6.68724e-05 0.00307291 0.00256019 671 -0.004542 0.009323
2016-10-12 -0.000907 -0.001598 0.004475 -0.004918 0.000690257 0.00538284 0.00332033 676 0.002437 0.004999
2016-10-13 0.000641 0.000400 0.005512 -0.003841 0.000240639 0.00487045 0.00424137 677 -0.014095 -0.008323

602 rows × 10 columns

In [8]:
df_1 = df_1[df_1.pre20<0]
df_1.head()
Out[8]:
open close high low bar upline downline No pre20 next20
2014-03-25 -0.009716 -0.009470 0.013240 -0.010665 0.000246501 0.0227101 0.000949013 54 -0.025961 -0.018466
2014-04-29 -0.008551 -0.008279 0.006034 -0.012187 0.000271631 0.0143131 0.00363623 78 -0.013229 -0.004456
2014-05-23 -0.004080 -0.004345 0.000119 -0.008800 0.000265041 0.00419809 0.00445587 94 -0.013341 -0.000664
2014-06-03 0.001756 0.001703 0.006032 -0.003826 5.31727e-05 0.00427542 0.00552878 100 -0.018557 0.003737
2014-06-11 -0.003509 -0.003131 0.000217 -0.008075 0.000377309 0.00334814 0.00456638 106 -0.000009 0.008957
In [7]:
sns.jointplot(df_1['pre20'], df_1['next20'], kind='reg', size=12)
Out[7]:
<seaborn.axisgrid.JointGrid at 0x7fbf5d5265c0>

虽然样本还是少了一些,但是应该已经足够说明问题了
这个因子是比较有效的

 

在用单因子做了一个策略,主要逻辑就是用这个因子选股,然后持有一个月,看起来效果是不错的

”’第1部、参数控制及打印”’

”’第1部、股票选择 ”’
def pick_stocks(context):
#剔除市值前1%和3%以后的股票
df=context.df.T
stock_list = list(df.index)
logger.info(len(stock_list))
stock_list = filter_paused_stock(stock_list)
logger.info(len(stock_list))
stock_list = filter_st_stock(stock_list)
logger.info(len(stock_list))
stock_list = filter_crossstar_stock(stock_list)
logger.info(len(stock_list))
stock_list = filter_minus_rate(stock_list)
logger.info(len(stock_list))
logger.info(stock_list)
# 选取指定可买数目的股票
if len(stock_list) > context.buy_list_count:
stock_list = stock_list[:context.buy_list_count]
return stock_list

”’第8部、功能控件”’
# 过滤停牌股票
def filter_paused_stock(stock_list):
return [stock for stock in stock_list if not is_suspended(stock)]

# 过滤ST及其他具有退市标签的股票
def filter_st_stock(stock_list):
return [stock for stock in stock_list if not is_st_stock(stock)]

# 筛选符合超额十字星的股票
def filter_crossstar_stock(stock_list):
stock_list_1 = []
index_pr = history(240, ‘1m’, ‘close’)[‘399905.XSHE’]
index_t = history(2,’1d’,’close’)[‘399905.XSHE’][0]
Ri = index_pr/index_t-1
for stk in stock_list:
stk_pr = history(240, ‘1m’, ‘close’)[stk]
stk_t = history(2,’1d’,’close’)[stk][0]
Rs = stk_pr/stk_t-1
Re = Rs – Ri
High = Re.max()
Low = Re.min()
Open = Re.ix[0]
Close = Re.ix[-1]
bar = abs(Re.ix[0]-Re.ix[-1])
if Open>Close:
upline = High – Open
downline = Close – Low
else:
upline = High – Close
downline = Open – Low
if bar < 0.001 and upline > bar*3 and downline > bar*3:
stock_list_1.append(stk)
return stock_list_1

# 前20日涨幅为负的股票:
def filter_minus_rate(stock_list):
stock_list_2 = []
for stk in stock_list:
close = history(20,’1d’,’close’)[stk]
if close[0] > close[-1]:
stock_list_2.append(stk)
return stock_list_2

def init(context):
#调仓频率
context.period = 20
#定时器
context.day_count = 0
#是否调仓
context.adjust = False
#买入股票的数目
context.buy_list_count = 20

context.adjust_position_hour = 9
context.adjust_position_minute = 51

def before_trading(context):

context.df = get_fundamentals(query(fundamentals.eod_derivative_indicator.market_cap).order_by(fundamentals.eod_derivative_indicator.market_cap.asc() ))

context.day_count += 1

pass

def handle_bar(context,bar_dict):

hour = context.now.hour
minute = context.now.minute

if hour == context.adjust_position_hour and minute == context.adjust_position_minute:
do_handle_data(context, bar_dict)

def do_handle_data(context, bar_dict):
logger.info(“调仓日计数 [%d]” %(context.day_count))
if context.day_count % context.period == 0:
logger.info(“==> 满足条件进行调仓”)
buy_stocks = pick_stocks(context)
logger.info(“选股后可买股票: %s” %(buy_stocks))
if len(context.portfolio.positions)>0:
for stk in context.portfolio.positions.keys():

if stk not in buy_stocks:
order_target_percent(stk,0)
for stk in buy_stocks:
order_target_percent(stk,0.99/20)