zoukankan      html  css  js  c++  java
  • 金融量化

    一、股票数据分析

    1. 获取茅台股票数据并存储到本地csv文件

     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%以上的日期

    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%的日期

    涉及到和前一天数据相比,笨办法自己写for循环,

    好在pandas提供了shift函数,非常方便的移动df的数据

    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股)股票,每年最后一个交易日卖出所有股票,

    那么迄今为止, 我的收益是多少?

    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]: 
    

    二、查找历史金叉死叉日期

    1. 获取平安银行股票(601318)的历史行情数据

    2. 计算该股票历史数据的5日均线和30日均线并进行可视化展示

    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]: 
    

    三、第一个量化策略

    编译运行

    # 导入函数库
    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)
        
    
  • 相关阅读:
    python 给文件批量加‘“’ ”,"
    ubuntu 编译android 源码笔记
    ubuntu java 环境配置
    Android4.4r1(KitKat)源码下载地址
    android 学习视频汇总
    Java 注解
    Linux 索引节点(inode)详解
    系统启动
    Win7、Ubuntu双系统正确卸载Ubuntu系统
    深入理解LInux内核-进程通信
  • 原文地址:https://www.cnblogs.com/standby/p/10745043.html
Copyright © 2011-2022 走看看