金融量化

 

1、股票數據分析

1. 獲取茅臺股票數據並存儲到本地csv文件html

 1 Signature:
 2 ts.get_k_data(
 3     code=None,
 4     start='',
 5     end='',
 6     ktype='D',
 7     autype='qfq',
 8     index=False,
 9     retry_count=3,
10     pause=0.001,
11 )
12 Docstring:
13 獲取k線數據
14 ---------
15 Parameters:
16   code:string
17               股票代碼 e.g. 600848
18   start:string
19               開始日期 format:YYYY-MM-DD 爲空時取上市首日
20   end:string
21               結束日期 format:YYYY-MM-DD 爲空時取最近一個交易日
22   autype:string
23               復權類型,qfq-前復權 hfq-後復權 None-不復權,默認爲qfq
24   ktype:string
25               數據類型,D=日k線 W=周 M=月 5=5分鐘 15=15分鐘 30=30分鐘 60=60分鐘,默認爲D
26   retry_count : int, 默認 3
27              如遇網絡等問題重複執行的次數 
28   pause : int, 默認 0
29             重複請求數據過程當中暫停的秒數,防止請求間隔時間過短出現的問題
30 return
31 -------
32   DataFrame
33       date 交易日期 (index)
34       open 開盤價
35       high  最高價
36       close 收盤價
37       low 最低價
38       volume 成交量
39       amount 成交額
40       turnoverratio 換手率
41       code 股票代碼
42 File:      /usr/local/python3.6/lib/python3.6/site-packages/tushare/stock/trading.py
43 Type:      function
tushare的get_k_data接口
1 import tushare as ts
2 
3 token = 'Your token'
4 ts.set_token(token)
5 
6 pro = ts.pro_api()
7 df = pro.daily(ts_code='xxx')
tushare的Pro接口
In [1]: import numpy as np                                                                                                                                                                                                                

In [2]: import pandas as pd                                                                                                                                                                                                               

In [3]: import tushare as ts                                                                                                                                                                                                              

In [4]: import matplotlib.pyplot as plt                                                                                                                                                                                                   

In [5]: df = ts.get_k_data("600519",start='1988-01-01')                                                                                                                                                                                   

In [6]: df.to_csv('600519.csv')                                                                                                                                                                                                           

In [7]: df = pd.read_csv('600519.csv',index_col='date',parse_dates=['date'])[['open','close','high','low']]                                                                                                                               

In [8]: df.head()                                                                                                                                                                                                                         
Out[8]: 
             open  close   high    low
date                                  
2001-08-27  5.392  5.554  5.902  5.132
2001-08-28  5.467  5.759  5.781  5.407
2001-08-29  5.777  5.684  5.781  5.640
2001-08-30  5.668  5.796  5.860  5.624
2001-08-31  5.804  5.782  5.877  5.749

In [9]: df.tail()                                                                                                                                                                                                                         
Out[9]: 
              open   close    high     low
date                                      
2019-04-15  931.00  907.00  939.00  907.00
2019-04-16  904.90  939.90  939.90  901.22
2019-04-17  938.00  952.00  955.51  925.00
2019-04-18  945.41  945.50  954.68  936.22
2019-04-19  943.96  952.56  960.95  931.31

In [10]: 

 

2. 輸出該股票全部收盤比開盤上漲8%以上的日期python

In [13]: df[ (df['close']-df['open'])/df['open']>=0.08 ]                                                                                                                                                                                  
Out[13]: 
               open    close     high      low
date                                          
2004-03-02    5.463    6.031    6.079    5.463
2005-06-08   11.383   12.555   12.639   11.383
2006-02-10   14.894   16.165   16.310   14.796
2006-05-29   25.024   27.520   27.520   25.024
2006-12-18   49.409   54.051   54.214   49.409
2007-06-11   67.313   73.569   73.569   66.913
2007-10-09   92.221   99.938  101.348   92.221
2007-12-14  125.269  135.970  137.154  124.029
2008-11-14   57.017   62.417   62.417   57.017
2009-03-04   73.123   79.024   79.961   72.756
2015-04-16  177.135  192.185  192.185  176.523
2015-07-09  201.180  219.085  221.182  197.901

In [14]: df[ (df['close']-df['open'])/df['open']>=0.1 ]                                                                                                                                                                                   
Out[14]: 
              open   close    high     low
date                                      
2004-03-02   5.463   6.031   6.079   5.463
2005-06-08  11.383  12.555  12.639  11.383


# 國內股票限制:最多漲10%
In [15]: df[ (df['close']-df['open'])/df['open']>=0.11 ]                                                                                                                                                                                  
Out[15]: 
Empty DataFrame
Columns: [open, close, high, low]
Index: []

In [16]: 
In [17]: df[ (df['close']-df['open'])/df['open']>=0.08 ].index                                                                                                                                                                            
Out[17]: 
DatetimeIndex(['2004-03-02', '2005-06-08', '2006-02-10', '2006-05-29',
               '2006-12-18', '2007-06-11', '2007-10-09', '2007-12-14',
               '2008-11-14', '2009-03-04', '2015-04-16', '2015-07-09'],
              dtype='datetime64[ns]', name='date', freq=None)

In [18]: 

 

3. 輸出該股票全部開盤價比前日收盤價跌幅超過5%的日期api

涉及到和前一天數據相比,笨辦法本身寫for循環,網絡

好在pandas提供了shift函數,很是方便的移動df的數據app

In [30]: df.head()                                                                                                                                                                                                                        
Out[30]: 
             open  close   high    low
date                                  
2001-08-27  5.392  5.554  5.902  5.132
2001-08-28  5.467  5.759  5.781  5.407
2001-08-29  5.777  5.684  5.781  5.640
2001-08-30  5.668  5.796  5.860  5.624
2001-08-31  5.804  5.782  5.877  5.749

In [31]: df['close'].shift(1).head()                                                                                                                                                                                                      
Out[31]: 
date
2001-08-27      NaN
2001-08-28    5.554
2001-08-29    5.759
2001-08-30    5.684
2001-08-31    5.796
Name: close, dtype: float64

In [32]: df[ (df['open']-df['close'].shift(1))/df['close'].shift(1)<=-0.05 ]                                                                                                                                                              
Out[32]: 
               open    close     high      low
date                                          
2008-03-13  124.709  133.893  135.341  120.258
2012-11-22  150.981  158.104  158.228  150.471
2015-07-08  194.504  201.180  208.085  186.656
2018-10-11  635.010  644.990  668.940  635.010
2018-10-29  549.090  549.090  549.090  549.090
2018-10-30  510.000  524.000  543.000  509.020

In [33]:   
In [33]: df[ (df['open']-df['close'].shift(1))/df['close'].shift(1)<=-0.05 ].index                                                                                                                                                        
Out[33]: 
DatetimeIndex(['2008-03-13', '2012-11-22', '2015-07-08', '2018-10-11',
               '2018-10-29', '2018-10-30'],
              dtype='datetime64[ns]', name='date', freq=None)

In [34]: 

 

4. 假如我從2001年1月1日開始,每個月第一個交易日買入1手(1手等於100股)股票,每一年最後一個交易日賣出全部股票,ide

那麼迄今爲止, 個人收益是多少?函數

In [72]: df = pd.read_csv('600519.csv',index_col='date',parse_dates=['date'])[['open','close','high','low']]                                                                                                                              

In [73]: df.head()                                                                                                                                                                                                                        
Out[73]: 
             open  close   high    low
date                                  
2001-08-27  5.392  5.554  5.902  5.132
2001-08-28  5.467  5.759  5.781  5.407
2001-08-29  5.777  5.684  5.781  5.640
2001-08-30  5.668  5.796  5.860  5.624
2001-08-31  5.804  5.782  5.877  5.749

In [74]: df.tail()                                                                                                                                                                                                                        
Out[74]: 
              open   close    high     low
date                                      
2019-04-15  931.00  907.00  939.00  907.00
2019-04-16  904.90  939.90  939.90  901.22
2019-04-17  938.00  952.00  955.51  925.00
2019-04-18  945.41  945.50  954.68  936.22
2019-04-19  943.96  952.56  960.95  931.31

In [75]: price_last = df['open'][-1]     # 記住當前最近一天開盤價                                                                                                                                                                                                 

In [76]: df = df['2001-09':'2019-03']    # 剔除首尾無用數據                                                                                                                                                                                  

In [77]: df.head()                                                                                                                                                                                                                        
Out[77]: 
             open  close   high    low
date                                  
2001-09-03  5.812  5.779  5.870  5.757
2001-09-04  5.782  5.852  5.949  5.762
2001-09-05  5.876  5.849  5.924  5.813
2001-09-06  5.835  5.734  5.854  5.704
2001-09-07  5.702  5.574  5.773  5.570

In [78]: df.tail()                                                                                                                                                                                                                        
Out[78]: 
              open   close    high     low
date                                      
2019-03-25  786.00  775.60  788.00  773.30
2019-03-26  780.00  773.00  785.94  764.10
2019-03-27  781.00  788.50  793.88  775.00
2019-03-28  793.43  806.80  814.48  785.68
2019-03-29  835.00  853.99  866.68  830.17

In [79]: 


# 利用resample從新採樣:獲取每個月第一天的股票信息
In [83]: df_monthly = df.resample("M").first()                                                                                                                                                                                            

In [84]: df.resample('A').last()                                                                                                                                                                                                          
Out[84]: 
               open    close     high      low
date                                          
2001-12-31    5.885    6.023    6.140    5.852
2002-12-31    4.473    4.448    4.504    4.447
2003-12-31    4.940    4.921    4.940    4.888
2004-12-31    9.325    9.310    9.579    9.168
2005-12-31   14.309   14.039   14.316   13.817
2006-12-31   53.482   54.946   57.617   52.900
2007-12-31  139.495  144.783  144.846  137.085
2008-12-31   68.502   68.818   69.318   68.058
2009-12-31  107.993  108.369  108.516  107.718
2010-12-31  117.103  118.469  118.701  116.620
2011-12-31  138.039  138.468  139.600  136.105
2012-12-31  155.208  152.087  156.292  150.144
2013-12-31   93.188   96.480   97.179   92.061
2014-12-31  157.642  161.056  161.379  157.132
2015-12-31  207.487  207.458  208.704  207.106
2016-12-31  317.239  324.563  325.670  317.239
2017-12-31  707.948  687.725  716.329  681.918
2018-12-31  563.300  590.010  596.400  560.000
2019-12-31  835.000  853.990  866.680  830.170

# 利用resample從新採樣:獲取每一年最後一天的股票信息
# 當前是2019-04-21,前面剔除了4月的數據,因此計算是到2019年3月
# 2019年還未結束,因此最後手裏應該還持有2019年前三個月月初買入的股票
In [85]: df.resample('A').last()[:-1]                                                                                                                                                                                                     
Out[85]: 
               open    close     high      low
date                                          
2001-12-31    5.885    6.023    6.140    5.852
2002-12-31    4.473    4.448    4.504    4.447
2003-12-31    4.940    4.921    4.940    4.888
2004-12-31    9.325    9.310    9.579    9.168
2005-12-31   14.309   14.039   14.316   13.817
2006-12-31   53.482   54.946   57.617   52.900
2007-12-31  139.495  144.783  144.846  137.085
2008-12-31   68.502   68.818   69.318   68.058
2009-12-31  107.993  108.369  108.516  107.718
2010-12-31  117.103  118.469  118.701  116.620
2011-12-31  138.039  138.468  139.600  136.105
2012-12-31  155.208  152.087  156.292  150.144
2013-12-31   93.188   96.480   97.179   92.061
2014-12-31  157.642  161.056  161.379  157.132
2015-12-31  207.487  207.458  208.704  207.106
2016-12-31  317.239  324.563  325.670  317.239
2017-12-31  707.948  687.725  716.329  681.918
2018-12-31  563.300  590.010  596.400  560.000

In [86]: df_yearly = df.resample('A').last()[:-1]


# 計算2001年9月到2019年3月購買茅臺股票的當前收益
# 當前收益包括兩部分:以前每一年清倉後的收益和當前持有2019年的股票市值
In [93]: cost = 0                                                                                                                                                                                                                         

In [94]: hold = 0                                                                                                                                                                                                                         

In [95]: for year in range(2001, 2020): 
    ...:     cost += df_monthly[str(year)]['open'].sum()*100 
    ...:     hold += len(df_monthly[str(year)])*100 
    ...:     if 2019 != year: 
    ...:         cost -= df_yearly[str(year)]['open'][0]*hold 
    ...:         hold = 0 
    ...:                                                                                                                                                                                                                                  

In [96]: cost -= hold*price_last                                                                                                                                                                                                          

In [97]: print(-cost)           # 45萬...     (5塊錢漲到943塊...)                                                                                                                                                                                                     
454879.89999999985

In [98]: 

 

2、查找歷史金叉死叉日期

1. 獲取平安銀行股票(601318)的歷史行情數據spa

3d

2. 計算該股票歷史數據的5日均線和30日均線並進行可視化展現code

5日均線:其實就是最近5天的收盤價的簡單移動平均

2.1 純手寫

In [159]: df = pd.read_csv('601318.20190412.csv',index_col='date',parse_dates=['date'])[['open','close','high','low']]                                                                                                                    

In [160]: df.head()                                                                                                                                                                                                                       
Out[160]: 
              open   close    high     low
date                                      
2007-03-01  21.254  19.890  21.666  19.469
2007-03-02  19.979  19.728  20.166  19.503
2007-03-05  19.545  18.865  19.626  18.504
2007-03-06  18.704  19.235  19.554  18.597
2007-03-07  19.252  19.758  19.936  19.090

In [161]: for i in range(4,len(df)): 
     ...:     df.loc[df.index[i],'ma5'] = df['close'][i-4:i+1].mean() 
     ...:                                                                                                                                                                                                                                 

In [162]: for i in range(29,len(df)): 
     ...:     df.loc[df.index[i],'ma30'] = df['close'][i-29:i+1].mean() 
     ...:                                                                                                                                                                                                                                 

In [163]: df.head()                                                                                                                                                                                                                       
Out[163]: 
              open   close    high     low      ma5  ma30
date                                                     
2007-03-01  21.254  19.890  21.666  19.469      NaN   NaN
2007-03-02  19.979  19.728  20.166  19.503      NaN   NaN
2007-03-05  19.545  18.865  19.626  18.504      NaN   NaN
2007-03-06  18.704  19.235  19.554  18.597      NaN   NaN
2007-03-07  19.252  19.758  19.936  19.090  19.4952   NaN

In [164]: df.tail()                                                                                                                                                                                                                       
Out[164]: 
             open  close   high    low     ma5       ma30
date                                                     
2019-04-15  82.23  81.66  83.88  81.60  81.188  75.443333
2019-04-16  81.22  85.01  85.13  80.90  81.970  75.857667
2019-04-17  84.92  84.48  85.35  83.80  82.460  76.271333
2019-04-18  84.69  84.30  85.02  83.88  83.178  76.676000
2019-04-19  85.27  87.00  87.00  84.20  84.490  77.233000

In [165]: 

2.2 pandas實現

In [167]: df['ma5'] = df['close'].rolling(5).mean()                                                                                                                                                                                       

In [168]: df['ma30'] = df['close'].rolling(30).mean()

2.3 numpy實現進行卷積運算

In [216]: df = pd.read_csv('601318.20190412.csv',index_col='date',parse_dates=['date'])[['open','close','high','low']]                                                                                                                   
 
In [217]: weights = np.ones(5)/5          # 構造array                                                                                                                                                                                               
 
In [218]: weights                                                                                                                                                                                                                        
Out[218]: array([0.2, 0.2, 0.2, 0.2, 0.2])

# np.convolve 卷積運算
# np.hstack,即 horizontal stack,獲得ma5的array
In [219]: arr = np.hstack( (np.array([np.NaN]*4),np.convolve(df['close'],weights)[4:-4]) )                                                                                                                                               

# 構造ma5的df_ma5
In [220]: df_ma5 = pd.DataFrame({'ma5':arr},index=df.index)                                                                                                                                                                              
 
In [221]: df_ma5.head()                                                                                                                                                                                                                  
Out[221]:
                ma5
date              
2007-03-01      NaN
2007-03-02      NaN
2007-03-05      NaN
2007-03-06      NaN
2007-03-07  19.4952
 
In [222]: df.head()                                                                                                                                                                                                                      
Out[222]:
              open   close    high     low
date                                     
2007-03-01  21.254  19.890  21.666  19.469
2007-03-02  19.979  19.728  20.166  19.503
2007-03-05  19.545  18.865  19.626  18.504
2007-03-06  18.704  19.235  19.554  18.597
2007-03-07  19.252  19.758  19.936  19.090

# 合併到df裏
In [223]: df = pd.concat([df, df_ma5], axis=1, join_axes=[df.index])                                                                                                                                                                     
 
In [224]: df.head()                                                                                                                                                                                                                      
Out[224]:
              open   close    high     low      ma5
date                                              
2007-03-01  21.254  19.890  21.666  19.469      NaN
2007-03-02  19.979  19.728  20.166  19.503      NaN
2007-03-05  19.545  18.865  19.626  18.504      NaN
2007-03-06  18.704  19.235  19.554  18.597      NaN
2007-03-07  19.252  19.758  19.936  19.090  19.4952
 
In [225]: df.tail()                                                                                                                                                                                                                      
Out[225]:
             open  close   high    low     ma5
date                                         
2019-04-15  82.23  81.66  83.88  81.60  81.188
2019-04-16  81.22  85.01  85.13  80.90  81.970
2019-04-17  84.92  84.48  85.35  83.80  82.460
2019-04-18  84.69  84.30  85.02  83.88  83.178
2019-04-19  85.27  87.00  87.00  84.20  84.490
 
In [226]:
 
 
# 30日均線同理

 

ma5和ma30可視化

df[['close','ma5','ma30']].plot(figsize=[12,7],title='ALL')
plt.show()

 

3. 查找出金叉和死叉日期

3.1 純手寫

In [232]: df.head()                                                                                                                                                                                                                       
Out[232]: 
              open   close    high     low      ma5  ma30
date                                                     
2007-03-01  21.254  19.890  21.666  19.469      NaN   NaN
2007-03-02  19.979  19.728  20.166  19.503      NaN   NaN
2007-03-05  19.545  18.865  19.626  18.504      NaN   NaN
2007-03-06  18.704  19.235  19.554  18.597      NaN   NaN
2007-03-07  19.252  19.758  19.936  19.090  19.4952   NaN

In [233]: df.shape                                                                                                                                                                                                                        
Out[233]: (2888, 6)

In [234]: df = df.dropna()                                                                                                                                                                                                                

In [235]: df.shape                                                                                                                                                                                                                        
Out[235]: (2859, 6)

In [236]: golden_cross = []                                                                                                                                                                                                               

In [237]: death_cross = []                                                                                                                                                                                                                

In [238]: for i in range(1,len(df)): 
     ...:     if df['ma5'][i]>=df['ma30'][i] and df['ma5'][i-1]<df['ma30'][i-1]: 
     ...:         golden_cross.append(df.index[i].to_pydatetime()) 
     ...:     if df['ma5'][i]<=df['ma30'][i] and df['ma5'][i-1]>df['ma30'][i-1]: 
     ...:         death_cross.append(df.index[i].to_pydatetime()) 
     ...:                                                                                                                                                                                                                                 

In [239]: golden_cross                                                                                                                                                                                                                    
Out[239]: 
[datetime.datetime(2007, 6, 14, 0, 0),
 datetime.datetime(2007, 12, 10, 0, 0),
 datetime.datetime(2008, 4, 23, 0, 0),
 datetime.datetime(2008, 7, 30, 0, 0),
 datetime.datetime(2008, 8, 6, 0, 0),
 datetime.datetime(2008, 8, 26, 0, 0),
 datetime.datetime(2008, 11, 14, 0, 0),
 datetime.datetime(2008, 12, 5, 0, 0),
 datetime.datetime(2009, 3, 6, 0, 0),
 datetime.datetime(2009, 5, 6, 0, 0),
 datetime.datetime(2009, 6, 2, 0, 0),
 datetime.datetime(2009, 9, 14, 0, 0),
 datetime.datetime(2010, 3, 22, 0, 0),
 datetime.datetime(2010, 6, 23, 0, 0),
 datetime.datetime(2010, 12, 9, 0, 0),
 datetime.datetime(2011, 2, 18, 0, 0),
 datetime.datetime(2011, 3, 4, 0, 0),
 datetime.datetime(2011, 4, 6, 0, 0),
 datetime.datetime(2011, 6, 30, 0, 0),
 datetime.datetime(2011, 10, 28, 0, 0),
 datetime.datetime(2012, 1, 13, 0, 0),
 datetime.datetime(2012, 4, 17, 0, 0),
 datetime.datetime(2012, 6, 13, 0, 0),
 datetime.datetime(2012, 9, 13, 0, 0),
 datetime.datetime(2012, 9, 27, 0, 0),
 datetime.datetime(2012, 12, 7, 0, 0),
 datetime.datetime(2013, 4, 22, 0, 0),
 datetime.datetime(2013, 5, 9, 0, 0),
 datetime.datetime(2013, 8, 14, 0, 0),
 datetime.datetime(2013, 10, 14, 0, 0),
 datetime.datetime(2013, 11, 1, 0, 0),
 datetime.datetime(2014, 1, 21, 0, 0),
 datetime.datetime(2014, 4, 2, 0, 0),
 datetime.datetime(2014, 5, 28, 0, 0),
 datetime.datetime(2014, 7, 4, 0, 0),
 datetime.datetime(2014, 9, 5, 0, 0),
 datetime.datetime(2014, 10, 31, 0, 0),
 datetime.datetime(2015, 3, 17, 0, 0),
 datetime.datetime(2015, 5, 25, 0, 0),
 datetime.datetime(2015, 6, 8, 0, 0),
 datetime.datetime(2015, 9, 22, 0, 0),
 datetime.datetime(2015, 12, 4, 0, 0),
 datetime.datetime(2015, 12, 17, 0, 0),
 datetime.datetime(2016, 3, 4, 0, 0),
 datetime.datetime(2016, 4, 14, 0, 0),
 datetime.datetime(2016, 5, 31, 0, 0),
 datetime.datetime(2016, 7, 1, 0, 0),
 datetime.datetime(2016, 8, 9, 0, 0),
 datetime.datetime(2016, 11, 1, 0, 0),
 datetime.datetime(2017, 1, 18, 0, 0),
 datetime.datetime(2017, 3, 24, 0, 0),
 datetime.datetime(2017, 4, 26, 0, 0),
 datetime.datetime(2017, 8, 22, 0, 0),
 datetime.datetime(2017, 10, 12, 0, 0),
 datetime.datetime(2017, 12, 8, 0, 0),
 datetime.datetime(2017, 12, 21, 0, 0),
 datetime.datetime(2018, 1, 12, 0, 0),
 datetime.datetime(2018, 3, 19, 0, 0),
 datetime.datetime(2018, 6, 6, 0, 0),
 datetime.datetime(2018, 7, 24, 0, 0),
 datetime.datetime(2018, 8, 9, 0, 0),
 datetime.datetime(2018, 8, 24, 0, 0),
 datetime.datetime(2018, 10, 22, 0, 0),
 datetime.datetime(2018, 11, 6, 0, 0),
 datetime.datetime(2018, 11, 19, 0, 0),
 datetime.datetime(2019, 1, 21, 0, 0)]

In [240]: death_cross                                                                                                                                                                                                                     
Out[240]: 
[datetime.datetime(2007, 6, 4, 0, 0),
 datetime.datetime(2007, 11, 6, 0, 0),
 datetime.datetime(2007, 12, 13, 0, 0),
 datetime.datetime(2008, 5, 20, 0, 0),
 datetime.datetime(2008, 7, 31, 0, 0),
 datetime.datetime(2008, 8, 13, 0, 0),
 datetime.datetime(2008, 9, 8, 0, 0),
 datetime.datetime(2008, 11, 24, 0, 0),
 datetime.datetime(2009, 3, 3, 0, 0),
 datetime.datetime(2009, 4, 28, 0, 0),
 datetime.datetime(2009, 5, 18, 0, 0),
 datetime.datetime(2009, 8, 11, 0, 0),
 datetime.datetime(2009, 11, 26, 0, 0),
 datetime.datetime(2010, 4, 29, 0, 0),
 datetime.datetime(2010, 11, 16, 0, 0),
 datetime.datetime(2010, 12, 20, 0, 0),
 datetime.datetime(2011, 2, 23, 0, 0),
 datetime.datetime(2011, 3, 17, 0, 0),
 datetime.datetime(2011, 5, 5, 0, 0),
 datetime.datetime(2011, 7, 21, 0, 0),
 datetime.datetime(2011, 11, 21, 0, 0),
 datetime.datetime(2012, 3, 9, 0, 0),
 datetime.datetime(2012, 6, 5, 0, 0),
 datetime.datetime(2012, 7, 27, 0, 0),
 datetime.datetime(2012, 9, 17, 0, 0),
 datetime.datetime(2012, 10, 29, 0, 0),
 datetime.datetime(2013, 2, 25, 0, 0),
 datetime.datetime(2013, 4, 24, 0, 0),
 datetime.datetime(2013, 5, 13, 0, 0),
 datetime.datetime(2013, 10, 9, 0, 0),
 datetime.datetime(2013, 10, 17, 0, 0),
 datetime.datetime(2013, 12, 23, 0, 0),
 datetime.datetime(2014, 1, 28, 0, 0),
 datetime.datetime(2014, 5, 19, 0, 0),
 datetime.datetime(2014, 6, 25, 0, 0),
 datetime.datetime(2014, 8, 26, 0, 0),
 datetime.datetime(2014, 9, 15, 0, 0),
 datetime.datetime(2015, 2, 2, 0, 0),
 datetime.datetime(2015, 5, 18, 0, 0),
 datetime.datetime(2015, 6, 2, 0, 0),
 datetime.datetime(2015, 6, 18, 0, 0),
 datetime.datetime(2015, 12, 1, 0, 0),
 datetime.datetime(2015, 12, 10, 0, 0),
 datetime.datetime(2016, 1, 5, 0, 0),
 datetime.datetime(2016, 4, 12, 0, 0),
 datetime.datetime(2016, 5, 6, 0, 0),
 datetime.datetime(2016, 6, 27, 0, 0),
 datetime.datetime(2016, 8, 8, 0, 0),
 datetime.datetime(2016, 9, 29, 0, 0),
 datetime.datetime(2016, 12, 20, 0, 0),
 datetime.datetime(2017, 3, 2, 0, 0),
 datetime.datetime(2017, 4, 13, 0, 0),
 datetime.datetime(2017, 8, 11, 0, 0),
 datetime.datetime(2017, 9, 20, 0, 0),
 datetime.datetime(2017, 12, 7, 0, 0),
 datetime.datetime(2017, 12, 18, 0, 0),
 datetime.datetime(2017, 12, 29, 0, 0),
 datetime.datetime(2018, 2, 8, 0, 0),
 datetime.datetime(2018, 3, 28, 0, 0),
 datetime.datetime(2018, 6, 25, 0, 0),
 datetime.datetime(2018, 8, 7, 0, 0),
 datetime.datetime(2018, 8, 16, 0, 0),
 datetime.datetime(2018, 10, 15, 0, 0),
 datetime.datetime(2018, 10, 31, 0, 0),
 datetime.datetime(2018, 11, 14, 0, 0),
 datetime.datetime(2018, 11, 20, 0, 0)]

In [241]:  

 

3.2 pandas實現

1 df['ma5'] < df['ma30']
2 
3 TTTFFFTTT
4  FFFTTTFFF
5 
6 df['ma5'] >= df['ma30']

 

In [260]: death_cross = df[sr1 & sr2.shift(1)].index                                                                                                                                                                                      

In [261]: golden_cross = df[~(sr1 | sr2.shift(1))].index                                                                                                                                                                                  

In [262]: golden_cross                                                                                                                                                                                                                    
Out[262]: 
DatetimeIndex(['2007-04-12', '2007-06-14', '2007-12-10', '2008-04-23',
               '2008-07-30', '2008-08-06', '2008-08-26', '2008-11-14',
               '2008-12-05', '2009-03-06', '2009-05-06', '2009-06-02',
               '2009-09-14', '2010-03-22', '2010-06-23', '2010-12-09',
               '2011-02-18', '2011-03-04', '2011-04-06', '2011-06-30',
               '2011-10-28', '2012-01-13', '2012-04-17', '2012-06-13',
               '2012-09-13', '2012-09-27', '2012-12-07', '2013-04-22',
               '2013-05-09', '2013-08-14', '2013-10-14', '2013-11-01',
               '2014-01-21', '2014-04-02', '2014-05-28', '2014-07-04',
               '2014-09-05', '2014-10-31', '2015-03-17', '2015-05-25',
               '2015-06-08', '2015-09-22', '2015-12-04', '2015-12-17',
               '2016-03-04', '2016-04-14', '2016-05-31', '2016-07-01',
               '2016-08-09', '2016-11-01', '2017-01-18', '2017-03-24',
               '2017-04-26', '2017-08-22', '2017-10-12', '2017-12-08',
               '2017-12-21', '2018-01-12', '2018-03-19', '2018-06-06',
               '2018-07-24', '2018-08-09', '2018-08-24', '2018-10-22',
               '2018-11-06', '2018-11-19', '2019-01-21'],
              dtype='datetime64[ns]', name='date', freq=None)

In [263]: death_cross                                                                                                                                                                                                                     
Out[263]: 
DatetimeIndex(['2007-06-04', '2007-11-06', '2007-12-13', '2008-05-20',
               '2008-07-31', '2008-08-13', '2008-09-08', '2008-11-24',
               '2009-03-03', '2009-04-28', '2009-05-18', '2009-08-11',
               '2009-11-26', '2010-04-29', '2010-11-16', '2010-12-20',
               '2011-02-23', '2011-03-17', '2011-05-05', '2011-07-21',
               '2011-11-21', '2012-03-09', '2012-06-05', '2012-07-27',
               '2012-09-17', '2012-10-29', '2013-02-25', '2013-04-24',
               '2013-05-13', '2013-10-09', '2013-10-17', '2013-12-23',
               '2014-01-28', '2014-05-19', '2014-06-25', '2014-08-26',
               '2014-09-15', '2015-02-02', '2015-05-18', '2015-06-02',
               '2015-06-18', '2015-12-01', '2015-12-10', '2016-01-05',
               '2016-04-12', '2016-05-06', '2016-06-27', '2016-08-08',
               '2016-09-29', '2016-12-20', '2017-03-02', '2017-04-13',
               '2017-08-11', '2017-09-20', '2017-12-07', '2017-12-18',
               '2017-12-29', '2018-02-08', '2018-03-28', '2018-06-25',
               '2018-08-07', '2018-08-16', '2018-10-15', '2018-10-31',
               '2018-11-14', '2018-11-20'],
              dtype='datetime64[ns]', name='date', freq=None)

In [264]: 

 

注意:判斷金叉和死叉,應該依賴天天的開盤價,更符合事實。

這裏作練習就以收盤價作實驗了。 

 

4. 假如我從2010年1月1日開始,初始資金是100000元,金叉儘可能買入,死叉所有賣出;

那麼迄今爲止,個人炒股收益如何?

In [304]: sr1 = pd.Series(1,index=golden_cross)                                                                                                                                                                                           

In [305]: sr1[:5]                                                                                                                                                                                                                         
Out[305]: 
date
2010-03-22    1
2010-06-23    1
2010-12-09    1
2011-02-18    1
2011-03-04    1
dtype: int64

In [306]: sr2 = pd.Series(0,index=death_cross)                                                                                                                                                                                            

In [307]: sr2[:5]                                                                                                                                                                                                                         
Out[307]: 
date
2010-04-29    0
2010-11-16    0
2010-12-20    0
2011-02-23    0
2011-03-17    0
dtype: int64

In [308]: sr = sr1.append(sr2).sort_index()    # 把金叉和死叉按時間順序組合                                                                                                                                                                                           

In [309]: sr[:6]                                                                                                                                                                                                                          
Out[309]: 
date
2010-03-22    1
2010-04-29    0
2010-06-23    1
2010-11-16    0
2010-12-09    1
2010-12-20    0
dtype: int64

In [310]: first_money = 100000                                                                                                                                                                                                            

In [311]: money = first_money                                                                                                                                                                                                             

In [312]: hold = 0 # 持有多少股                                                                                                                                                                                                           

In [313]: for i in range(0,len(sr)): 
     ...:     p = df['open'][sr.index[i]] 
     ...:     if 1 == sr.iloc[i]: 
     ...:         # 金叉,應該儘可能買入 
     ...:         buy = money//(p*100) 
     ...:         hold += buy*100 
     ...:         money -= buy*100*p 
     ...:     else: 
     ...:         # 死叉,應該所有賣出 
     ...:         money += hold*p 
     ...:         hold = 0 
     ...:                                                                                                                                                                                                                                 

In [314]: p = df['open'][-1] # 記住最後一天的開盤價                                                                                                                                                                                       

In [315]: now_money = money + hold*p  # 所有收益包括兩部分:持有股票價值和手裏已有的現金                                                                                                                                                  

In [316]: print(now_money-first_money)                                                                                                                                                                                                    
502734.7999999997

In [317]: 

 

3、第一個量化策略

編譯運行

# 導入函數庫
from jqdata import *

# 初始化函數,設定基準等等
def initialize(context):
    # 設置基本收益
    set_benchmark('000300.XSHG')
    # 獲取股票池
    g.security = get_index_stocks('000300.XSHG')
    set_option('use_real_price', True)
    # 股票類每筆交易時的手續費是:買入時佣金萬分之三,賣出時佣金萬分之三加千分之一印花稅, 每筆交易佣金最低扣5塊錢
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, open_commission=0.0003, close_commission=0.0003, close_today_commission=0, min_commission=5), type='stock')

# 每一個交易日執行一次
def handle_data(context, data):
    # 通常狀況下先賣後買
    tobuy = []
    for stock in g.security:
        p = get_current_data()[stock].day_open
        # 持有的股票數量
        amount = context.portfolio.positions[stock].total_amount
        # 平均的開倉成本
        cost = context.portfolio.positions[stock].avg_cost
        if amount>0 and p>=cost*1.25:
            order_target(stock, 0)      # 清倉止盈
        if amount>0 and p<=cost*0.9:
            order_target(stock, 0)      # 清倉止損
        if p<=10 and 0==amount:
            tobuy.append(stock)         # 能夠買
            
    cash_per_stock = context.portfolio.available_cash / len(tobuy)
    for stock in tobuy:
        order_value(stock, cash_per_stock)
    
相關文章
相關標籤/搜索