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
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')
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]:
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]:
# 導入函數庫 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)