十字星形态的简单研究

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

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

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

超额十字星的计算方法

为了定义超额十字星,我们首先需计算每只股票的超额蜡烛图(或称超额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]:
Nobarclosedownlinehighlownext20openpre20upline
2016-10-18270.00079774-0.0037700.002492080.008187-0.006262-0.005002-0.0029720.0018940.0111595
2016-10-21300.0009707810.0014130.005043580.006563-0.0036310.0104320.002383-0.0101420.00418013
2016-10-27340.0008187540.0041570.003327320.0129120.0008290.0136920.0049750.0072050.00793644
2016-11-15470.0002679910.0012320.007402240.002138-0.006438NaN0.0009640.0050020.000906188
2016-09-1280.0006367640.0014100.0129140.005389-0.011504-0.0007440.002047NaN0.00334192
2016-09-21130.000564488-0.0039690.004864590.000500-0.008833-0.030573-0.003404NaN0.00390405
2016-10-18270.0002146080.0038070.006288610.007978-0.0026960.0111390.0035920.0077590.00417093
2016-11-01370.000138128-0.0012520.004564010.005113-0.005816NaN-0.0011140.0154190.00622715
2016-11-02380.000211409-0.0026750.0071915-0.000543-0.009867NaN-0.0024640.0040200.00192073
2016-11-07410.0003052950.0008480.007016690.005692-0.006168NaN0.001154-0.0012030.0045387
2016-10-14250.000845177-0.0004880.003562470.009963-0.0040500.0301270.000357-0.0112800.00960517
2016-10-20290.000700113-0.0032760.01554030.002995-0.018816-0.006919-0.0025760.0160670.00557018
2016-11-24540.000586006-0.0042610.005227880.001193-0.009489NaN-0.0036750.0189700.0048682
2016-09-0860.000105506-0.0004500.006075260.007156-0.0065250.007919-0.000344NaN0.00750053
2016-09-21130.000564488-0.0033770.005450540.005326-0.0088280.010758-0.002813NaN0.00813856
2016-10-14250.0003692140.0042670.008962150.025011-0.004696-0.0115240.004636-0.0030370.0203752
2016-10-20290.000230630.0005110.01350730.013321-0.012996-0.0679910.000742-0.0481910.0125796
2016-10-24310.000727063-0.0051780.008383230.001363-0.014288-0.005292-0.005905-0.0360110.00654016
2016-10-12233.48944e-050.0005680.006902840.003820-0.006369-0.0101410.0005330.0060490.00325187
2016-11-02380.0006593880.0005750.007976190.003527-0.008061NaN-0.0000850.0040660.00295236
2016-11-11450.000193605-0.0010890.002567660.003306-0.003851NaN-0.0012830.0079740.0043954
2016-11-18500.0006415780.0006470.007649760.006352-0.007644NaN0.0000050.0029540.00570539
2016-11-25550.000100626-0.0044950.002602130.007634-0.007097NaN-0.0043940.0053820.0120279
2016-09-0530.00020701-0.0030160.0043616-0.000573-0.007378-0.008153-0.002809NaN0.00223569
2016-09-14100.0008290460.0021230.005488770.008352-0.0033660.0068590.002952NaN0.00540016
2016-10-19280.0007768330.0006120.004699350.005156-0.004864-0.006480-0.000164-0.0032460.00454413
2016-11-07410.000305295-0.0025350.01129420.003538-0.013829NaN-0.0022290.0343570.00576718
2016-11-08420.000579561-0.0021640.005448420.003421-0.007612NaN-0.0015840.0012990.00500517
2016-11-09430.000404826-0.0007400.001246170.010240-0.001986NaN-0.000335-0.0058770.0105754
2016-11-17490.000716673-0.0028890.007420670.002564-0.010310NaN-0.0021720.0011740.00473643
2016-09-29190.0004050360.0052480.008575410.009771-0.0037320.0026370.004843NaN0.00452285
2016-10-10210.000353476-0.0008710.004928910.001998-0.005800-0.012189-0.0005180.0059510.00251583
2016-10-11220.000893326-0.0029830.002940190.005045-0.0068170.006228-0.003877-0.0059290.00802837
2016-11-01370.0005136960.0037870.003323050.008657-0.000049NaN0.0032740.0070690.0048698
2016-11-04400.000221849-0.0002360.002613490.002844-0.003072NaN-0.000458-0.0026710.00308066
2016-11-21510.000401302-0.0005470.006942530.003594-0.007489NaN-0.000146-0.0067290.00374009
2016-09-29194.13928e-05-0.0027870.006176610.003703-0.008964-0.014448-0.002746NaN0.00644853
2016-10-10210.000586688-0.0028090.008255050.003330-0.011651-0.001846-0.003396-0.0036160.00613935
2016-10-31364.9729e-05-0.0016280.004031670.013651-0.005709NaN-0.001678-0.0150540.0152788
2016-11-01370.000535190.0029170.004028790.014210-0.001112NaN0.0034520.0056030.0107579
2016-09-0220.0008541680.0005240.009029010.004768-0.0093590.001063-0.000330NaN0.0042435
2016-09-21130.0002578330.0000350.004556630.004762-0.004522-0.0071170.000293NaN0.00446928
2016-09-22140.000494773-0.0016970.003629740.007605-0.005327-0.000656-0.001202NaN0.00880745
2016-09-28180.0005651110.0005810.004067790.005105-0.0034860.0031880.001147NaN0.00395864
2016-09-29194.13928e-05-0.0002790.002923310.009352-0.003203-0.002042-0.000238NaN0.0095905
2016-10-10210.0005759850.0028250.003048360.007299-0.0008000.0004110.0022490.0144390.00447417
2016-10-24310.000760739-0.0037810.002823090.000378-0.007365-0.019246-0.0045420.0033950.00415886
2016-10-27340.000895743-0.0010410.003908360.003683-0.004949-0.004304-0.0001450.0006560.00382803
2016-11-03390.0005345620.0017630.003129740.008293-0.001367NaN0.0022970.0020420.00599582
2016-11-24540.0002135750.0032630.005533580.005765-0.002271NaN0.0034770.0043040.00228796
2016-09-1285.17113e-05-0.0077130.006750640.005134-0.014464-0.047022-0.007661NaN0.0127952
2016-09-19110.000211130.0022530.01014720.007446-0.008105-0.0019740.002042NaN0.00519277
2016-09-27170.000428801-0.0056630.004989690.001271-0.011081-0.001716-0.006092NaN0.00693369
2016-09-1280.000539117-0.0112350.00905839-0.007475-0.020293-0.001961-0.010696NaN0.0032207
2016-09-14100.000328796-0.0010670.00960750.004199-0.0106740.003107-0.000738NaN0.00493743
2016-10-26330.0001893340.0011760.004053260.006450-0.0028770.0100200.0013650.0127470.00508488
2016-11-01370.0004895110.0013440.00482140.006146-0.003967NaN0.000854-0.0136500.00480187
2016-11-10440.000318871-0.0029220.004467980.001373-0.007390NaN-0.002603-0.0337270.00397611
2016-11-11450.0005040470.0126240.003490840.0388570.008629NaN0.0121200.0159190.0262325
2016-11-18500.000674624-0.0026070.005603340.002171-0.008211NaN-0.0019330.0015670.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: 0Nobarclosedownlinehighlownext20openpre20upline
02016-10-18270.000798-0.0037700.0024920.008187-0.006262-0.005002-0.0029720.0018940.011159
12016-10-21300.0009710.0014130.0050440.006563-0.0036310.0104320.002383-0.0101420.004180
22016-10-27340.0008190.0041570.0033270.0129120.0008290.0136920.0049750.0072050.007936
32016-11-15470.0002680.0012320.0074020.002138-0.006438NaN0.0009640.0050020.000906
42016-09-1280.0006370.0014100.0129140.005389-0.011504-0.0007440.002047NaN0.003342
52016-09-21130.000564-0.0039690.0048650.000500-0.008833-0.030573-0.003404NaN0.003904
62016-10-18270.0002150.0038070.0062890.007978-0.0026960.0111390.0035920.0077590.004171
72016-11-01370.000138-0.0012520.0045640.005113-0.005816NaN-0.0011140.0154190.006227
82016-11-02380.000211-0.0026750.007191-0.000543-0.009867NaN-0.0024640.0040200.001921
92016-11-07410.0003050.0008480.0070170.005692-0.006168NaN0.001154-0.0012030.004539
102016-10-14250.000845-0.0004880.0035620.009963-0.0040500.0301270.000357-0.0112800.009605
112016-10-20290.000700-0.0032760.0155400.002995-0.018816-0.006919-0.0025760.0160670.005570
122016-11-24540.000586-0.0042610.0052280.001193-0.009489NaN-0.0036750.0189700.004868
132016-09-0860.000106-0.0004500.0060750.007156-0.0065250.007919-0.000344NaN0.007501
142016-09-21130.000564-0.0033770.0054510.005326-0.0088280.010758-0.002813NaN0.008139
152016-10-14250.0003690.0042670.0089620.025011-0.004696-0.0115240.004636-0.0030370.020375
162016-10-20290.0002310.0005110.0135070.013321-0.012996-0.0679910.000742-0.0481910.012580
172016-10-24310.000727-0.0051780.0083830.001363-0.014288-0.005292-0.005905-0.0360110.006540
182016-10-12230.0000350.0005680.0069030.003820-0.006369-0.0101410.0005330.0060490.003252
192016-11-02380.0006590.0005750.0079760.003527-0.008061NaN-0.0000850.0040660.002952
202016-11-11450.000194-0.0010890.0025680.003306-0.003851NaN-0.0012830.0079740.004395
212016-11-18500.0006420.0006470.0076500.006352-0.007644NaN0.0000050.0029540.005705
222016-11-25550.000101-0.0044950.0026020.007634-0.007097NaN-0.0043940.0053820.012028
232016-09-0530.000207-0.0030160.004362-0.000573-0.007378-0.008153-0.002809NaN0.002236
242016-09-14100.0008290.0021230.0054890.008352-0.0033660.0068590.002952NaN0.005400
252016-10-19280.0007770.0006120.0046990.005156-0.004864-0.006480-0.000164-0.0032460.004544
262016-11-07410.000305-0.0025350.0112940.003538-0.013829NaN-0.0022290.0343570.005767
272016-11-08420.000580-0.0021640.0054480.003421-0.007612NaN-0.0015840.0012990.005005
282016-11-09430.000405-0.0007400.0012460.010240-0.001986NaN-0.000335-0.0058770.010575
292016-11-17490.000717-0.0028890.0074210.002564-0.010310NaN-0.0021720.0011740.004736
19732016-09-29190.0004050.0052480.0085750.009771-0.0037320.0026370.004843NaN0.004523
19742016-10-10210.000353-0.0008710.0049290.001998-0.005800-0.012189-0.0005180.0059510.002516
19752016-10-11220.000893-0.0029830.0029400.005045-0.0068170.006228-0.003877-0.0059290.008028
19762016-11-01370.0005140.0037870.0033230.008657-0.000049NaN0.0032740.0070690.004870
19772016-11-04400.000222-0.0002360.0026130.002844-0.003072NaN-0.000458-0.0026710.003081
19782016-11-21510.000401-0.0005470.0069430.003594-0.007489NaN-0.000146-0.0067290.003740
19792016-09-29190.000041-0.0027870.0061770.003703-0.008964-0.014448-0.002746NaN0.006449
19802016-10-10210.000587-0.0028090.0082550.003330-0.011651-0.001846-0.003396-0.0036160.006139
19812016-10-31360.000050-0.0016280.0040320.013651-0.005709NaN-0.001678-0.0150540.015279
19822016-11-01370.0005350.0029170.0040290.014210-0.001112NaN0.0034520.0056030.010758
19832016-09-0220.0008540.0005240.0090290.004768-0.0093590.001063-0.000330NaN0.004243
19842016-09-21130.0002580.0000350.0045570.004762-0.004522-0.0071170.000293NaN0.004469
19852016-09-22140.000495-0.0016970.0036300.007605-0.005327-0.000656-0.001202NaN0.008807
19862016-09-28180.0005650.0005810.0040680.005105-0.0034860.0031880.001147NaN0.003959
19872016-09-29190.000041-0.0002790.0029230.009352-0.003203-0.002042-0.000238NaN0.009590
19882016-10-10210.0005760.0028250.0030480.007299-0.0008000.0004110.0022490.0144390.004474
19892016-10-24310.000761-0.0037810.0028230.000378-0.007365-0.019246-0.0045420.0033950.004159
19902016-10-27340.000896-0.0010410.0039080.003683-0.004949-0.004304-0.0001450.0006560.003828
19912016-11-03390.0005350.0017630.0031300.008293-0.001367NaN0.0022970.0020420.005996
19922016-11-24540.0002140.0032630.0055340.005765-0.002271NaN0.0034770.0043040.002288
19932016-09-1280.000052-0.0077130.0067510.005134-0.014464-0.047022-0.007661NaN0.012795
19942016-09-19110.0002110.0022530.0101470.007446-0.008105-0.0019740.002042NaN0.005193
19952016-09-27170.000429-0.0056630.0049900.001271-0.011081-0.001716-0.006092NaN0.006934
19962016-09-1280.000539-0.0112350.009058-0.007475-0.020293-0.001961-0.010696NaN0.003221
19972016-09-14100.000329-0.0010670.0096080.004199-0.0106740.003107-0.000738NaN0.004937
19982016-10-26330.0001890.0011760.0040530.006450-0.0028770.0100200.0013650.0127470.005085
19992016-11-01370.0004900.0013440.0048210.006146-0.003967NaN0.000854-0.0136500.004802
20002016-11-10440.000319-0.0029220.0044680.001373-0.007390NaN-0.002603-0.0337270.003976
20012016-11-11450.0005040.0126240.0034910.0388570.008629NaN0.0121200.0159190.026232
20022016-11-18500.000675-0.0026070.0056030.002171-0.008211NaN-0.0019330.0015670.004104

2003 rows × 11 columns

In [11]:
data = data[data.pre20 < 0]
data
Out[11]:
Unnamed: 0Nobarclosedownlinehighlownext20openpre20upline
12016-10-21300.0009710.0014130.0050440.006563-0.0036310.0104320.002383-0.0101420.004180
92016-11-07410.0003050.0008480.0070170.005692-0.006168NaN0.001154-0.0012030.004539
102016-10-14250.000845-0.0004880.0035620.009963-0.0040500.0301270.000357-0.0112800.009605
152016-10-14250.0003690.0042670.0089620.025011-0.004696-0.0115240.004636-0.0030370.020375
162016-10-20290.0002310.0005110.0135070.013321-0.012996-0.0679910.000742-0.0481910.012580
172016-10-24310.000727-0.0051780.0083830.001363-0.014288-0.005292-0.005905-0.0360110.006540
252016-10-19280.0007770.0006120.0046990.005156-0.004864-0.006480-0.000164-0.0032460.004544
282016-11-09430.000405-0.0007400.0012460.010240-0.001986NaN-0.000335-0.0058770.010575
322016-11-16480.0005150.0027500.0075970.011324-0.004846NaN0.003265-0.0018600.008059
332016-10-18270.000583-0.0127860.0025510.001859-0.015338-0.014888-0.012203-0.0355460.014062
402016-11-16480.000469-0.0021710.0021590.002625-0.004330NaN-0.001702-0.0059520.004327
452016-10-31360.000909-0.0019880.0090700.003731-0.011059NaN-0.001080-0.0148300.004811
472016-10-17260.000013-0.0033810.0022990.002578-0.005693-0.080159-0.003393-0.0116410.005958
482016-11-08420.0006260.0016090.0069690.004473-0.005986NaN0.000983-0.0028190.002864
492016-11-07410.000305-0.0009630.0028030.003681-0.003767NaN-0.000658-0.0373700.004339
512016-11-02380.0008970.0049010.0110860.012621-0.007082NaN0.004004-0.0467190.007720
522016-11-03390.000489-0.0055060.014324-0.001247-0.020319NaN-0.005995-0.0383510.004260
542016-11-18500.000249-0.0023990.0073380.004994-0.009737NaN-0.002150-0.0123830.007144
582016-10-21300.000465-0.0076720.007212-0.002406-0.014884-0.004436-0.007206-0.0171410.004800
652016-11-10440.000187-0.0011950.0082000.004600-0.009395NaN-0.001008-0.0029040.005608
672016-11-21510.000617-0.0109090.0026430.000278-0.013552NaN-0.010292-0.0310270.010570
712016-11-24540.000018-0.0133200.002637-0.006773-0.015957NaN-0.013302-0.0082060.006529
812016-11-03390.000377-0.0027660.0050160.004506-0.007781NaN-0.002389-0.0044350.006894
822016-11-14460.000374-0.0022820.016615-0.000118-0.019271NaN-0.002655-0.0126590.002163
832016-11-22520.000475-0.0019310.0064390.000791-0.008846NaN-0.002407-0.0217230.002723
922016-11-02380.0001970.0006350.0085630.002303-0.008125NaN0.000438-0.0002600.001668
952016-11-21510.0006680.0009460.0037250.012448-0.003446NaN0.000279-0.0017670.011502
962016-11-22520.0004390.0018280.0051000.009302-0.003272NaN0.002266-0.0044950.007035
972016-11-25550.0000800.0002110.0102240.006349-0.010094NaN0.000131-0.0017850.006138
1032016-10-28350.0001330.0053440.0132680.011861-0.007923NaN0.005477-0.0296420.006384
18782016-10-17260.0008610.0087090.0078870.0218340.000822-0.0856750.009570-0.0053880.012264
18802016-11-21510.0008070.0035670.0122020.017646-0.009442NaN0.002760-0.0373140.014079
18822016-11-07410.0003050.0012480.0023530.011023-0.001105NaN0.001553-0.0028480.009470
18832016-11-14460.0004240.0033970.0098060.008098-0.006833NaN0.002973-0.0053120.004700
18882016-11-03390.0006660.0001920.0040330.006258-0.004508NaN-0.000475-0.0079080.006067
18942016-11-23530.000488-0.0030420.008321-0.001185-0.011851NaN-0.003530-0.0202810.001857
18962016-10-14250.0008110.0023650.0031320.009537-0.000767-0.0147230.003177-0.0194200.006360
19002016-10-11220.0000390.0044560.0133140.008419-0.008857-0.0373080.004495-0.0008720.003923
19052016-10-13240.000241-0.0024830.0057010.001448-0.008184-0.002806-0.002242-0.0299520.003691
19082016-10-13240.000241-0.0003230.0025040.002217-0.0028270.012599-0.000083-0.0110700.002300
19152016-10-25320.000507-0.0022620.0043490.002844-0.006611-0.003734-0.001755-0.0213640.004599
19292016-11-18500.000070-0.0005590.0028310.005383-0.003460NaN-0.000628-0.0074540.005942
19382016-11-02380.000197-0.0035430.0022510.002900-0.005794NaN-0.003346-0.0007170.006246
19412016-10-20290.0006650.0030190.0028620.0076070.0001570.0125310.003685-0.0235620.003922
19432016-10-12230.000007-0.0037390.0030590.007798-0.006806-0.019094-0.003747-0.0220970.011537
19462016-11-15470.000720-0.0032100.0046320.003058-0.007841NaN-0.002489-0.0027760.005547
19482016-10-10210.0003760.0022550.0034760.015210-0.0015960.0045940.001880-0.0073430.012955
19492016-10-18270.000876-0.0010430.0051660.004163-0.006209-0.032124-0.000167-0.0054270.004330
19502016-10-25320.000711-0.0103190.006101-0.003082-0.017132-0.005389-0.011031-0.0179040.007237
19512016-10-26330.000370-0.0043740.007323-0.001106-0.0116970.001434-0.004004-0.0127350.002898
19572016-10-20290.000231-0.0004590.0010890.003078-0.001548-0.001621-0.000228-0.0008990.003306
19652016-11-22520.000138-0.0022690.0071860.003832-0.009592NaN-0.002407-0.0077840.006101
19702016-11-04400.000206-0.0019710.005055-0.000329-0.007026NaN-0.001765-0.0034600.001436
19752016-10-11220.000893-0.0029830.0029400.005045-0.0068170.006228-0.003877-0.0059290.008028
19772016-11-04400.000222-0.0002360.0026130.002844-0.003072NaN-0.000458-0.0026710.003081
19782016-11-21510.000401-0.0005470.0069430.003594-0.007489NaN-0.000146-0.0067290.003740
19802016-10-10210.000587-0.0028090.0082550.003330-0.011651-0.001846-0.003396-0.0036160.006139
19812016-10-31360.000050-0.0016280.0040320.013651-0.005709NaN-0.001678-0.0150540.015279
19992016-11-01370.0004900.0013440.0048210.006146-0.003967NaN0.000854-0.0136500.004802
20002016-11-10440.000319-0.0029220.0044680.001373-0.007390NaN-0.002603-0.0337270.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]:
openclosehighlowbaruplinedownlineNopre20next20
2014-01-07-0.001897-0.0019430.006458-0.0066514.55517e-050.008354670.004708844NaN-0.001856
2014-02-07-0.005527-0.0060070.013378-0.0099610.0004802040.01890520.00395399220.007638-0.000179
2014-03-050.0004210.0012460.012940-0.0063170.0008249540.01169360.00673872400.015679-0.003833
2014-03-25-0.009716-0.0094700.013240-0.0106650.0002465010.02271010.00094901354-0.025961-0.018466
2014-04-110.0016090.0015620.007111-0.0018514.68696e-050.005501710.00341342660.0064320.004684
2014-04-29-0.008551-0.0082790.006034-0.0121870.0002716310.01431310.0036362378-0.013229-0.004456
2014-05-120.0023950.0027560.017588-0.0043100.0003609350.01483220.00670472850.0120060.001380
2014-05-140.0016320.0023670.006712-0.0020740.0007344580.004345970.00370598870.0168910.009744
2014-05-23-0.004080-0.0043450.000119-0.0088000.0002650410.004198090.0044558794-0.013341-0.000664
2014-05-300.0057320.0060180.016081-0.0007910.000286210.01006330.00652331990.0100920.015166
2014-06-030.0017560.0017030.006032-0.0038265.31727e-050.004275420.00552878100-0.0185570.003737
2014-06-11-0.003509-0.0031310.000217-0.0080750.0003773090.003348140.00456638106-0.0000090.008957
2014-07-23-0.002892-0.0028790.006577-0.0054671.26583e-050.009456050.00257562136-0.009436-0.012740
2014-11-12-0.004968-0.0040380.002243-0.0089860.0009307370.006280910.00401753210-0.008778-0.024373
2014-11-130.0200050.0191900.0255520.0141110.0008152010.005546590.005078762110.0286300.031774
2014-11-21-0.004224-0.004553-0.001483-0.0097460.0003296420.002740620.00519264217-0.0032240.000472
2015-01-060.000965-0.0000340.011175-0.0126600.0009989430.01021040.01262612470.0191870.002940
2015-01-07-0.004445-0.0038140.009787-0.0124810.0006318390.01360040.00803581248-0.009749-0.002055
2015-01-12-0.001993-0.0013950.003410-0.0083290.0005976690.004805510.006335932510.011189-0.008026
2015-01-21-0.003244-0.0041310.002246-0.0086590.0008872160.005489210.00452844258-0.006634-0.003735
2015-10-27-0.030401-0.030548-0.003477-0.0619910.0001466320.02692460.0314432442-0.038208-0.068074
2015-12-25-0.003435-0.0042760.011034-0.0092700.0008410360.0144690.00499451485-0.050652-0.064786
2016-02-160.0085190.0090040.013755-0.0161590.0004849690.004751630.02467785160.0195570.025104
2016-02-18-0.000986-0.0005000.014788-0.0126980.0004854950.01528810.0117118518-0.042430-0.016038
2016-08-04-0.002302-0.0016160.009708-0.0050030.0006865980.01132390.00270023634-0.016891-0.009812
2016-08-050.0000880.0008120.007674-0.0065720.0007238810.006861530.006660596350.006899-0.003935
2016-08-12-0.002550-0.0033170.015110-0.0064410.0007673860.01766020.00312398640-0.022925-0.012306
2016-08-180.0004050.0005850.028629-0.0070710.0001798780.02804380.007476446440.0142340.007435
2016-08-24-0.001738-0.0009900.002079-0.0052460.0007482080.003068580.003508646480.036781-0.001524
2016-09-19-0.006974-0.0068500.008454-0.0102550.000124080.01530430.00328066664-0.007435-0.019789
2014-03-140.0053390.0046510.011939-0.0015520.0006887380.006599190.0062024847-0.0340510.012145
2014-03-26-0.001957-0.0025950.000969-0.0046650.0006386640.002925730.0020693355-0.018953-0.013884
2014-04-02-0.001095-0.0006550.001874-0.0057350.0004400580.002529310.004640160-0.0027720.073600
2014-06-27-0.009957-0.0090920.000361-0.0147980.0008653060.009452910.004841021180.046355-0.017387
2014-07-300.0053640.0061360.008639-0.0125770.0007718170.002502930.01794181410.0353090.054842
2014-08-180.0012730.0011440.008594-0.0058450.000128960.007321490.006989411540.0137110.015067
2014-09-110.0040930.0036500.0144850.0005330.0004435320.0103910.003116631710.017122-0.009726
2014-09-25-0.004175-0.0033760.010172-0.0092490.0007998090.01354750.005073921810.0453310.019990
2014-11-28-0.004615-0.0036570.011943-0.0160640.0009580950.01560030.01144922220.0090650.011809
2015-01-27-0.006059-0.0053920.004997-0.0235930.0006673110.01038820.0175342620.0100740.010936
2015-04-16-0.021033-0.0211590.023717-0.0397960.0001251340.04475020.018637313-0.048245-0.027740
2015-05-12-0.011428-0.0120810.046723-0.0147170.0006531230.05815160.00263569330-0.0018510.011615
2015-07-23-0.012344-0.0113700.000708-0.0253810.0009735680.01207780.01303743810.033617-0.004172
2015-08-130.0112480.0114410.020079-0.0016880.0001933060.008637670.0129358396-0.0400840.042951
2015-09-02-0.013187-0.0126560.027920-0.0367550.00053140.04057580.02356734100.003805-0.061268
2015-10-13-0.012480-0.0124060.004185-0.0182337.38099e-050.0165910.00575265432-0.0675210.010086
2015-12-170.0069220.0078160.015884-0.0019250.0008940050.008068640.00884642479-0.0106170.014929
2016-02-040.0035530.0045520.014893-0.0024130.0009989680.01034050.005966475130.018235-0.017088
2016-03-03-0.001259-0.0018510.020796-0.0066390.000592260.02205530.00478745280.0036760.005921
2016-03-250.0037760.0034630.006021-0.0077140.0003122610.002245590.01117735440.0464110.011860
2016-04-140.0042780.0039220.012181-0.0031840.0003554970.007902880.007105855570.0054240.016256
2016-04-15-0.004720-0.004970-0.002328-0.0119550.0002497980.002392560.00698465558-0.025893-0.013047
2016-04-26-0.004821-0.004057-0.000586-0.0123770.0007639580.003471060.007556435650.005957-0.059779
2016-06-01-0.006262-0.0059290.003318-0.0130840.000332890.00924760.00682147590-0.0018830.014125
2016-07-11-0.001556-0.0013410.013781-0.0031380.0002146840.01512210.00158217616-0.0213950.000101
2016-08-180.000405-0.0003150.003329-0.0058050.0007202120.002924160.00548998644-0.0128130.001219
2016-08-30-0.002213-0.0025870.006481-0.0042370.0003739930.008694230.001650236520.000442-0.005860
2016-09-28-0.002059-0.0021260.001013-0.0046876.68724e-050.003072910.00256019671-0.0045420.009323
2016-10-12-0.000907-0.0015980.004475-0.0049180.0006902570.005382840.003320336760.0024370.004999
2016-10-130.0006410.0004000.005512-0.0038410.0002406390.004870450.00424137677-0.014095-0.008323

602 rows × 10 columns

In [8]:
df_1 = df_1[df_1.pre20<0]
df_1.head()
Out[8]:
openclosehighlowbaruplinedownlineNopre20next20
2014-03-25-0.009716-0.0094700.013240-0.0106650.0002465010.02271010.00094901354-0.025961-0.018466
2014-04-29-0.008551-0.0082790.006034-0.0121870.0002716310.01431310.0036362378-0.013229-0.004456
2014-05-23-0.004080-0.0043450.000119-0.0088000.0002650410.004198090.0044558794-0.013341-0.000664
2014-06-030.0017560.0017030.006032-0.0038265.31727e-050.004275420.00552878100-0.0185570.003737
2014-06-11-0.003509-0.0031310.000217-0.0080750.0003773090.003348140.00456638106-0.0000090.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)