├── Elements ├── 布林止損對照組.png ├── 1413_sharpe_對照.png ├── drawdown_plot.png ├── 1413_drawdown_實驗.png ├── 1413_drawdown_對照.png ├── 1413_portfolio_對照.png ├── 1413_rolling_Sharpe.png ├── 1413_drawdown_periods.png └── 1413_rolling_Sharpe1.png ├── README.md ├── Price_to_Earnings_Ratio.py ├── Medium_Pre IPO.py ├── 國安基金.py ├── 元富 API 下單介紹.ipynb ├── Black Scholes Merton Model.ipynb ├── Survivorship_bias.ipynb ├── seekingalpha.ipynb ├── CRR model.ipynb └── TEJAPI_MediumWeek5.ipynb /Elements/布林止損對照組.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/布林止損對照組.png -------------------------------------------------------------------------------- /Elements/1413_sharpe_對照.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_sharpe_對照.png -------------------------------------------------------------------------------- /Elements/drawdown_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/drawdown_plot.png -------------------------------------------------------------------------------- /Elements/1413_drawdown_實驗.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_drawdown_實驗.png -------------------------------------------------------------------------------- /Elements/1413_drawdown_對照.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_drawdown_對照.png -------------------------------------------------------------------------------- /Elements/1413_portfolio_對照.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_portfolio_對照.png -------------------------------------------------------------------------------- /Elements/1413_rolling_Sharpe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_rolling_Sharpe.png -------------------------------------------------------------------------------- /Elements/1413_drawdown_periods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_drawdown_periods.png -------------------------------------------------------------------------------- /Elements/1413_rolling_Sharpe1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tejtw/TEJAPI_Python_Medium_Quant/HEAD/Elements/1413_rolling_Sharpe1.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TEJAPI_Python_Medium_Quant 2 | Medium 文章程式碼-Week5, Week9 3 | 4 | ## 主題:Python_量化分析 5 | 程式內容說明
6 | Week5:透過Python以0050為主要標的進行定期定額回測操作
7 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-一-定期定額與複利的效果-8787f3851273
8 | 9 | Week9:透過Python對技術分析指標進行簡介、程式碼撰寫及應用
10 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-二-技術分析簡介與回測-14ae9bbb9c76
11 | 12 | Week10:透過Python使用機器學習模組來對市場進行預測
13 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-三-預測市場-bde88352a011
14 | 15 | 量化分析4:透過Python使用籌碼分析來撰寫股價回測
16 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-四-跟隨大戶的交易策略-f0fb8fae9401
17 | 18 | 量化分析5:驗證產業動態指數的預測性(營收篇)
19 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-五-台電產業動態指數之應用-營收篇-8253926f9e3b
20 | 21 | 量化分析6:透過Python進行事件研究法
22 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-六-現金增資宣告效果-以事件研究法為例-e14d6e1854d2
23 | 24 | 量化分析7:效率前緣
25 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-七-效率前緣曲線-cfbe972274
26 | 27 | 量化分析8:MACD回測實戰
28 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-八-macd指標回測實戰-8794ca221029
29 | 30 | 量化分析9:ESG量化因子選股
31 | Medium文章連結:
Https://medium.com/tej-api-金融資料分析/量化分析-九-esg量化因子選股-4dbaec338e64
32 | 33 | 量化分析10:KD指標回測
34 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十-kd指標回測實戰-5e743c10468b 35 | 36 | 量化分析11:雙因子權重設置
37 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十一-雙因子權重設置-bf05d78c7b4a 38 | 39 | 量化分析12:衡量公司盈餘管理程度
40 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十二-衡量公司盈餘管理程度-6b41704baa72 41 | 42 | 量化分析13:RSI指標回測實戰
43 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十三-rsi指標回測實戰-1d915873f1f7 44 | 45 | 量化分析14:三大法人都買哪些產業?
46 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十四-三大法人都買哪些產業-45a7c4152bfe 47 | 48 | 量化分析15:量能回測實戰
49 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十四-量能回測實戰-e174fb5ebafb 50 |
備註:不用擔心網址出現,量化分析-十四,連結是量化分析十五的文章沒錯。 51 | 52 | 量化分析16投資組合風險值
53 | Medium文章連結:
https://medium.com/tej-api-金融資料分析/量化分析-十六-投資組合風險值-f4b62645258b 54 | 55 | 56 | 量化分析17防禦型股票填權息探討
57 | Medium文章連結:
https://medium.com/tej-api--金融資料分析/量化分析-十七-防禦型股票填權息探討-443af3db8a45 58 | 59 | 量化分析18 殖利率曲線倒掛
60 | Medium文章連結:
https://medium.com/tej-api--金融資料分析/量化分析-十八-殖利率曲線倒掛-2dfd996ca6a0 61 | ## 備註 62 | 資料庫使用:
TEJ E SHOP 斜槓方案-證券交易資料表(TWN/EWPRCD)
63 | TEJ E SHOP 斜槓方案-報酬率資訊表(TWN/EWPRCD2) 64 | -------------------------------------------------------------------------------- /Price_to_Earnings_Ratio.py: -------------------------------------------------------------------------------- 1 | import tejapi 2 | import matplotlib.pyplot as plt 3 | 4 | tejapi.ApiConfig.api_key = "your_api_key" 5 | 6 | company = '2330' 7 | price_data = tejapi.get('TWN/EWIFINQ', # tej 財務資料庫 8 | coid = company, 9 | mdate={ 10 | # 起始日期 11 | 'gte':'2022-01-01', 12 | # 結束日期 13 | 'lte':'2022-12-31'}, 14 | opts={'columns': ['coid','mdate','ac_3990']}, 15 | paginate=True 16 | ) 17 | 18 | company_data = tejapi.get( 19 | 'TWN/EWPRCD', # 資料庫 20 | coid=company, # 股票代碼 21 | mdate={ 22 | # 起始日期 23 | 'gte':'2018-01-01', 24 | # 結束日期 25 | 'lte':'2018-12-31'}, 26 | paginate=True, 27 | opts={'columns': ['mdate', 'close_d']}, 28 | ) 29 | 30 | print(price_data['ac_3990']) 31 | print(company_data['close_d']) 32 | close = company_data['close_d'] 33 | 34 | Price_to_Earnings_Ratio = [] 35 | quarter = [60,63,63,61] 36 | quarter_count = 0 37 | season_days = 0 38 | init_day = 0 39 | 40 | while quarter_count<4: 41 | season_days = quarter[quarter_count] # 每季有幾天 42 | print(init_day+season_days) 43 | for i in range(init_day, int(init_day+season_days)): 44 | Price_to_Earnings_Ratio.append(round(company_data['close_d'][i]/price_data['ac_3990'][quarter_count])) 45 | init_day = init_day + season_days 46 | quarter_count += 1 47 | 48 | # print(Price_to_Earnings_Ratio) 49 | # 設定畫出本益比倍數 50 | x = [x for x in range(0, len(close))] 51 | Price_to_Earnings_Ratio_30 = [ratio * 30 for ratio in Price_to_Earnings_Ratio] 52 | Price_to_Earnings_Ratio_35 = [ratio * 35 for ratio in Price_to_Earnings_Ratio] 53 | Price_to_Earnings_Ratio_40 = [ratio * 40 for ratio in Price_to_Earnings_Ratio] 54 | Price_to_Earnings_Ratio_45 = [ratio * 35 for ratio in Price_to_Earnings_Ratio] 55 | Price_to_Earnings_Ratio_50 = [ratio * 50 for ratio in Price_to_Earnings_Ratio] 56 | 57 | # 畫出本益比 58 | plt.plot(x, Price_to_Earnings_Ratio_30, label='Ratio=30', color='blue') 59 | plt.plot(x, Price_to_Earnings_Ratio_35, label='Ratio=35', color='blue') 60 | plt.plot(x, Price_to_Earnings_Ratio_40, label='Ratio=40', color='yellow') 61 | plt.plot(x, Price_to_Earnings_Ratio_45, label='Ratio=45', color='brown') 62 | plt.plot(x, Price_to_Earnings_Ratio_50, label='Ratio=50', color='purple') 63 | plt.plot(x, close.tolist(), label='K line', color='red') # 畫出收盤價曲線 64 | 65 | plt.title('Price_to_Earnings_Ratio') # 設定圖形標題 66 | plt.xlabel('Days') # 設定X軸標籤 67 | plt.ylabel('Ratio') # 設定Y軸標籤 68 | plt.legend() # 添加圖例 69 | plt.show() 70 | 71 | -------------------------------------------------------------------------------- /Medium_Pre IPO.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Aug 2 11:36:14 2022 4 | 5 | @author: Mark 6 | """ 7 | 8 | import numpy as np 9 | import pandas as pd 10 | from scipy.stats.mstats import gmean 11 | import matplotlib.pyplot as plt 12 | plt.rcParams['axes.unicode_minus'] = False 13 | plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei'] 14 | import tejapi 15 | import time 16 | tejapi.ApiConfig.api_key="EyUSGsEJr8ouhg7nDjtVrPcPlexvSI" 17 | tejapi.ApiConfig.api_base="http://10.10.10.66" 18 | tejapi.ApiConfig.ignoretz = True 19 | 20 | #%%資料撈取整理計算報酬 21 | 22 | df = pd.read_excel('C:/Users/Mark/Desktop/Python/PreIPO Python/TEST2.xlsx') 23 | A1 = df[['代號','名稱','上市日收盤價(元)','上市日後一天收盤價(元)','上市日後二天收盤價(元)','上市日後三天收盤價(元)','上市日後四天收盤價(元)','上市日後五天收盤價(元)']] 24 | # A1 = A1.rename(columns={"代號" : "公司簡稱"}, inplace = False) 25 | A2 = A1[['上市日收盤價(元)','上市日後一天收盤價(元)','上市日後二天收盤價(元)','上市日後三天收盤價(元)','上市日後四天收盤價(元)','上市日後五天收盤價(元)']] 26 | A3 = A2.copy() 27 | for i in range(1, len(A2.columns)): 28 | A3.iloc[:,i:i+1] = ((A2.iloc[:,i:i+1].values)/(A2.iloc[:,0:1].values))-1 29 | # 此段非單日日報酬計算,屬於累積報酬 30 | 31 | # A3 = A2.T 32 | # A3 = A3.pct_change(1)*100 33 | # A3 = A3.T 34 | # 單日日報酬計算,需先將Dataframe矩陣轉置 35 | 36 | # def culmulative(df,p): 37 | # df =df.copy() 38 | # df["後二日累積報酬率"]=df.rolling(p).gmean() 39 | # return df 40 | # CR = culmulative(A3 , 3) 41 | # 無意義的一段 42 | 43 | A3 = A3.rename(columns={'上市日後一天收盤價(元)' : '後一日累積報酬率%', 44 | '上市日後二天收盤價(元)' : '後二日累積報酬率%', 45 | '上市日後三天收盤價(元)' : '後三日累積報酬率%', 46 | '上市日後四天收盤價(元)' : '後四日累積報酬率%', 47 | '上市日後五天收盤價(元)' : '後五日累積報酬率%'}, inplace = False) 48 | data = A3.drop('上市日收盤價(元)',axis=1) 49 | data1 = A1.join(data, how = "left") 50 | 51 | Company = A1['代號'].to_list() 52 | Detail = tejapi.get('TWN/AIND', chinese_column_name = True , paginate = True, coid = Company, 53 | opts={'columns':['coid','ind1']}) # 舊產業名 54 | Detail = Detail.rename(columns={"公司簡稱" : "代號"}, inplace = False) 55 | #Detail['TSE 產業別'] = Detail['TSE 產業別'].map(lambda x : int(x)) 56 | qq = Detail[Detail['TSE 產業別'] != "17" ] 57 | qq = qq[qq['TSE 產業別'] != "14" ] 58 | qq = qq[qq['TSE 產業別'] != "19" ] 59 | qq = qq[qq['TSE 產業別'] != "20" ] 60 | qq = qq[qq['TSE 產業別'] != "80" ] 61 | qq = qq[qq['TSE 產業別'] != "32" ] 62 | qq = qq[qq['TSE 產業別'] != "33" ] 63 | qq = qq[qq['TSE 產業別'] != "34" ] 64 | qq = qq[qq['TSE 產業別'] != "91" ] 65 | PreIPO = data1.merge(qq, on='代號') 66 | 67 | #%%依照產業計算勝率繪製圖表 68 | 69 | PreIPO = PreIPO.dropna(axis=0,how='any') # 清空NA 70 | industry_name = np.unique(PreIPO[['TSE 產業別']]) 71 | payoff = np.array(['後一日累積報酬率%','後二日累積報酬率%','後三日累積報酬率%','後四日累積報酬率%','後五日累積報酬率%']) 72 | industry_number = len(PreIPO.groupby('TSE 產業別').count()) 73 | save_IPO = list() 74 | for i in range(industry_number): 75 | for j in range(len(payoff)): 76 | positive_payoff = len(PreIPO[(PreIPO['TSE 產業別'] == industry_name[i]) & (PreIPO[payoff[j]] > 0)]) 77 | total_number = len(PreIPO[(PreIPO['TSE 產業別'] == industry_name[i])]) 78 | save_IPO.append(f'{round(positive_payoff/total_number*100,2)}') 79 | x = np.array(save_IPO) 80 | x = x.reshape([27,5]) 81 | make_form= pd.DataFrame(x) 82 | make_form.columns = ['上市/櫃後一日勝率%','上市/櫃後二日勝率%','上市/櫃後三日勝率%','上市/櫃後四日勝率%','上市/櫃後五日勝率%'] 83 | make_form.index = industry_name 84 | make_form 85 | 86 | a = industry_name.tolist() 87 | b = make_form['上市/櫃後一日勝率%'] 88 | c = make_form['上市/櫃後二日勝率%'] 89 | d = make_form['上市/櫃後三日勝率%'] 90 | e = make_form['上市/櫃後四日勝率%'] 91 | f = make_form['上市/櫃後五日勝率%'] 92 | y = [] 93 | for i in range(len(b)): 94 | b[i] = float(b[i]) 95 | c[i] = float(c[i]) 96 | d[i] = float(d[i]) 97 | e[i] = float(e[i]) 98 | f[i] = float(f[i]) 99 | for i in range(27): 100 | y.append(round((b[i]+c[i]+d[i]+e[i]+f[i])/5,2)) 101 | 102 | plt.figure(figsize=(20,15)) 103 | plt.plot(a,b,color = 'red',marker='o', label="上市/櫃後一日勝率%") 104 | plt.plot(a,c,color = 'green',marker='o', label="上市/櫃後二日勝率%") 105 | plt.plot(a,d,color = 'orange',marker='o', label="上市/櫃後三日勝率%") 106 | plt.plot(a,e,color = 'mediumblue',marker='o', label="上市/櫃後四日勝率%") 107 | plt.plot(a,f,color = 'purple',marker='o', label="上市/櫃後五日勝率%") 108 | plt.axhline(y=60, xmin=0, xmax=1, label='60%線') 109 | plt.title("上市/櫃 勝率",fontsize=30, x=0.5, y=1.03) 110 | plt.xticks(fontsize=15) 111 | plt.yticks(fontsize=20) 112 | plt.xlabel("產業", fontsize=30, labelpad = 20) 113 | plt.ylabel("勝率%", fontsize=30, labelpad = 20) 114 | plt.legend(loc = "best",fontsize=20) 115 | plt.gcf().autofmt_xdate() 116 | plt.show() 117 | 118 | 119 | PreIPO = PreIPO.dropna(axis=0,how='any') # 清空NA 120 | industry_name = np.unique(PreIPO[['TSE 產業別']]) 121 | payoff = np.array(['後一日累積報酬率%','後二日累積報酬率%','後三日累積報酬率%','後四日累積報酬率%','後五日累積報酬率%']) 122 | industry_number = len(PreIPO.groupby('TSE 產業別').count()) 123 | save_IPO = list() 124 | for i in range(industry_number): 125 | for j in range(len(payoff)): 126 | industry_payoff = PreIPO[payoff[j]][PreIPO['TSE 產業別']==industry_name[i]].mean() 127 | save_IPO.append(f'{round(industry_payoff*100,2)}') 128 | x = np.array(save_IPO) 129 | x = x.reshape([27,5]) 130 | 131 | make_form2= pd.DataFrame(x) 132 | make_form2.columns = ['後一日累積報酬率%','後二日累積報酬率%','後三日累積報酬率%','後四日累積報酬率%','後五日累積報酬率%'] 133 | make_form2.index = industry_name 134 | 135 | #=============================繪圖================================= 136 | 137 | a = industry_name.tolist() 138 | b = make_form2['後一日累積報酬率%'] 139 | c = make_form2['後二日累積報酬率%'] 140 | d = make_form2['後三日累積報酬率%'] 141 | e = make_form2['後四日累積報酬率%'] 142 | f = make_form2['後五日累積報酬率%'] 143 | for i in range(len(b)): 144 | b[i] = float(b[i]) 145 | c[i] = float(c[i]) 146 | d[i] = float(d[i]) 147 | e[i] = float(e[i]) 148 | f[i] = float(f[i]) 149 | y = [] 150 | for i in range(27): 151 | y.append(round((b[i]+c[i]+d[i]+e[i]+f[i])/5,2)) 152 | 153 | 154 | plt.figure(figsize=(23,13)) 155 | plt.plot(a,b,color = 'red',marker='o', label="後一日累積報酬率%") 156 | plt.plot(a,c,color = 'green',marker='o', label="後二日累積報酬率%") 157 | plt.plot(a,d,color = 'orange',marker='o', label="後三日累積報酬率%") 158 | plt.plot(a,e,color = 'mediumblue',marker='o', label="後四日累積報酬率%") 159 | plt.plot(a,f,color = 'purple',marker='o', label="後五日累積報酬率%") 160 | plt.axhline(y=10, xmin=0, xmax=1, label='10%線') 161 | plt.title("上市/櫃 報酬率",fontsize=30, x=0.5, y=1.03) 162 | plt.xticks(fontsize=15) 163 | plt.yticks(fontsize=20) 164 | plt.xlabel("產業", fontsize=30, labelpad = 20) 165 | plt.ylabel("報酬率%", fontsize=30, labelpad = 20) 166 | plt.legend(loc = "best",fontsize=20) 167 | plt.gcf().autofmt_xdate() 168 | plt.show() 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /國安基金.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | # In[1]: 5 | 6 | 7 | pip install tejapi 8 | 9 | 10 | # In[47]: 11 | 12 | 13 | import tejapi 14 | import pandas as pd 15 | import numpy as np 16 | 17 | tejapi.ApiConfig.api_key = "Your Key" 18 | tejapi.ApiConfig.ignoretz = True 19 | #----------------------------------------------------------------- 20 | mdate = {'gte':'2022-07-13', 'lte':'2022-11-14'}#國安基金進場期間 21 | coid = "Y9997"#大盤代號 22 | data = tejapi.get('TWN/APRCD1', 23 | coid = coid, 24 | mdate = mdate, 25 | paginate=True) 26 | df = pd.DataFrame({"日期":data["mdate"],"大盤":data["close_adj"]}) 27 | 28 | 29 | # In[18]: 30 | 31 | 32 | 33 | 34 | 35 | # In[48]: 36 | 37 | 38 | coid = ["1101","1301","1303","1326","2308","2317","2330","2382","2880","2886"] 39 | 40 | for i in range(0,len(coid)): 41 | 42 | stock = tejapi.get('TWN/APRCD1', 43 | coid = coid[i], 44 | mdate = mdate, 45 | paginate=True) 46 | df1 = pd.DataFrame({"日期":stock["mdate"],str(coid[i]):stock["close_adj"]}) 47 | #以日期做合併 48 | df = pd.merge(df,df1,left_on="日期",right_on="日期",how="outer") 49 | df 50 | 51 | 52 | # In[ ]: 53 | 54 | 55 | 56 | 57 | 58 | # In[49]: 59 | 60 | 61 | #算個別個股績效 62 | #(每天股價-國安基金進場第一天股價)/國安基金進場第一天股價 63 | df2 = (df.iloc[:, 1:] - df.iloc[0, 1:].values.squeeze()).div(df.iloc[:, 1:]) 64 | #四捨五入 65 | df2 = df2.astype(float).round(3) 66 | df_result = pd.DataFrame({"日期":df["日期"]}) 67 | 68 | df_result = pd.merge(df_result,df2,left_on=None,right_on=None,left_index=True, 69 | right_index=True) 70 | df_result 71 | 72 | 73 | # In[50]: 74 | 75 | 76 | df = df_result.copy() 77 | 78 | import matplotlib.pyplot as plt 79 | 80 | df.set_index(pd.to_datetime(df["日期"], format="%Y-%m-%d"), inplace=True) 81 | del(df["日期"]) 82 | 83 | plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei'] 84 | plt.rcParams['axes.unicode_minus'] = False 85 | 86 | #畫圖 87 | fig, ax1 = plt.subplots(figsize=(20, 10)) 88 | for i in range(0,len(coid)): 89 | plt.plot(df.index,df[coid[i]],lw=1.5,label=coid[i]) 90 | 91 | plt.plot(df.index,df["大盤"],lw=5,label="大盤",color="blue") 92 | plt.xlabel("日期",fontsize=20) 93 | plt.ylabel("累積報酬",fontsize=20) 94 | plt.xticks(fontsize=20) 95 | plt.yticks(fontsize=20) 96 | plt.title("第八次國安基金熱門標的股價表現與大盤比較",fontsize=30) 97 | plt.legend(bbox_to_anchor=(1, 1.0)) 98 | plt.show() 99 | 100 | 101 | # In[ ]: 102 | 103 | 104 | #============================================================================================================= 105 | 106 | 107 | # In[52]: 108 | 109 | 110 | import tejapi 111 | import pandas as pd 112 | 113 | tejapi.ApiConfig.api_key = "Your Key" 114 | tejapi.ApiConfig.ignoretz = True 115 | #----------------------------------------------------------------------------- 116 | #第八次國安基金進場 117 | mdate = {'gte':'2020-03-20', 'lte':'2020-10-12'} 118 | #八大券商 119 | bank = ["000102 合庫證券","000538 第一金證","000104 臺銀證券","2801 彰銀", 120 | "2834 臺企銀","5857 土銀","000930 華南永昌證券","000700 兆豐證券"] 121 | #國安基金熱門標的 122 | coid = ["1101","1301","1303","1326","2308","2317","2330","2382","2880","2886"] 123 | 124 | 125 | # In[53]: 126 | 127 | 128 | cor = [] 129 | for i in coid: 130 | 131 | #--------------------------------------------------------------------------- 132 | #個股股價 133 | market = tejapi.get('TWN/APRCD1', 134 | coid = i, 135 | mdate = mdate, 136 | paginate=True) 137 | #累積買賣超 138 | df = pd.DataFrame({"日期":market["mdate"],"股價":market["close_d"]}) 139 | #--------------------------------------------------------------------------- 140 | #個股券商買賣超 141 | data = tejapi.get('TWN/AMTOP1', 142 | coid = i, 143 | mdate = mdate, 144 | paginate=True) 145 | #--------------------------------------------------------------------------- 146 | for i in range(0,len(bank)): 147 | #選出八大券商 148 | broker = bank[i] 149 | data1 = data[data["key3"] == broker] 150 | 151 | bs_data = data1[["mdate","bs_m"]] 152 | bs_data = bs_data.rename(columns={"mdate": '日期',"bs_m": str(broker)}) 153 | #算出八大券商期間累積買賣超 154 | df = pd.merge(df,bs_data,left_on="日期",right_on="日期",how="outer") 155 | df[str(broker)] = df[str(broker)].fillna(0) 156 | bs_m_list = list(df[str(broker)]) 157 | agg = [] 158 | n = 0 159 | for j in range(0,len(bs_m_list)): 160 | n = n + bs_m_list[j] #每日淨買賣 161 | agg = agg + [n] # #每日加總 162 | df[str(broker)] = agg 163 | #八大券商買賣總金額 164 | df_total = pd.DataFrame({"股價":market["close_d"], 165 | "八大淨買賣總和":df[bank].sum(axis=1)}) 166 | #標準化 167 | from sklearn.preprocessing import StandardScaler 168 | df_total[df_total.columns] = StandardScaler().fit_transform(df_total[df_total.columns]) 169 | #相關性 170 | df_total_cor = round(df_total['股價'].corr(df_total["八大淨買賣總和"]),2) 171 | cor = cor + [df_total_cor] 172 | 173 | df_cor = pd.DataFrame({"股票":coid,"相關係數":cor}) 174 | df_cor 175 | 176 | 177 | # In[57]: 178 | 179 | 180 | #Plot 八大行庫各家買賣超金額 181 | import pandas as pd 182 | import matplotlib.pyplot as plt 183 | import matplotlib.dates as mdates 184 | from datetime import datetime 185 | import datetime 186 | #輸入個股代碼 187 | coid = "2308" 188 | #個股股價 189 | market = tejapi.get('TWN/APRCD1', 190 | coid = coid, 191 | mdate = mdate, 192 | paginate=True) 193 | 194 | df = pd.DataFrame({"日期":market["mdate"],"股價":market["close_d"]}) 195 | #--------------------------------------------------------------------------- 196 | #個股券商買賣超 197 | data = tejapi.get('TWN/AMTOP1', 198 | coid = coid, 199 | mdate = mdate, 200 | paginate=True) 201 | 202 | for i in range(0,len(bank)): 203 | 204 | broker = bank[i] 205 | data1 = data[data["key3"] == broker] 206 | 207 | bs_data = data1[["mdate","bs_m"]] 208 | bs_data = bs_data.rename(columns={"mdate": '日期',"bs_m": str(broker)}) 209 | #累積買賣超 210 | df = pd.merge(df,bs_data,left_on="日期",right_on="日期",how="outer") 211 | df[str(broker)] = df[str(broker)].fillna(0) 212 | bs_m_list = list(df[str(broker)]) 213 | agg = [] 214 | n = 0 215 | for j in range(0,len(bs_m_list)): 216 | n = n + bs_m_list[j] #每日淨買賣 217 | agg = agg + [n] # #每日更新 218 | df[str(broker)] = agg 219 | 220 | df["八大淨買賣總和"] = df[bank].sum(axis=1) 221 | df 222 | 223 | 224 | # In[58]: 225 | 226 | 227 | #Plot 228 | #Index設定為日期 229 | df.set_index(pd.to_datetime(df["日期"], format="%Y-%m-%d"), inplace=True) 230 | del(df["日期"]) 231 | 232 | plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei'] 233 | plt.rcParams['axes.unicode_minus'] = False 234 | #畫雙軸圖 235 | fig, ax1 = plt.subplots(figsize=(20, 10)) 236 | for i in range(0,len(bank)): 237 | plt.plot(df.index,df[bank[i]],lw=1.5,label=bank[i]) 238 | plt.plot(df.index,df["八大淨買賣總和"],lw=5,label="八大淨買賣總和") 239 | plt.xlabel("日期",fontsize=20) 240 | plt.ylabel("累積買賣超(元)",fontsize=20) 241 | plt.xticks(fontsize=20) 242 | plt.yticks(fontsize=20) 243 | plt.title(str(coid)+" 國安基金期間八大券商累積買賣超關係圖",fontsize=30) 244 | plt.legend(bbox_to_anchor=(-0.05, 1.0)) 245 | 246 | ax2 = ax1.twinx() 247 | plt.plot(df.index,df["股價"],lw=5,label=str(coid)+"股價") 248 | plt.ylabel("股價(元)",fontsize=20) 249 | plt.yticks(fontsize=20) 250 | plt.legend(bbox_to_anchor=(1, 1.0)) 251 | plt.show() 252 | 253 | -------------------------------------------------------------------------------- /元富 API 下單介紹.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "f5149aa6", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import threading\n", 11 | "from MasterTradePy.api import MasterTradeAPI\n", 12 | "from MasterTradePy.model import *\n", 13 | "from MasterTradePy.constant import PriceType, OrderType, TradingSession, Side, TradingUnit, RCode" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 2, 19 | "id": "ad02eb72", 20 | "metadata": {}, 21 | "outputs": [], 22 | "source": [ 23 | "username = 'your_username'\n", 24 | "password = 'your_password'\n", 25 | "stock_id_list = ['1216', '1582', '2108', '2373', '6277', '9911', '9943']" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 3, 31 | "id": "733b63c2", 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "event = threading.Event()" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 4, 41 | "id": "ff344703", 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "class ConcreteMarketTrader(MarketTrader):\n", 46 | " def OnNewOrderReply(self, data) -> None:\n", 47 | " print(data)\n", 48 | "\n", 49 | " def OnChangeReply(self, data) -> None:\n", 50 | " print(data)\n", 51 | "\n", 52 | " def OnCancelReply(self, data) -> None:\n", 53 | " print(data)\n", 54 | "\n", 55 | " def OnReport(self, data) -> None:\n", 56 | " if type(data) is ReportOrder:\n", 57 | " if data.order.tableName == \"ORD:TwsOrd\":\n", 58 | " print(f'回報資料: 委託書號={data.order.ordNo}, 股票代號={data.order.symbol}, 委託股數={data.orgOrder.qty}, 成交股數={data.order.cumQty}, 訊息={data.lastMessage}, 狀態={data.order.status}')\n", 59 | " elif data.order.tableName == \"RPT:TwsDeal\":\n", 60 | " print(f'回報資料: 委託書號={data.order.ordNo}, 股票代號={data.order.symbol}, 成交價格={data.order.dealPri}, 成交股數={data.order.cumQty}, 剩餘股數={data.order.leavesQty} 訊息={data.lastMessage}, 狀態={data.order.status}')\n", 61 | " elif data.order.tableName == \"RPT:TwsNew\":\n", 62 | " print(f'回報資料: 委託書號={data.order.ordNo}, 股票代號={data.order.symbol}, 委託價格={data.orgOrder.price}, 委託股數={data.orgOrder.qty}, 訊息={data.lastMessage}, 狀態={data.order.status}')\n", 63 | " else:\n", 64 | " print(f'回報資料: 委託書號={data.order.ordNo}, 股票代號={data.order.symbol}, 委託價格={data.orgOrder.price}, 委託股數={data.orgOrder.qty}, 成交股數={data.order.cumQty}, 訊息={data.lastMessage}, 狀態={data.order.status}')\n", 65 | " \n", 66 | " def OnReqResult(self, workID: str, data) -> None:\n", 67 | " pass\n", 68 | "\n", 69 | " def OnSystemEvent(self, data: SystemEvent) -> None:\n", 70 | " print(f'OnSystemEvent{data}')\n", 71 | " \n", 72 | " def OnAnnouncementEvent(self, data)->None:\n", 73 | " print(f'OnAnnouncementEvent:{data}')\n", 74 | " \n", 75 | " def OnError(self, data):\n", 76 | " print(data)\n", 77 | "\n", 78 | "def OnDigitalSSOEvent(aIsOK, aMsg):\n", 79 | " print(f'OnDigitalSSOEvent: {aIsOK} {aMsg}')\n", 80 | "\n", 81 | "def OnTAConnStuEvent(aIsOK):\n", 82 | " print(f'OnTAConnStuEvent: {aIsOK}')\n", 83 | " if aIsOK:\n", 84 | " event.set()\n" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "id": "a3913ab6", 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "def execute_order(api, stock_id_list):\n", 95 | " account = 'your_account'\n", 96 | " price = '' # 空白表示市價下單\n", 97 | " qtr = '1' # 1張請輸入1\n", 98 | " orderType = OrderType.ROD\n", 99 | "\n", 100 | " if not price:\n", 101 | " priceType = PriceType.MKT\n", 102 | " else:\n", 103 | " priceType = PriceType.LMT\n", 104 | "\n", 105 | " for stock_id in stock_id_list:\n", 106 | " symbol = stock_id\n", 107 | " order = Order(tradingSession=TradingSession.NORMAL,\n", 108 | " side=Side.Buy,\n", 109 | " symbol=symbol,\n", 110 | " priceType=priceType,\n", 111 | " price=price,\n", 112 | " tradingUnit=TradingUnit.COMMON, \n", 113 | " qty=qty,\n", 114 | " orderType=orderType,\n", 115 | " tradingAccount=account,\n", 116 | " userDef='')\n", 117 | " rcode = api.NewOrder(order)\n", 118 | " if rcode == RCode.OK:\n", 119 | " print(f'已送出委託: {symbol}')\n", 120 | " else:\n", 121 | " print(f'下單失敗! 股票代號: {symbol},請再次執行程式,依據回報資料修正輸入')" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 6, 127 | "id": "f2f09fa4", 128 | "metadata": {}, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | "連線競賽ID:C121695520VA\n", 135 | "OnAnnouncementEvent:證券交易驗證公告內文 : 證券登入公告\n", 136 | "期貨交易驗證公告內文 : 期貨登入公告\n", 137 | "連線競賽主機!!!\n", 138 | "\n", 139 | "交易主機連線成功,進行雙因子認證\n", 140 | "驗證已通過,可執行 API 交易功能\n", 141 | "回報資料: 委託書號=Y0001, 股票代號=3515, 委託價格=, 委託股數=5000, 訊息=新單 5000 股OK!, 狀態=101)委託已接受(交易所已接受)\n", 142 | "已送出委託: 3515\n", 143 | "已送出委託: 2610\n", 144 | "回報資料: 委託書號=Y0002, 股票代號=2610, 委託價格=, 委託股數=5000, 訊息=新單 5000 股OK!, 狀態=101)委託已接受(交易所已接受)\n", 145 | "已送出委託: 2344\n", 146 | "回報資料: 委託書號=Y0003, 股票代號=2344, 委託價格=, 委託股數=5000, 訊息=新單 5000 股OK!, 狀態=101)委託已接受(交易所已接受)\n", 147 | "已送出委託: 2317\n", 148 | "回報資料: 委託書號=Y0004, 股票代號=2317, 委託價格=, 委託股數=5000, 訊息=新單 5000 股OK!, 狀態=101)委託已接受(交易所已接受)\n", 149 | "已送出委託: 2460\n", 150 | "回報資料: 委託書號=Y0005, 股票代號=2460, 委託價格=, 委託股數=5000, 訊息=新單 5000 股OK!, 狀態=101)委託已接受(交易所已接受)\n" 151 | ] 152 | } 153 | ], 154 | "source": [ 155 | "def main():\n", 156 | " trader = ConcreteMarketTrader()\n", 157 | " api = MasterTradeAPI(trader)\n", 158 | " api.SetConnectionHost('solace140.masterlink.com.tw:55555')\n", 159 | " \n", 160 | " # 登入交易主機\n", 161 | " rc = api.Login(username, password, True, True, True)\n", 162 | " if rc == RCode.OK:\n", 163 | " print('交易主機連線成功,進行雙因子認證')\n", 164 | " \n", 165 | " # 取得帳戶並進行驗證\n", 166 | " accounts = [x[4:] for x in api.accounts]\n", 167 | " rcc = api.CheckAccs(tradingAccounts=accounts)\n", 168 | " if rcc == RCode.OK:\n", 169 | " print('驗證已通過,可執行 API 交易功能')\n", 170 | "\n", 171 | " execute_order(api, stock_id_list)\n", 172 | "\n", 173 | " input(\"Press Enter to finish...\\n\")\n", 174 | "\n", 175 | "main()\n" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "id": "a3234a19", 182 | "metadata": {}, 183 | "outputs": [], 184 | "source": [] 185 | } 186 | ], 187 | "metadata": { 188 | "kernelspec": { 189 | "display_name": "Python 3", 190 | "language": "python", 191 | "name": "python3" 192 | }, 193 | "language_info": { 194 | "codemirror_mode": { 195 | "name": "ipython", 196 | "version": 3 197 | }, 198 | "file_extension": ".py", 199 | "mimetype": "text/x-python", 200 | "name": "python", 201 | "nbconvert_exporter": "python", 202 | "pygments_lexer": "ipython3", 203 | "version": "3.11.8" 204 | } 205 | }, 206 | "nbformat": 4, 207 | "nbformat_minor": 5 208 | } 209 | -------------------------------------------------------------------------------- /Black Scholes Merton Model.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "ad87483c", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# 載入所需套件\n", 11 | "import math \n", 12 | "import tejapi\n", 13 | "import pandas as pd \n", 14 | "import numpy as np \n", 15 | "import matplotlib.pyplot as plt \n", 16 | "from scipy.stats import norm\n", 17 | "plt.style.use('bmh')\n", 18 | "plt.rcParams['font.sans-serif']=['Microsoft YaHei']\n", 19 | "\n", 20 | "# 登入TEJ API\n", 21 | "api_key = 'YOUR_KEY'\n", 22 | "tejapi.ApiConfig.api_key = api_key\n", 23 | "tejapi.ApiConfig.ignoretz = True\n", 24 | "\n", 25 | "gte, lte = '2021-03-16', '2023-04-10'\n", 26 | "# 標的物價格\n", 27 | "stocks = tejapi.get('TWN/APRCD',\n", 28 | " paginate = True,\n", 29 | " coid = 'Y9999',\n", 30 | " mdate = {'gte':gte, 'lte':lte},\n", 31 | " chinese_column_name = True,\n", 32 | " opts = {\n", 33 | " 'columns':[ 'mdate','close_d']\n", 34 | " }\n", 35 | " )\n", 36 | "# 選擇權價格\n", 37 | "options = tejapi.get(\n", 38 | " 'TWN/AOPTION',\n", 39 | " paginate = True,\n", 40 | " coid = 'TXO202304C15500',\n", 41 | " mdate = {'gte':gte, 'lte':lte},\n", 42 | " chinese_column_name = True,\n", 43 | " opts = {\n", 44 | " 'columns':['mdate', 'coid','settle', 'kk', 'theoremp', 'acls', 'ex_price', 'td1y', 'avolt', 'rtime']\n", 45 | " }\n", 46 | ")\n", 47 | "# 重設日期為index\n", 48 | "stocks = stocks.set_index('年月日')\n", 49 | "options = options.set_index('日期')\n", 50 | "\n", 51 | "stocks['日報酬'] = np.log(stocks['收盤價(元)']) - np.log(stocks['收盤價(元)'].shift(1))\n", 52 | "stocks['移動報酬波動度'] = stocks['日報酬'].rolling(252).std()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "id": "3a01f887", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "class BS_formula:\n", 63 | "\n", 64 | " def __init__(self, s0, k, r, sigma, T): \n", 65 | " self.s0 = s0 # 標的物價格\n", 66 | " self.k = k # 履約價格\n", 67 | " self.r = r # 無風險利率\n", 68 | " self.sigma = sigma # 歷史波動度\n", 69 | " self.T = T # 剩餘到期時間\n", 70 | " self.d1 = (np.log(s0/k)+(r+sigma**2/2)*T) / (sigma * np.sqrt(T))\n", 71 | " self.d2 = ((np.log(s0/k)+(r+sigma**2/2)*T) / (sigma * np.sqrt(T))) - sigma*np.sqrt(T)\n", 72 | " \n", 73 | " def BS_price(self): # 計算理論價格\n", 74 | " c = self.s0*norm.cdf(self.d1) - self.k*np.exp(-self.r*self.T)*norm.cdf(self.d2)\n", 75 | " p = self.k*np.exp(-self.r*self.T)*norm.cdf(-self.d2) - self.s0*norm.cdf(-self.d1)\n", 76 | " return c,p\n", 77 | " \n", 78 | " def BS_delta(self): # 計算 delta\n", 79 | " return norm.cdf(self.d1), norm.cdf(self.d1)-1\n", 80 | " \n", 81 | " def BS_gamma(self): # 計算 gamma\n", 82 | " return norm.pdf(self.d1)/(self.s0*self.sigma*np.sqrt(self.T)), norm.pdf(self.d1)/(self.s0*self.sigma*np.sqrt(self.T))\n", 83 | " \n", 84 | " def BS_vega(self): # 計算 vega\n", 85 | " return self.s0*np.sqrt(self.T)*norm.pdf(self.d1), self.s0*np.sqrt(self.T)*norm.pdf(self.d1)\n", 86 | " \n", 87 | " def BS_theta(self): # 計算 theta \n", 88 | " c_theta = -self.s0*norm.pdf(self.d1)*self.sigma / (2*np.sqrt(self.T)) - self.r*self.k*np.exp(-self.r*self.T)*norm.cdf(self.d2)\n", 89 | " p_theta = -self.s0*norm.pdf(self.d1)*self.sigma / (2*np.sqrt(self.T)) + self.r*self.k*np.exp(-self.r*self.T)*norm.cdf(-self.d2)\n", 90 | " return c_theta, p_theta\n", 91 | " \n", 92 | " def BS_rho(self): # 計算 rho \n", 93 | " return self.k*self.T*np.exp(-self.r*self.T)*norm.cdf(self.d2), -self.k*self.T*np.exp(-self.r*self.T)*norm.cdf(-self.d2)" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": null, 99 | "id": "d8e88fc9", 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "s0 = np.linspace(200,800)\n", 104 | "k = 500\n", 105 | "r = 0.00\n", 106 | "sigma = 0.2\n", 107 | "T = 252/252\n", 108 | "\n", 109 | "mybs = BS_formula(s0, k, r, sigma, T)\n", 110 | "c, p = mybs.BS_price()\n", 111 | "\n", 112 | "fig = plt.figure(figsize = (12,8))\n", 113 | "plt.plot(s0, c, label = '買權')\n", 114 | "plt.plot(s0, p, label = '賣權')\n", 115 | "plt.axvline(x = 500, color = 'black', linestyle = '--')\n", 116 | "plt.xlabel('標的物價格', fontsize = 15)\n", 117 | "plt.ylabel('選擇權價格', fontsize = 15)\n", 118 | "plt.title('選擇權價格 VS. 標的物價格', fontsize = 20)\n", 119 | "plt.legend(fontsize = 14)\n", 120 | "plt.savefig('black scholes put call price.png')\n", 121 | "plt.show()" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "id": "312569cf", 128 | "metadata": {}, 129 | "outputs": [], 130 | "source": [ 131 | "s0 = np.linspace(200,800)\n", 132 | "k = 500\n", 133 | "r = 0.00\n", 134 | "sigma = 0.2\n", 135 | "T = 252/252\n", 136 | "\n", 137 | "mybs = BS_formula(s0, k, r, sigma, T)\n", 138 | "c, p = mybs.BS_delta()\n", 139 | "\n", 140 | "fig = plt.figure(figsize = (12,8))\n", 141 | "plt.plot(s0, c, label = '買權')\n", 142 | "plt.plot(s0, p, label = '賣權')\n", 143 | "plt.axvline(x = 500, color = 'black', linestyle = '--')\n", 144 | "plt.axhline(y = 0, color = 'black', linestyle = '--')\n", 145 | "plt.xlabel('標的物價格', fontsize = 15)\n", 146 | "plt.ylabel('Delta值', fontsize = 15)\n", 147 | "plt.title('Delta值 VS. 標的物價格', fontsize = 20)\n", 148 | "plt.legend(fontsize = 14)\n", 149 | "plt.savefig('black scholes put call delta.png')\n", 150 | "plt.show()" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": null, 156 | "id": "78b6d3a6", 157 | "metadata": {}, 158 | "outputs": [], 159 | "source": [ 160 | "s0, s1, s2 = 400, 500, 600 \n", 161 | "k = 500\n", 162 | "r = 0.00\n", 163 | "sigma = 0.2\n", 164 | "T = np.linspace(1, 0.01)\n", 165 | "\n", 166 | "mybs0 = BS_formula(s0, k, r, sigma, T)\n", 167 | "c0, p0 = mybs0.BS_gamma()\n", 168 | "\n", 169 | "mybs1 = BS_formula(s1, k, r, sigma, T)\n", 170 | "c1, p1 = mybs1.BS_gamma()\n", 171 | "\n", 172 | "mybs2 = BS_formula(s2, k, r, sigma, T)\n", 173 | "c2, p2 = mybs2.BS_gamma()\n", 174 | "\n", 175 | "fig = plt.figure(figsize = (12,8))\n", 176 | "plt.plot(T, c0, label = '買權(價外)')\n", 177 | "plt.plot(T, c1, label = '買權(價平)')\n", 178 | "plt.plot(T, c2, label = '買權(價內)')\n", 179 | "plt.xlabel('剩餘時間', fontsize = 15)\n", 180 | "plt.ylabel('Gamma值', fontsize = 15)\n", 181 | "plt.title('Gamma值 VS. 剩餘時間', fontsize = 20)\n", 182 | "plt.legend(fontsize = 14)\n", 183 | "plt.axis([1.005, -0, -0.005, .045])\n", 184 | "plt.savefig('black scholes put call gamma2.png')\n", 185 | "plt.show()" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "id": "1628e153", 192 | "metadata": {}, 193 | "outputs": [], 194 | "source": [ 195 | "r = 0.012\n", 196 | "s0 = stocks.loc['2023-04-10']['收盤價(元)']\n", 197 | "k = 15500\n", 198 | "sigma = stocks.loc['2023-04-10']['移動報酬波動度']*np.sqrt(252)\n", 199 | "T = 6/252\n", 200 | "\n", 201 | "mybs = BS_formula(s0, k, r, sigma, T)\n", 202 | "c, p = mybs.BS_price()\n", 203 | "c_delta, p_delta = mybs.BS_delta()\n", 204 | "c_gamma, p_gamma = mybs.BS_gamma()\n", 205 | "c_vega, p_vega = mybs.BS_vega()\n", 206 | "c_theta, p_theta = mybs.BS_theta()\n", 207 | "c_rho, p_rho = mybs.BS_rho()\n", 208 | "\n", 209 | "print('==2023-04-10履約價為525的台積電買權==')\n", 210 | "print('當前標的物價格為 %.3f, 年化波動度為 %.3f, 剩餘期間為 %.3f'%(s0, sigma, T*252))\n", 211 | "print('買權理論價格: %.4f, 賣權理論價格: %.4f' %(c,p))\n", 212 | "print('買權delta: %.4f, 賣權delta: %.4f' %(c_delta,p_delta))\n", 213 | "print('買權gamma: %.4f, 賣權gamma: %.4f' %(c_gamma,p_gamma))\n", 214 | "print('買權vega: %.4f, 賣權vega: %.4f' %(c_vega,p_vega))\n", 215 | "print('買權theta: %.4f, 賣權theta: %.4f' %(c_theta,p_theta))\n", 216 | "print('買權rho: %.4f, 賣權rho: %.4f' %(c_rho,p_rho))" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": null, 222 | "id": "0b224856", 223 | "metadata": {}, 224 | "outputs": [], 225 | "source": [ 226 | "options.loc['2023-04-10'] # 實際買權價格" 227 | ] 228 | } 229 | ], 230 | "metadata": { 231 | "kernelspec": { 232 | "display_name": "Python 3 (ipykernel)", 233 | "language": "python", 234 | "name": "python3" 235 | }, 236 | "language_info": { 237 | "codemirror_mode": { 238 | "name": "ipython", 239 | "version": 3 240 | }, 241 | "file_extension": ".py", 242 | "mimetype": "text/x-python", 243 | "name": "python", 244 | "nbconvert_exporter": "python", 245 | "pygments_lexer": "ipython3", 246 | "version": "3.11.3" 247 | } 248 | }, 249 | "nbformat": 4, 250 | "nbformat_minor": 5 251 | } 252 | -------------------------------------------------------------------------------- /Survivorship_bias.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "519de3c2", 6 | "metadata": {}, 7 | "source": [ 8 | "套件導入" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "230e8419", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pandas as pd \n", 19 | "import numpy as np \n", 20 | "import tejapi\n" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 2, 26 | "id": "6dfb815e", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "api_key = 'your_api_key'\n", 31 | "tejapi.ApiConfig.api_key = api_key\n", 32 | "tejapi.ApiConfig.ignoretz = True" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "id": "11d0ad14", 38 | "metadata": {}, 39 | "source": [ 40 | "資料庫導入" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 18, 46 | "id": "0fc03dfd", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "comp_data = tejapi.get('TWN/ANPRCSTD',\n", 51 | " paginate = True,\n", 52 | " opts = {\"columns\":[\"coid\", \"mdate\", \"mkt\", \"stype\", \"list_date\", \"delis_date\", \"tseind\"]}\n", 53 | " )" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 22, 59 | "id": "18b2306f", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "coid_lst = list(comp_data.loc[(comp_data[\"stype\"] == \"STOCK\") & (comp_data[\"tseind\"] == \"22\")][\"coid\"])" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 24, 69 | "id": "d0658ecd", 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "241" 76 | ] 77 | }, 78 | "execution_count": 24, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "len(coid_lst)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 70, 90 | "id": "4ac80bc6", 91 | "metadata": { 92 | "scrolled": false 93 | }, 94 | "outputs": [], 95 | "source": [ 96 | "gte, lte = \"2020-01-01\", \"2022-12-31\"\n", 97 | "price_data = tejapi.get('TWN/AAPRCDA',\n", 98 | " paginate = True,\n", 99 | " coid = coid_lst,\n", 100 | " mdate = {\"gte\":gte, \"lte\":lte},\n", 101 | " opts = {\"columns\":[\"coid\", \"mdate\", \"fld014\", \"cls60\", \"close_d\"]}\n", 102 | " )" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": 26, 108 | "id": "5c3aff20", 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "# price_data = pd.read_csv(\"price_data.csv\")" 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "id": "ccc5530a", 118 | "metadata": {}, 119 | "source": [ 120 | "資料前處理" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 71, 126 | "id": "cc1a677c", 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "price_data[\"coid\"] = price_data[\"coid\"].astype(str)" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": 72, 136 | "id": "04e52bb6", 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "inter_coid = list(set(coid_lst).intersection(set(price_data[\"coid\"].unique())))" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 73, 146 | "id": "28b13f9b", 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "data": { 151 | "text/plain": [ 152 | "['8432',\n", 153 | " '6645',\n", 154 | " '1760',\n", 155 | " '4195',\n", 156 | " '6661',\n", 157 | " '1733',\n", 158 | " '8436',\n", 159 | " '4155',\n", 160 | " '6872',\n", 161 | " '6493',\n", 162 | " '4114',\n", 163 | " '1799',\n", 164 | " '1783',\n", 165 | " '4167',\n", 166 | " '4126',\n", 167 | " '6549',\n", 168 | " '6885',\n", 169 | " '4736',\n", 170 | " '6586',\n", 171 | " '6703',\n", 172 | " '4911',\n", 173 | " '3218',\n", 174 | " '6580',\n", 175 | " '6518',\n", 176 | " '7595',\n", 177 | " '6637',\n", 178 | " '4129',\n", 179 | " '4131',\n", 180 | " '5312',\n", 181 | " '4771',\n", 182 | " '6572',\n", 183 | " '6242',\n", 184 | " '4151',\n", 185 | " '6747',\n", 186 | " '6527',\n", 187 | " '6767',\n", 188 | " '6535',\n", 189 | " '4138',\n", 190 | " '6612',\n", 191 | " '1762',\n", 192 | " '3176',\n", 193 | " '1736',\n", 194 | " '6130',\n", 195 | " '6794',\n", 196 | " '4116',\n", 197 | " '8403',\n", 198 | " '7575',\n", 199 | " '6589',\n", 200 | " '1789',\n", 201 | " '6838',\n", 202 | " '1598',\n", 203 | " '4164',\n", 204 | " '4108',\n", 205 | " '1271',\n", 206 | " '4105',\n", 207 | " '6562',\n", 208 | " '6543',\n", 209 | " '6861',\n", 210 | " '6762',\n", 211 | " '6891',\n", 212 | " '4166',\n", 213 | " '6677',\n", 214 | " '6610',\n", 215 | " '4162',\n", 216 | " '4175',\n", 217 | " '6472',\n", 218 | " '6492',\n", 219 | " '6665',\n", 220 | " '6496',\n", 221 | " '4109',\n", 222 | " '6758',\n", 223 | " '6844',\n", 224 | " '6879',\n", 225 | " '1777',\n", 226 | " '6461',\n", 227 | " '6748',\n", 228 | " '6929',\n", 229 | " '4106',\n", 230 | " '6734',\n", 231 | " '6932',\n", 232 | " '4119',\n", 233 | " '3164',\n", 234 | " '6569',\n", 235 | " '7427',\n", 236 | " '4732',\n", 237 | " '4127',\n", 238 | " '4728',\n", 239 | " '6657',\n", 240 | " '1786',\n", 241 | " '4194',\n", 242 | " '6566',\n", 243 | " '6857',\n", 244 | " '4183',\n", 245 | " '4133',\n", 246 | " '7561',\n", 247 | " '4192',\n", 248 | " '4743',\n", 249 | " '6850',\n", 250 | " '1784',\n", 251 | " '6469',\n", 252 | " '4173',\n", 253 | " '4170',\n", 254 | " '6547',\n", 255 | " '4161',\n", 256 | " '6633',\n", 257 | " '4197',\n", 258 | " '4735',\n", 259 | " '6848',\n", 260 | " '3118',\n", 261 | " '1780',\n", 262 | " '4130',\n", 263 | " '1565',\n", 264 | " '6615',\n", 265 | " '6892',\n", 266 | " '4169',\n", 267 | " '6864',\n", 268 | " '4174',\n", 269 | " '6875',\n", 270 | " '6634',\n", 271 | " '4142',\n", 272 | " '4104',\n", 273 | " '6713',\n", 274 | " '4132',\n", 275 | " '1593',\n", 276 | " '6446',\n", 277 | " '4102',\n", 278 | " '4153',\n", 279 | " '6796',\n", 280 | " '4160',\n", 281 | " '6931',\n", 282 | " '4198',\n", 283 | " '1795',\n", 284 | " '4111',\n", 285 | " '6815',\n", 286 | " '6814',\n", 287 | " '6676',\n", 288 | " '4188',\n", 289 | " '4744',\n", 290 | " '1731',\n", 291 | " '1813',\n", 292 | " '4747',\n", 293 | " '6841',\n", 294 | " '4726',\n", 295 | " '4737',\n", 296 | " '6539',\n", 297 | " '8279',\n", 298 | " '6575',\n", 299 | " '3184',\n", 300 | " '4168',\n", 301 | " '6733',\n", 302 | " '4150',\n", 303 | " '6574',\n", 304 | " '4128',\n", 305 | " '6576',\n", 306 | " '4163',\n", 307 | " '6523',\n", 308 | " '6712',\n", 309 | " '4152',\n", 310 | " '7555',\n", 311 | " '4107',\n", 312 | " '4117',\n", 313 | " '3205',\n", 314 | " '6817',\n", 315 | " '1752',\n", 316 | " '6491',\n", 317 | " '6797',\n", 318 | " '4147',\n", 319 | " '6499',\n", 320 | " '6785',\n", 321 | " '4746',\n", 322 | " '6620',\n", 323 | " '3705',\n", 324 | " '6709',\n", 325 | " '4120',\n", 326 | " '1707',\n", 327 | " '6782',\n", 328 | " '8409',\n", 329 | " '6808',\n", 330 | " '1788',\n", 331 | " '6696',\n", 332 | " '6621',\n", 333 | " '4121',\n", 334 | " '4115',\n", 335 | " '6564',\n", 336 | " '6926',\n", 337 | " '1781',\n", 338 | " '1734',\n", 339 | " '1701',\n", 340 | " '4123',\n", 341 | " '6847',\n", 342 | " '4191',\n", 343 | " '6730',\n", 344 | " '1720',\n", 345 | " '6445',\n", 346 | " '6652',\n", 347 | " '4172',\n", 348 | " '6744',\n", 349 | " '6810',\n", 350 | " '6919',\n", 351 | " '6827',\n", 352 | " '6649',\n", 353 | " '6662',\n", 354 | " '4186']" 355 | ] 356 | }, 357 | "execution_count": 73, 358 | "metadata": {}, 359 | "output_type": "execute_result" 360 | } 361 | ], 362 | "source": [ 363 | "inter_coid" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": 186, 369 | "id": "81bc5077", 370 | "metadata": {}, 371 | "outputs": [ 372 | { 373 | "data": { 374 | "text/html": [ 375 | "
\n", 376 | "\n", 389 | "\n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | "
coidmdatefld014cls60close_d
None
012712021-01-1870.3070.300070.3
112712021-01-1969.7069.700069.1
212712021-01-2069.6069.600069.4
312712021-01-2169.1069.100067.6
412712021-01-2269.1269.120069.2
..................
12673984362022-12-26165.75132.6083175.0
12674084362022-12-27167.75133.5083177.5
12674184362022-12-28168.65134.2917171.0
12674284362022-12-29169.90135.0917172.0
12674384362022-12-30171.25135.8083171.0
\n", 499 | "

126744 rows × 5 columns

\n", 500 | "
" 501 | ], 502 | "text/plain": [ 503 | " coid mdate fld014 cls60 close_d\n", 504 | "None \n", 505 | "0 1271 2021-01-18 70.30 70.3000 70.3\n", 506 | "1 1271 2021-01-19 69.70 69.7000 69.1\n", 507 | "2 1271 2021-01-20 69.60 69.6000 69.4\n", 508 | "3 1271 2021-01-21 69.10 69.1000 67.6\n", 509 | "4 1271 2021-01-22 69.12 69.1200 69.2\n", 510 | "... ... ... ... ... ...\n", 511 | "126739 8436 2022-12-26 165.75 132.6083 175.0\n", 512 | "126740 8436 2022-12-27 167.75 133.5083 177.5\n", 513 | "126741 8436 2022-12-28 168.65 134.2917 171.0\n", 514 | "126742 8436 2022-12-29 169.90 135.0917 172.0\n", 515 | "126743 8436 2022-12-30 171.25 135.8083 171.0\n", 516 | "\n", 517 | "[126744 rows x 5 columns]" 518 | ] 519 | }, 520 | "execution_count": 186, 521 | "metadata": {}, 522 | "output_type": "execute_result" 523 | } 524 | ], 525 | "source": [ 526 | "price_data[price_data[\"coid\"].isin(inter_coid)]" 527 | ] 528 | }, 529 | { 530 | "cell_type": "markdown", 531 | "id": "94e6a98b", 532 | "metadata": {}, 533 | "source": [ 534 | "交易策略" 535 | ] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": 209, 540 | "id": "c147f6bf", 541 | "metadata": {}, 542 | "outputs": [], 543 | "source": [ 544 | "fltr_price_data = price_data[price_data[\"coid\"].isin(inter_coid)]\n", 545 | "group = fltr_price_data.groupby(\"coid\")\n" 546 | ] 547 | }, 548 | { 549 | "cell_type": "code", 550 | "execution_count": 210, 551 | "id": "4b7318ff", 552 | "metadata": {}, 553 | "outputs": [], 554 | "source": [ 555 | "def MA_strategy(df, principal):\n", 556 | " position = 0 \n", 557 | " lst = []\n", 558 | " \n", 559 | " for i in range(len(df)):\n", 560 | " if df[\"fld014\"].iloc[i] > df[\"cls60\"].iloc[i] and principal >= float(df[\"close_d\"].iloc[i])*1*1000:\n", 561 | " principal -= float(df[\"close_d\"].iloc[i])*1*1000\n", 562 | " position += 1\n", 563 | " lst.append({\n", 564 | " \"日期\": df[\"mdate\"].iloc[i],\n", 565 | " \"標的\": df[\"coid\"].iloc[i],\n", 566 | " \"買入/賣出\": \"買入\",\n", 567 | " \"單價\": float(df[\"close_d\"].iloc[i]),\n", 568 | " \"單位\": 1,\n", 569 | " \"剩餘現金\": principal,\n", 570 | " \"部位\" : position\n", 571 | " })\n", 572 | "\n", 573 | " elif df[\"fld014\"].iloc[i] < df[\"cls60\"].iloc[i] and position > 0:\n", 574 | " principal += float(df[\"close_d\"].iloc[i])*1*1000\n", 575 | " position -= 1\n", 576 | " \n", 577 | " lst.append({\n", 578 | " \"日期\": df[\"mdate\"].iloc[i],\n", 579 | " \"標的\": df[\"coid\"].iloc[i],\n", 580 | " \"買入/賣出\": \"賣出\",\n", 581 | " \"單價\": float(df[\"close_d\"].iloc[i]),\n", 582 | " \"單位\": 1,\n", 583 | " \"剩餘現金\": principal,\n", 584 | " \"部位\" : position\n", 585 | " })\n", 586 | " \n", 587 | " elif i == len(df)-1 and position > 0:\n", 588 | " principal += float(df[\"close_d\"].iloc[i])*position*1000\n", 589 | " position -= position\n", 590 | " lst.append({\n", 591 | " \"日期\": df[\"mdate\"].iloc[i],\n", 592 | " \"標的\": df[\"coid\"].iloc[i],\n", 593 | " \"買入/賣出\": \"賣出\",\n", 594 | " \"單價\": float(df[\"close_d\"].iloc[i]),\n", 595 | " \"單位\": position,\n", 596 | " \"剩餘現金\": principal,\n", 597 | " \"部位\" : position\n", 598 | " })\n", 599 | " \n", 600 | "\n", 601 | " df_output = pd.DataFrame(lst)\n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " return (df_output, principal)\n", 606 | " \n" 607 | ] 608 | }, 609 | { 610 | "cell_type": "markdown", 611 | "id": "035dff17", 612 | "metadata": {}, 613 | "source": [ 614 | "所有曾經上市櫃公司股價資訊" 615 | ] 616 | }, 617 | { 618 | "cell_type": "code", 619 | "execution_count": 211, 620 | "id": "25a299a1", 621 | "metadata": {}, 622 | "outputs": [], 623 | "source": [ 624 | "principal = 1000000\n", 625 | "total_return_1 = 0\n", 626 | "df = pd.DataFrame(columns = [\"日期\", \"標的\", \"買入/賣出\", \"單價\", \"單位\", \"剩餘現金\", \"部位\"])\n", 627 | "\n", 628 | "for g in group.groups.keys():\n", 629 | " reuslt = MA_strategy(group.get_group(g), principal)\n", 630 | " total_return_1 += round(reuslt[1], 2)\n", 631 | " df = pd.concat([df, reuslt[0]], ignore_index=True)\n", 632 | " " 633 | ] 634 | }, 635 | { 636 | "cell_type": "code", 637 | "execution_count": 212, 638 | "id": "c5b632d9", 639 | "metadata": {}, 640 | "outputs": [ 641 | { 642 | "name": "stdout", 643 | "output_type": "stream", 644 | "text": [ 645 | "-14.269384236453197\n" 646 | ] 647 | } 648 | ], 649 | "source": [ 650 | "total_return = (total_return_1/(1000000*len(group.groups.keys())) - 1) *100\n", 651 | "print(f\"ROI : {total_return}%\")" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": 225, 657 | "id": "db059aec", 658 | "metadata": {}, 659 | "outputs": [ 660 | { 661 | "name": "stdout", 662 | "output_type": "stream", 663 | "text": [ 664 | "2020–01–01 至 2022–12–31狀態曾經為上市櫃的公司數量:203\n" 665 | ] 666 | } 667 | ], 668 | "source": [ 669 | "print(f'2020–01–01 至 2022–12–31狀態曾經為上市櫃的公司數量:{len(list(comp_data.loc[(comp_data[\"coid\"].isin(inter_coid))][\"coid\"]))}')\n" 670 | ] 671 | }, 672 | { 673 | "cell_type": "markdown", 674 | "id": "d03ca560", 675 | "metadata": {}, 676 | "source": [ 677 | "剔除下市櫃公司" 678 | ] 679 | }, 680 | { 681 | "cell_type": "code", 682 | "execution_count": 213, 683 | "id": "736bf729", 684 | "metadata": {}, 685 | "outputs": [], 686 | "source": [ 687 | "without_dist_coid = comp_data.loc[(comp_data[\"coid\"].isin(inter_coid)) & (comp_data[\"mkt\"] != \"DIST\")][\"coid\"].unique()\n", 688 | "fltr_price_data = price_data[price_data[\"coid\"].isin(without_dist_coid)]\n", 689 | "group = fltr_price_data.groupby(\"coid\")" 690 | ] 691 | }, 692 | { 693 | "cell_type": "code", 694 | "execution_count": 214, 695 | "id": "902e9b86", 696 | "metadata": {}, 697 | "outputs": [], 698 | "source": [ 699 | "principal = 1000000\n", 700 | "total_return_2 = 0\n", 701 | "df_without_dist = pd.DataFrame(columns = [\"日期\", \"標的\", \"買入/賣出\", \"單價\", \"單位\", \"剩餘現金\", \"部位\"])\n", 702 | "\n", 703 | "for g in group.groups.keys():\n", 704 | " reuslt = MA_strategy(group.get_group(g), principal)\n", 705 | " total_return_2 += round(reuslt[1], 2)\n", 706 | " df = pd.concat([df_without_dist, reuslt[0]], ignore_index=True)\n", 707 | " \n" 708 | ] 709 | }, 710 | { 711 | "cell_type": "code", 712 | "execution_count": 226, 713 | "id": "9f40cb7d", 714 | "metadata": {}, 715 | "outputs": [ 716 | { 717 | "name": "stdout", 718 | "output_type": "stream", 719 | "text": [ 720 | "ROI : -13.846355670103094%\n" 721 | ] 722 | } 723 | ], 724 | "source": [ 725 | "return_without_dist = (total_return_2/(1000000*len(group.groups.keys())) - 1) *100\n", 726 | "print(f\"ROI : {return_without_dist}%\")" 727 | ] 728 | }, 729 | { 730 | "cell_type": "code", 731 | "execution_count": null, 732 | "id": "cf159e62", 733 | "metadata": {}, 734 | "outputs": [], 735 | "source": [] 736 | } 737 | ], 738 | "metadata": { 739 | "kernelspec": { 740 | "display_name": "Python 3", 741 | "language": "python", 742 | "name": "python3" 743 | }, 744 | "language_info": { 745 | "codemirror_mode": { 746 | "name": "ipython", 747 | "version": 3 748 | }, 749 | "file_extension": ".py", 750 | "mimetype": "text/x-python", 751 | "name": "python", 752 | "nbconvert_exporter": "python", 753 | "pygments_lexer": "ipython3", 754 | "version": "3.8.8" 755 | } 756 | }, 757 | "nbformat": 4, 758 | "nbformat_minor": 5 759 | } 760 | -------------------------------------------------------------------------------- /seekingalpha.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import pandas as pd\n", 10 | "import numpy as np\n", 11 | "import tejapi\n", 12 | "import statsmodels.api as sm\n", 13 | "import matplotlib.pyplot as plt\n", 14 | "import matplotlib.transforms as transforms\n", 15 | "plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'] # 解決MAC電腦 plot中文問題\n", 16 | "plt.rcParams['axes.unicode_minus'] = False\n", 17 | "tejapi.ApiConfig.api_key =\"Your Key\"\n", 18 | "tejapi.ApiConfig.ignoretz = True" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 3, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "data=tejapi.get('TWN/ANPRCSTD' ,chinese_column_name=True )\n", 28 | "select=data[\"上市別\"].unique()\n", 29 | "select=select[1:3]\n", 30 | "condition =(data[\"上市別\"].isin(select)) & ( data[\"證券種類名稱\"]==\"普通股\" )\n", 31 | "data=data[condition]\n", 32 | "twid=data[\"證券碼\"].to_list() #取得上市櫃股票證券碼" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "df = pd.DataFrame()\n", 42 | "for i in twid: #資料筆數超過100萬筆,透過迴圈方式抓取\n", 43 | " df = pd.concat([df, tejapi.get('TWN/APRCD1', #從TEJ api撈取所需要的資料\n", 44 | " chinese_column_name = True,\n", 45 | " paginate = True,\n", 46 | " mdate = {'gt':'2013-12-31', 'lt':'2022-07-01'},\n", 47 | " coid=i,\n", 48 | " opts={'columns':['coid','mdate', 'close_adj' ,'roi' ,'mv', \"pbr_tej\"]})])" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 4, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# df = pd.read_csv('alpha.csv', sep=',', encoding='big5')" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 5, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "# df = df.iloc[:,1:]" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 6, 72 | "metadata": {}, 73 | "outputs": [], 74 | "source": [ 75 | "# df['年月日'] = df['年月日'].map(lambda x: x[:10])" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 7, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "# df['年月日'] = pd.to_datetime(df['年月日'])" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 8, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "df['帳面市值比'] = 1/df['股價淨值比-TEJ']" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 10, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "ME = df.groupby('年月日')['市值(百萬元)'].apply(lambda x: x.median())\n", 103 | "ME.name = '市值_中位數'\n", 104 | "df = df.merge(ME, on='年月日')\n", 105 | "df['市值matrix'] = np.where(df['市值(百萬元)']>df['市值_中位數'], 'B', 'S')" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 13, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "df1 = (df.groupby(['年月日','市值matrix'])['市值(百萬元)'].sum()).reset_index()\n", 115 | "df = df.merge(df1, on=['年月日','市值matrix'])\n", 116 | "df['weight'] = df['市值(百萬元)_x']/df['市值(百萬元)_y']\n", 117 | "df.groupby(['年月日','市值matrix'])['weight'].sum()" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": 16, 123 | "metadata": {}, 124 | "outputs": [ 125 | { 126 | "data": { 127 | "text/plain": [ 128 | "年月日 市值matrix\n", 129 | "2014-01-02 B 1.0\n", 130 | " S 1.0\n", 131 | "2014-01-03 B 1.0\n", 132 | " S 1.0\n", 133 | "2014-01-06 B 1.0\n", 134 | " ... \n", 135 | "2022-07-27 S 1.0\n", 136 | "2022-07-28 B 1.0\n", 137 | " S 1.0\n", 138 | "2022-07-29 B 1.0\n", 139 | " S 1.0\n", 140 | "Name: weight, Length: 4196, dtype: float64" 141 | ] 142 | }, 143 | "execution_count": 16, 144 | "metadata": {}, 145 | "output_type": "execute_result" 146 | } 147 | ], 148 | "source": [ 149 | "df.groupby(['年月日','市值matrix'])['weight'].sum()" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 37, 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [ 158 | "df['return1'] = df['報酬率%']* df['weight']\n", 159 | "SMB = df.groupby(['年月日','市值matrix'])['return1'].sum()\n", 160 | "SMB.reset_index(inplace=True)\n", 161 | "SMB.set_index('年月日',drop=True, inplace=True)\n", 162 | "SMB = SMB[SMB['市值matrix']=='S']['return1'] - SMB[SMB['市值matrix']=='B']['return1']\n", 163 | "SMB.name = 'SMB'\n", 164 | "SMB" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 42, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "data": { 174 | "text/plain": [ 175 | "年月日\n", 176 | "2014-01-02 0.727428\n", 177 | "2014-01-03 1.214870\n", 178 | "2014-01-06 0.623517\n", 179 | "2014-01-07 0.642468\n", 180 | "2014-01-08 0.241418\n", 181 | " ... \n", 182 | "2022-07-25 0.322174\n", 183 | "2022-07-26 0.053480\n", 184 | "2022-07-27 -0.290234\n", 185 | "2022-07-28 -0.106124\n", 186 | "2022-07-29 0.065884\n", 187 | "Name: SMB, Length: 2098, dtype: float64" 188 | ] 189 | }, 190 | "execution_count": 42, 191 | "metadata": {}, 192 | "output_type": "execute_result" 193 | } 194 | ], 195 | "source": [ 196 | "SMB" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 24, 202 | "metadata": {}, 203 | "outputs": [], 204 | "source": [ 205 | "a = df.groupby('年月日')['帳面市值比'].quantile(0.7)\n", 206 | "a.name = 'BM_0.7'\n", 207 | "b = df.groupby('年月日')['帳面市值比'].quantile(0.3)\n", 208 | "b.name = 'BM_0.3'\n", 209 | "df = df.merge(a, on='年月日')\n", 210 | "df = df.merge(b, on='年月日')\n", 211 | "df['BM_matrix'] = np.where(df['帳面市值比']>df['BM_0.7'], 'V', (np.where(df['帳面市值比']\n", 282 | "\n", 295 | "\n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | "
SMBHML
年月日
2014-01-020.7274280.423522
2014-01-031.2148700.678727
2014-01-060.6235170.075185
2014-01-070.6424680.697764
2014-01-080.2414180.260657
.........
2022-07-250.3221740.767774
2022-07-260.0534800.787060
2022-07-27-0.290234-1.005587
2022-07-28-0.1061240.418247
2022-07-290.065884-0.549442
\n", 366 | "

2098 rows × 2 columns

\n", 367 | "" 368 | ], 369 | "text/plain": [ 370 | " SMB HML\n", 371 | "年月日 \n", 372 | "2014-01-02 0.727428 0.423522\n", 373 | "2014-01-03 1.214870 0.678727\n", 374 | "2014-01-06 0.623517 0.075185\n", 375 | "2014-01-07 0.642468 0.697764\n", 376 | "2014-01-08 0.241418 0.260657\n", 377 | "... ... ...\n", 378 | "2022-07-25 0.322174 0.767774\n", 379 | "2022-07-26 0.053480 0.787060\n", 380 | "2022-07-27 -0.290234 -1.005587\n", 381 | "2022-07-28 -0.106124 0.418247\n", 382 | "2022-07-29 0.065884 -0.549442\n", 383 | "\n", 384 | "[2098 rows x 2 columns]" 385 | ] 386 | }, 387 | "execution_count": 535, 388 | "metadata": {}, 389 | "output_type": "execute_result" 390 | } 391 | ], 392 | "source": [ 393 | "fama = pd.concat([SMB,HML], axis=1)\n", 394 | "fama" 395 | ] 396 | }, 397 | { 398 | "cell_type": "code", 399 | "execution_count": 79, 400 | "metadata": {}, 401 | "outputs": [], 402 | "source": [ 403 | "Y9999 = tejapi.get('TWN/APRCD1', #從TEJ api撈取所需要的資料\n", 404 | " chinese_column_name = True,\n", 405 | " paginate = True,\n", 406 | " mdate = {'gt':'2013-12-31', 'lt':'2022-07-01'},\n", 407 | " coid='Y9999',\n", 408 | " opts={'columns':['coid','mdate', 'roi']})" 409 | ] 410 | }, 411 | { 412 | "cell_type": "code", 413 | "execution_count": 81, 414 | "metadata": {}, 415 | "outputs": [], 416 | "source": [ 417 | "fama = fama.merge(Y9999[['年月日','報酬率%']], on='年月日')\n", 418 | "fama.rename(columns = {'報酬率%':'rm'}, inplace=True)\n", 419 | "fama.set_index('年月日',drop=True,inplace=True)\n", 420 | "fama" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": 157, 426 | "metadata": {}, 427 | "outputs": [], 428 | "source": [ 429 | "fama = fama.loc[:'2022-06-30']" 430 | ] 431 | }, 432 | { 433 | "cell_type": "code", 434 | "execution_count": 161, 435 | "metadata": {}, 436 | "outputs": [ 437 | { 438 | "data": { 439 | "text/html": [ 440 | "
\n", 441 | "\n", 454 | "\n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | "
SMBHMLrm
年月日
2014-01-020.7274280.4235220.0120
2014-01-031.2148700.678727-0.7663
2014-01-060.6235170.075185-0.5444
2014-01-070.6424680.6977640.1446
2014-01-080.2414180.2606570.5135
............
2022-06-240.0674930.7379710.8360
2022-06-270.029549-0.9918831.5989
2022-06-28-0.0215010.649327-0.6952
2022-06-290.699726-0.251527-1.2940
2022-06-300.2833220.301092-2.7191
\n", 538 | "

2077 rows × 3 columns

\n", 539 | "
" 540 | ], 541 | "text/plain": [ 542 | " SMB HML rm\n", 543 | "年月日 \n", 544 | "2014-01-02 0.727428 0.423522 0.0120\n", 545 | "2014-01-03 1.214870 0.678727 -0.7663\n", 546 | "2014-01-06 0.623517 0.075185 -0.5444\n", 547 | "2014-01-07 0.642468 0.697764 0.1446\n", 548 | "2014-01-08 0.241418 0.260657 0.5135\n", 549 | "... ... ... ...\n", 550 | "2022-06-24 0.067493 0.737971 0.8360\n", 551 | "2022-06-27 0.029549 -0.991883 1.5989\n", 552 | "2022-06-28 -0.021501 0.649327 -0.6952\n", 553 | "2022-06-29 0.699726 -0.251527 -1.2940\n", 554 | "2022-06-30 0.283322 0.301092 -2.7191\n", 555 | "\n", 556 | "[2077 rows x 3 columns]" 557 | ] 558 | }, 559 | "execution_count": 161, 560 | "metadata": {}, 561 | "output_type": "execute_result" 562 | } 563 | ], 564 | "source": [ 565 | "fama" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": 160, 571 | "metadata": {}, 572 | "outputs": [ 573 | { 574 | "data": { 575 | "text/html": [ 576 | "
\n", 577 | "\n", 590 | "\n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | " \n", 639 | " \n", 640 | " \n", 641 | " \n", 642 | " \n", 643 | " \n", 644 | " \n", 645 | " \n", 646 | " \n", 647 | " \n", 648 | " \n", 649 | " \n", 650 | " \n", 651 | " \n", 652 | " \n", 653 | " \n", 654 | " \n", 655 | " \n", 656 | " \n", 657 | " \n", 658 | " \n", 659 | " \n", 660 | "
證券代碼報酬率%
年月日
2014-01-021101-1.8378
2014-01-021102-1.2953
2014-01-0211040.1770
2014-01-0211101.7143
2014-01-0212030.0000
.........
2022-06-3084409.9836
2022-06-308446-0.2710
2022-06-308928-6.1002
2022-06-3099283.0488
2022-06-309950-9.1912
\n", 661 | "

3113725 rows × 2 columns

\n", 662 | "
" 663 | ], 664 | "text/plain": [ 665 | " 證券代碼 報酬率%\n", 666 | "年月日 \n", 667 | "2014-01-02 1101 -1.8378\n", 668 | "2014-01-02 1102 -1.2953\n", 669 | "2014-01-02 1104 0.1770\n", 670 | "2014-01-02 1110 1.7143\n", 671 | "2014-01-02 1203 0.0000\n", 672 | "... ... ...\n", 673 | "2022-06-30 8440 9.9836\n", 674 | "2022-06-30 8446 -0.2710\n", 675 | "2022-06-30 8928 -6.1002\n", 676 | "2022-06-30 9928 3.0488\n", 677 | "2022-06-30 9950 -9.1912\n", 678 | "\n", 679 | "[3113725 rows x 2 columns]" 680 | ] 681 | }, 682 | "execution_count": 160, 683 | "metadata": {}, 684 | "output_type": "execute_result" 685 | } 686 | ], 687 | "source": [ 688 | "stock = df[['證券代碼', '年月日','報酬率%']]\n", 689 | "stock.set_index('年月日', drop=True, inplace=True)\n", 690 | "stock = stock.loc[:'2022-06-30']\n", 691 | "stock" 692 | ] 693 | }, 694 | { 695 | "cell_type": "code", 696 | "execution_count": 220, 697 | "metadata": {}, 698 | "outputs": [], 699 | "source": [ 700 | "m = pd.date_range('2013-12-31', '2022-07-31', freq='6M').to_list()\n", 701 | "X = sm.add_constant(fama)\n", 702 | "stock_list = stock['證券代碼'].unique()\n" 703 | ] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "execution_count": 302, 708 | "metadata": {}, 709 | "outputs": [], 710 | "source": [ 711 | "b = pd.DataFrame()\n", 712 | "for j in stock_list:\n", 713 | " a=[]\n", 714 | " for i in range(len(m)-1):\n", 715 | " try:\n", 716 | " Y = (stock[stock['證券代碼']== j]).loc[m[i]:m[i+1]]\n", 717 | " result = sm.OLS(Y['報酬率%'], X.loc[m[i]:m[i+1]]).fit()\n", 718 | " a.append(result.params[0])\n", 719 | " except:\n", 720 | " pass\n", 721 | " j = str(j)\n", 722 | " c = pd.DataFrame({'證券代碼':([j]*len(a)), 'alpha':a}, index=m[1:len(a)+1])\n", 723 | " b = pd.concat([b,c])\n", 724 | "b.index.name = '年月日'" 725 | ] 726 | }, 727 | { 728 | "cell_type": "code", 729 | "execution_count": 323, 730 | "metadata": {}, 731 | "outputs": [], 732 | "source": [ 733 | "alpha1 = b.groupby('年月日')['alpha'].apply(lambda x : x.quantile(0.8))\n", 734 | "alpha1.name = 'alpha0.8'\n", 735 | "alpha2 = b.groupby('年月日')['alpha'].apply(lambda x : x.quantile(0.2))\n", 736 | "alpha2.name = 'alpha0.2'\n", 737 | "b = b.merge(alpha1, on='年月日')\n", 738 | "b = b.merge(alpha2, on='年月日')\n", 739 | "long = (b.where(b['alpha'] > b['alpha0.8'])).dropna()\n", 740 | "short = (b.where(b['alpha'] < b['alpha0.2'])).dropna()" 741 | ] 742 | }, 743 | { 744 | "cell_type": "code", 745 | "execution_count": 532, 746 | "metadata": {}, 747 | "outputs": [ 748 | { 749 | "data": { 750 | "text/html": [ 751 | "
\n", 752 | "\n", 765 | "\n", 766 | " \n", 767 | " \n", 768 | " \n", 769 | " \n", 770 | " \n", 771 | " \n", 772 | " \n", 773 | " \n", 774 | " \n", 775 | " \n", 776 | " \n", 777 | " \n", 778 | " \n", 779 | " \n", 780 | " \n", 781 | " \n", 782 | " \n", 783 | " \n", 784 | " \n", 785 | " \n", 786 | " \n", 787 | " \n", 788 | " \n", 789 | " \n", 790 | " \n", 791 | " \n", 792 | " \n", 793 | " \n", 794 | " \n", 795 | " \n", 796 | " \n", 797 | " \n", 798 | " \n", 799 | " \n", 800 | " \n", 801 | " \n", 802 | " \n", 803 | " \n", 804 | " \n", 805 | " \n", 806 | " \n", 807 | " \n", 808 | " \n", 809 | " \n", 810 | " \n", 811 | " \n", 812 | " \n", 813 | " \n", 814 | " \n", 815 | " \n", 816 | " \n", 817 | " \n", 818 | " \n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | " \n", 858 | " \n", 859 | " \n", 860 | " \n", 861 | "
證券代碼alphaalpha0.2alpha0.8
年月日
2014-06-3012100.216635-0.1422950.141690
2014-06-3015270.168521-0.1422950.141690
2014-06-3015820.237503-0.1422950.141690
2014-06-3015830.585237-0.1422950.141690
2014-06-3017110.192855-0.1422950.141690
...............
2022-06-3084090.490293-0.0876330.134834
2022-06-3084330.220098-0.0876330.134834
2022-06-3089280.279140-0.0876330.134834
2022-06-3089410.141910-0.0876330.134834
2022-06-3099500.295723-0.0876330.134834
\n", 862 | "

5067 rows × 4 columns

\n", 863 | "
" 864 | ], 865 | "text/plain": [ 866 | " 證券代碼 alpha alpha0.2 alpha0.8\n", 867 | "年月日 \n", 868 | "2014-06-30 1210 0.216635 -0.142295 0.141690\n", 869 | "2014-06-30 1527 0.168521 -0.142295 0.141690\n", 870 | "2014-06-30 1582 0.237503 -0.142295 0.141690\n", 871 | "2014-06-30 1583 0.585237 -0.142295 0.141690\n", 872 | "2014-06-30 1711 0.192855 -0.142295 0.141690\n", 873 | "... ... ... ... ...\n", 874 | "2022-06-30 8409 0.490293 -0.087633 0.134834\n", 875 | "2022-06-30 8433 0.220098 -0.087633 0.134834\n", 876 | "2022-06-30 8928 0.279140 -0.087633 0.134834\n", 877 | "2022-06-30 8941 0.141910 -0.087633 0.134834\n", 878 | "2022-06-30 9950 0.295723 -0.087633 0.134834\n", 879 | "\n", 880 | "[5067 rows x 4 columns]" 881 | ] 882 | }, 883 | "execution_count": 532, 884 | "metadata": {}, 885 | "output_type": "execute_result" 886 | } 887 | ], 888 | "source": [ 889 | "long" 890 | ] 891 | }, 892 | { 893 | "cell_type": "code", 894 | "execution_count": 359, 895 | "metadata": {}, 896 | "outputs": [], 897 | "source": [ 898 | "stock1 = df[['證券代碼','年月日','收盤價(元)']]\n", 899 | "stock1.set_index('年月日',drop=True, inplace=True)\n", 900 | "stock1 = stock1.loc[:\"2022-06-30\"]\n", 901 | "stock1['證券代碼'] = stock1['證券代碼'].astype('str')" 902 | ] 903 | }, 904 | { 905 | "cell_type": "code", 906 | "execution_count": 468, 907 | "metadata": {}, 908 | "outputs": [], 909 | "source": [ 910 | "ret = []\n", 911 | "for i in range(1, len(m)-1):\n", 912 | " qq = (stock1.loc[m[i]:m[i+1]])['證券代碼'].isin((long.loc[m[i]])['證券代碼'].tolist())\n", 913 | " a = ((stock1.loc[m[i]:m[i+1]])[qq]).groupby('證券代碼')['收盤價(元)'].tail(1).sum()\n", 914 | " b = ((stock1.loc[m[i]:m[i+1]])[qq]).groupby('證券代碼')['收盤價(元)'].head(1).sum()\n", 915 | " c = len((long.loc[m[i]])['證券代碼'].tolist())\n", 916 | " long_ret = ((a/b)-1)/c\n", 917 | " qq1 = (stock1.loc[m[i]:m[i+1]])['證券代碼'].isin((short.loc[m[i]])['證券代碼'].tolist())\n", 918 | " a1 = ((stock1.loc[m[i]:m[i+1]])[qq1]).groupby('證券代碼')['收盤價(元)'].tail(1).sum()\n", 919 | " b1 = ((stock1.loc[m[i]:m[i+1]])[qq1]).groupby('證券代碼')['收盤價(元)'].head(1).sum()\n", 920 | " c1 = len((short.loc[m[i]])['證券代碼'].tolist())\n", 921 | " short_ret = ((a1/b1)-1)/c1\n", 922 | " ret.append(long_ret - short_ret)" 923 | ] 924 | }, 925 | { 926 | "cell_type": "code", 927 | "execution_count": 524, 928 | "metadata": {}, 929 | "outputs": [], 930 | "source": [ 931 | "ret = pd.DataFrame({'ret':ret}, index=m[2:])" 932 | ] 933 | }, 934 | { 935 | "cell_type": "code", 936 | "execution_count": 479, 937 | "metadata": {}, 938 | "outputs": [], 939 | "source": [ 940 | "y9999 = tejapi.get('TWN/APRCD1', #從TEJ api撈取所需要的資料\n", 941 | " chinese_column_name = True,\n", 942 | " paginate = True,\n", 943 | " mdate = {'gt':'2013-12-31', 'lt':'2022-07-01'},\n", 944 | " coid='Y9999',\n", 945 | " opts={'columns':['coid','mdate', 'close_adj']})\n", 946 | "\n", 947 | "y9999.set_index('年月日' ,drop=True, inplace=True)\n", 948 | "\n", 949 | "a = []\n", 950 | "for i in range(1 , len(m)-1):\n", 951 | " b = (((y9999.loc[m[i]:m[i+1]]).tail(1)['收盤價(元)'].values / (y9999.loc[m[i]:m[i+1]]).head(1)['收盤價(元)'].values) -1)[0]\n", 952 | " a.append(b)\n", 953 | "\n", 954 | "ret['大盤'] = a\n", 955 | "ret[['ret', '大盤']].apply(lambda x :x*100)" 956 | ] 957 | }, 958 | { 959 | "cell_type": "code", 960 | "execution_count": null, 961 | "metadata": {}, 962 | "outputs": [], 963 | "source": [] 964 | } 965 | ], 966 | "metadata": { 967 | "kernelspec": { 968 | "display_name": "base", 969 | "language": "python", 970 | "name": "python3" 971 | }, 972 | "language_info": { 973 | "codemirror_mode": { 974 | "name": "ipython", 975 | "version": 3 976 | }, 977 | "file_extension": ".py", 978 | "mimetype": "text/x-python", 979 | "name": "python", 980 | "nbconvert_exporter": "python", 981 | "pygments_lexer": "ipython3", 982 | "version": "3.9.12 (main, Apr 4 2022, 05:22:27) [MSC v.1916 64 bit (AMD64)]" 983 | }, 984 | "orig_nbformat": 4, 985 | "vscode": { 986 | "interpreter": { 987 | "hash": "3e06028060a7864164bfee2227bae8dfd39c60041c455d9e6b5a8dd3aec9b09f" 988 | } 989 | } 990 | }, 991 | "nbformat": 4, 992 | "nbformat_minor": 2 993 | } 994 | -------------------------------------------------------------------------------- /CRR model.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "ed4e73de", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# Load required package\n", 11 | "import math \n", 12 | "import tejapi\n", 13 | "import pandas as pd \n", 14 | "import numpy as np \n", 15 | "import matplotlib.pyplot as plt \n", 16 | "from scipy.stats import norm\n", 17 | "plt.style.use('ggplot')\n", 18 | "\n", 19 | "# log in TEJ API\n", 20 | "api_key = 'YOUR_KEY'\n", 21 | "tejapi.ApiConfig.api_key = api_key\n", 22 | "tejapi.ApiConfig.ignoretz = True\n", 23 | "\n", 24 | "# set time zone\n", 25 | "gte, lte = '2021-03-16', '2023-04-20'\n", 26 | "\n", 27 | "# Get stock price\n", 28 | "stocks = tejapi.get('TWN/APRCD',\n", 29 | " paginate = True,\n", 30 | " coid = 'Y9999',\n", 31 | " mdate = {'gte':gte, 'lte':lte},\n", 32 | " opts = {\n", 33 | " 'columns':[ 'mdate','close_d']\n", 34 | " }\n", 35 | " )\n", 36 | "\n", 37 | "# Get options price\n", 38 | "puts = tejapi.get(\n", 39 | " 'TWN/AOPTION',\n", 40 | " paginate = True,\n", 41 | " coid = 'TXO202304P15500',\n", 42 | " mdate = {'gte':gte, 'lte':lte},\n", 43 | " opts = {\n", 44 | " 'columns':['mdate', 'coid','settle', 'kk', 'theoremp', 'acls', 'ex_price', 'td1y', 'avolt', 'rtime']\n", 45 | " }\n", 46 | ")\n", 47 | "calls = tejapi.get(\n", 48 | " 'TWN/AOPTION',\n", 49 | " paginate = True,\n", 50 | " coid = 'TXO202304C15500',\n", 51 | " mdate = {'gte':gte, 'lte':lte},\n", 52 | " opts = {\n", 53 | " 'columns':['mdate', 'coid','settle', 'kk', 'theoremp', 'acls', 'ex_price', 'td1y', 'avolt', 'rtime']\n", 54 | " }\n", 55 | ")\n", 56 | "\n", 57 | "# Calculate stock return and moving volatility\n", 58 | "stocks['daily return'] = np.log(stocks['close_d']) - np.log(stocks['close_d'].shift(1))\n", 59 | "stocks['moving volatility'] = stocks['daily return'].rolling(252).std()\n", 60 | "stocks = stocks.set_index('mdate')\n", 61 | "puts = puts.set_index('mdate')\n", 62 | "calls = calls.set_index('mdate')" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 2, 68 | "id": "14b2ff3b", 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [ 72 | "class crr_model:\n", 73 | " \n", 74 | " # init fuction\n", 75 | " def __init__(self, s, x, r, t, sigma, N, sigma_daily = True):\n", 76 | " \n", 77 | " t /= 252 \n", 78 | " dt = t/N \n", 79 | " if sigma_daily:\n", 80 | " sigma *= np.sqrt(252)\n", 81 | " u = np.exp(sigma * math.sqrt(dt))\n", 82 | " d = 1/u\n", 83 | " p = (np.exp(r*dt)-d) / (u-d)\n", 84 | " \n", 85 | " self.s = s\n", 86 | " self.x = x\n", 87 | " self.r = r\n", 88 | " self.t = t\n", 89 | " self.N = N \n", 90 | " self.dt = dt\n", 91 | " self.u = u\n", 92 | " self.d = d\n", 93 | " self.p = p\n", 94 | " self.sigma = sigma\n", 95 | " \n", 96 | " # european call price\n", 97 | " def eu_call_price(self):\n", 98 | " \n", 99 | " lattice = np.zeros((self.N+1, self.N+1))\n", 100 | " for j in range(self.N+1):\n", 101 | " lattice[self.N, j] = max(0, self.s*(self.u**j)*(self.d**(self.N-j)) - self.x)\n", 102 | " for i in range(self.N-1, -1, -1):\n", 103 | " for j in range(i+1):\n", 104 | " lattice[i, j] = np.exp(-self.r*self.dt)*(self.p*lattice[i+1,j+1] + (1-self.p) * lattice[i+1, j])\n", 105 | " \n", 106 | " return lattice[0,0], lattice\n", 107 | " \n", 108 | " # european put price\n", 109 | " def eu_put_price(self):\n", 110 | " \n", 111 | " lattice = np.zeros((self.N+1, self.N+1))\n", 112 | " for j in range(self.N+1):\n", 113 | " lattice[self.N, j] = max(0, self.x - self.s*(self.u**j)*(self.d**(self.N-j)))\n", 114 | " for i in range(self.N-1, -1, -1):\n", 115 | " for j in range(i+1):\n", 116 | " lattice[i, j] = np.exp(-self.r*self.dt)*(self.p*lattice[i+1,j+1] + (1-self.p) * lattice[i+1, j])\n", 117 | " \n", 118 | " return lattice[0,0], lattice\n", 119 | " \n", 120 | " # american call price\n", 121 | " def am_call_price(self):\n", 122 | " \n", 123 | " lattice = np.zeros((self.N+1, self.N+1))\n", 124 | " for j in range(self.N+1):\n", 125 | " lattice[self.N, j] = max(0, self.s*(self.u**j)*(self.d**(self.N-j)) - self.x)\n", 126 | " for i in range(self.N-1, -1, -1):\n", 127 | " for j in range(i+1):\n", 128 | " lattice[i, j] = max(np.exp(-self.r*self.dt)*(self.p*lattice[i+1,j+1] + (1-self.p) * lattice[i+1, j]),\n", 129 | " self.s*(self.u**j)*(self.d**(i-j)) - self.x )\n", 130 | " \n", 131 | " return lattice[0,0], lattice \n", 132 | " \n", 133 | " # american put price\n", 134 | " def am_put_price(self):\n", 135 | "\n", 136 | " lattice = np.zeros((self.N+1, self.N+1))\n", 137 | " for j in range(self.N+1):\n", 138 | " lattice[self.N, j] = max(0, self.x - self.s*(self.u**j)*(self.d**(self.N-j)))\n", 139 | " for i in range(self.N-1, -1, -1):\n", 140 | " for j in range(i+1):\n", 141 | " lattice[i, j] = max(\n", 142 | " np.exp(-self.r*self.dt)*(self.p*lattice[i+1,j+1] + (1-self.p) * lattice[i+1, j]), \n", 143 | " self.x - self.s*(self.u**j)*(self.d**(i-j))\n", 144 | " )\n", 145 | " \n", 146 | " return lattice[0,0], lattice " 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 3, 152 | "id": "e1c0a147", 153 | "metadata": {}, 154 | "outputs": [ 155 | { 156 | "data": { 157 | "text/plain": [ 158 | "array([[14.35480056, 0. , 0. , 0. , 0. ],\n", 159 | " [ 5.68258642, 24.43047591, 0. , 0. , 0. ],\n", 160 | " [ 1.06985574, 11.04181488, 39.98588076, 0. , 0. ],\n", 161 | " [ 0. , 2.31285077, 21.18342427, 61.83121855, 0. ],\n", 162 | " [ 0. , 0. , 5. , 39.98588076, 87.21188004]])" 163 | ] 164 | }, 165 | "execution_count": 3, 166 | "metadata": {}, 167 | "output_type": "execute_result" 168 | } 169 | ], 170 | "source": [ 171 | "s = 100\n", 172 | "x = 95\n", 173 | "r = 0\n", 174 | "t = 252\n", 175 | "sigma = 0.3\n", 176 | "N = 4\n", 177 | "\n", 178 | "crr = crr_model(s, x, r, t, sigma, N, sigma_daily = False)\n", 179 | "call, call_lat = crr.eu_call_price()\n", 180 | "call_lat" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 4, 186 | "id": "785bc6e8", 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "data": { 191 | "image/png": "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7vurjUdOTg727t0LPz8/NGzY8Lr617p1awDA999/X+62v/7663U957U+r/yeO04ZAcDx48dx7tw5JCYmuswIlZe/vz/69++PCxcuYOPGjVi+fDmMRqNTdkjuf1ZWVpk/69dCfo3yz7mtvLw87N27V7UPQMW8H65cy/skGzVqFCRJwoIFC/Dpp5/CZDIxO1SVebJgiaiymDJligAg6tSpIw4cOOB0fs2aNcLf319otVq7JfdClG+VmWOx88SJE52W79tSK6r+/PPPBQDRqlUru1Vg+fn5olWrVgKAWLZsmd19YF3arcaxsLuoqEhs3brVqV1JSYlo3ry5ACAOHjyo+li2yrPKzLEA19U2A7KrrTJbvny5031sVxGVlJSIunXrCn9/f5eF09u2bVNdXefIdpWZ2s+K7fP+9ttvAoBISEiw22rAaDSKBx54QAAQr732mt394+PjRXx8vOpzy2O7efNmp3Nbt25Vtl9o0aKF0Ol04tKlS07t5AL8Nm3aiPPnzzudz8vLE9u3by93n3JycpStC8q7yuzQoUNCr9eL5ORkceTIEafHLC4uFr/88ovdsbJ+RtR+PmxXmW3ZssXpPrbvk6177rlH6HQ6UaNGDREWFma30o+qFtYQUZU0ffp05OfnY9asWWjWrBnuu+8+NG7cGAaDAdu2bcPOnTvh7++PL774wuUu1ffffz/69OmDPn36ICkpCXv37sX333+PiIgIfPDBB3Zt7777brz99tsYOXIk+vbti+DgYISFhWHMmDEu+zh48GCsW7cOKSkpaNy4MXr37g1JkrB27VqcOnUKAwYMwJAhQ9weg8LCQrRv3x5JSUlo2bIl4uPjUVRUhA0bNuDQoUPo1avXNWV1unXrhnbt2qF///6IiYnB1q1bsXXrViQkJODNN990u58yHx8frFy5Evfeey8GDx6MBQsWoHXr1igqKsKhQ4ewadMmGI1GAIBer8fq1atx3333oUePHmjbti2aN2+OgIAAnD17Frt27cLJkydx8eJFBAQElPm8jRo1wgcffICnnnoKLVq0wAMPPIDk5GRcvnwZu3btQkhICDZv3gwAaNu2LSZNmoS33noLt9xyC/r164fAwEB8//332L9/P9q3b4+JEyde91gAlmncpKQkrFy5EgaDAffffz+ioqKc2t19991488038cILLyA5ORndu3dHYmIi8vLy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d7rVzwrHK94TERF5ldsBUUpKCtatW+c0haTT6dCrV69y1xnZ6tGjB6ZMmYLVq1ejbdu2OH78ODZt2oQnnnhCabN8+XJkZmZizJgxACzB0Pz58zFs2DAkJycjOzsbAODj44OAgAAAwJIlS3DbbbchMjISWVlZSElJgUajQfv27d189RXMmiHiKjMiIiLvcCsgWrVqFb766iu0aNECXbt2RWxsLABLNueHH37A6tWrodVq0a9fv2t63KSkJEyYMAHLly/HV199haioKAwdOtQuk5OVlYWMjAzl9saNG2EymfDpp5/i008/VY537NgRTz/9NADLZo9z587FlStXEBISggYNGmDGjBkICQlx5+VXOMEMERERkVe5FRBt2LABLVu2xKRJk+yOR0VFoXnz5njzzTexYcOGaw6IAKBly5Zo2bKly/NykCObPn36VR9z/Pjx19wPj5KveM9rmREREXmFW9s1FxQU2F0aw9Gtt96KwsJCd/tU9VgDIsls9nJHiIiIqia3AqIGDRrg2LFjLs8fO3YM9evXd7tTVY1ghoiIiMir3AqIRo4ciaNHj+Kzzz5DamoqzGYzzGYzUlNT8dlnn+HYsWMYOXJkRff15sUaIiIiIq9yq4ZowoQJEELg+++/x/fff69cKNVsnfLR6/WYOHGi0/0WL158HV29iXGVGRERkVe5FRDdcccdvJ5LBeIqMyIiIu9yKyByXOlF14kZIiIiIq9yq4aIKhYzRERERN7FgKgy4CozIiIir2JAVBlwHyIiIiKvYkBUCXAfIiIiIu9iQFQZsIaIiIjIqxgQVQZcZUZERORV5Vp2b3t1+WsRGRnp1v2qGq4yIyIi8q5yBUTu7ju0YsUKt+5X5VgzRAyIiIiIvKNcAdGoUaNudD+qNmuGiFNmRERE3lGugKhTp043uBtVG1eZEREReReLqisDOSDiPkREREReUa4M0apVq9x68H79+rl1vypH3piRGSIiIiKvKFdAtHLlSrcenAFR+XCVGRERkXeVKyDiarEbjPsQEREReRVriCoBZoiIiIi8iwFRZcB9iIiIiLyqXFNmav755x98//33OHXqFAoKCiCEsDsvSRLef//96+5glcB9iIiIiLzKrQzRgQMHMHnyZPzxxx8IDw9HWloaatSogfDwcKSnp8PPzw8NGzas6L7etLgPERERkXe5lSFKSUlBVFQU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qVOnIioqyu58nTp1oNVqsW/fPuXYhQsXkJGRwfF3Q5MmTfDOO+/grbfeUv6rW7cu2rdvr/yb411x6tev7zS1fuHCBVSvXh0AEBUVhbCwMLvxLigowPHjxznebiguLoZGY/+xqNFoIKyX/OR43zjlGdt69eohPz8fJ0+eVNrs378fQogK2caGGSIP6NmzJ+bPn486deogKSkJ69evR3FxMVOwFeDTTz/F1q1bMWnSJPj7+yuZuICAAPj4+CAgIACdO3fGkiVLEBQUhICAACxcuBD16tXjHzA3+Pv7K/VZMl9fXwQHByvHOd4Vp0ePHpgyZQpWr16Ntm3b4vjx49i0aROeeOIJAIAkSejevTtWr16NmJgYREVF4csvv0R4eDhatWrl5d7/+7Rs2RKrV69GZGQk4uLicPr0aXz77be46667AHC8r1dRURFSU1OV22lpaTh9+jSCgoIQGRl51bGNi4tD8+bNsWDBAowcORJGoxELFy5E27ZtERERcd3949XuPeSHH37A119/jezsbCQkJOCxxx5DcnKyt7v1r9e/f3/V46NHj1YCTnmjwN9++w1Go5EbBVaw6dOnIyEhwWljRo53xdizZw+WL1+O1NRUREVFoUePHrjnnnuU88K6md3GjRtRUFCABg0a4PHHH7fbnJTKp7CwECtWrMDvv/+OnJwcREREoF27dujXrx90Okv+gOPtvgMHDuDll192Ot6xY0c8/fTT5RrbvLw8fPrpp3YbMw4fPrxCNmZkQERERERVHmuIiIiIqMpjQERERERVHgMiIiIiqvIYEBEREVGVx4CIiIiIqjwGRERERFTlMSAiIiKiKo8BERH9qx04cAD9+/fHjh07vN2VCnP8+HG89NJLeOSRR9C/f3+cPn3a210iuukxICKiq/r555/Rv39/DBkyBJmZmU7np0+fjueee84LPbv5GI1GzJ49G3l5eRg6dCjGjBmDyMhI1bZyMNi/f3+76zvJ5s+fj0ceeeRGd5nopsCAiIjKzWAwYO3atd7uxk3t0qVLSE9Px/3334977rkHHTp0QFBQ0FXvl5KS4oHeEd28GBARUbklJCRg06ZNqlmim11RUZFHnicnJwcAEBgYWO77JCQk4I8//lDNEhFR+fBq90RUbn369MF7772HtWvXYvjw4S7bpaWlYcyYMXYX2ZX1798f/fr1Uy7Mm5KSglWr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", 192 | "text/plain": [ 193 | "
" 194 | ] 195 | }, 196 | "metadata": {}, 197 | "output_type": "display_data" 198 | } 199 | ], 200 | "source": [ 201 | "# plot the stablization pattern of crr model\n", 202 | "\n", 203 | "calls_ = []\n", 204 | "for n in range(1, 100):\n", 205 | " \n", 206 | " s = 100\n", 207 | " x = 100\n", 208 | " r = 0.011\n", 209 | " t = 52\n", 210 | " sigma = 0.3\n", 211 | " \n", 212 | " crr = crr_model(s, x, r, t, sigma, n, sigma_daily = False)\n", 213 | " call, call_lat = crr.eu_call_price()\n", 214 | " calls_.append(call)\n", 215 | " \n", 216 | "plt.plot(range(1, 100), calls_, color = 'red')\n", 217 | "plt.xlabel('Numbers of N')\n", 218 | "plt.ylabel('Theoretical call price')\n", 219 | "plt.title('Options price convergency')\n", 220 | "# plt.savefig('Options price convergency')\n", 221 | "plt.show()" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 15, 227 | "id": "4c56fd30", 228 | "metadata": {}, 229 | "outputs": [], 230 | "source": [ 231 | "s = stocks.loc['2023-01-31']['close_d'] # get the stock price at the first dat of options trading\n", 232 | "x = 15500 # strike price\n", 233 | "r = 0.011 # use 5-year Taiwan government bond ytm\n", 234 | "t = 51 # time to maturity\n", 235 | "sigma = stocks.loc['2023-01-31']['moving volatility'] # get the return volatility at the first day od options trading\n", 236 | "N = 100 # divided time 2 maturity into 10 parts\n", 237 | "\n", 238 | "crr = crr_model(s, x, r, t, sigma, N, sigma_daily = True)\n", 239 | "call, call_lat = crr.eu_call_price()\n", 240 | "put, put_lat = crr.eu_put_price()\n", 241 | "call_a, call_lat_a = crr.am_call_price()\n", 242 | "put_a, put_lat_a = crr.am_put_price()" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "execution_count": 18, 248 | "id": "6f7da8f6", 249 | "metadata": {}, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "CRR theoretical price: 665.6911\n", 256 | "TEJ Black Scholes price: 708.365\n", 257 | "Real price: 650.0\n" 258 | ] 259 | } 260 | ], 261 | "source": [ 262 | "print('CRR theoretical price: ', round(put,4))\n", 263 | "print('TEJ Black Scholes price: ', round(puts.loc['2023-01-31']['theoremp'],4))\n", 264 | "print('Real price: ', puts.loc['2023-01-31']['settle'])" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "id": "1da8e559", 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [] 274 | } 275 | ], 276 | "metadata": { 277 | "kernelspec": { 278 | "display_name": "Python 3 (ipykernel)", 279 | "language": "python", 280 | "name": "python3" 281 | }, 282 | "language_info": { 283 | "codemirror_mode": { 284 | "name": "ipython", 285 | "version": 3 286 | }, 287 | "file_extension": ".py", 288 | "mimetype": "text/x-python", 289 | "name": "python", 290 | "nbconvert_exporter": "python", 291 | "pygments_lexer": "ipython3", 292 | "version": "3.11.3" 293 | } 294 | }, 295 | "nbformat": 4, 296 | "nbformat_minor": 5 297 | } 298 | -------------------------------------------------------------------------------- /TEJAPI_MediumWeek5.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "dependent-split", 6 | "metadata": {}, 7 | "source": [ 8 | "## Week 5 Medium - 定期定額投資回測" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "fluid-albert", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pandas as pd\n", 19 | "import numpy as np\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "import matplotlib.ticker as ticker\n", 22 | "import matplotlib.transforms as transforms\n", 23 | "import numpy_financial as npf\n", 24 | "\n", 25 | "\n", 26 | "import datetime\n", 27 | "\n", 28 | "import tejapi\n", 29 | "tejapi.ApiConfig.api_key = \"your key\"" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 2, 35 | "id": "dutch-portuguese", 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "### 資料撈取 from TEJ API\n", 40 | "\n", 41 | "TW0050 = tejapi.get(\n", 42 | " 'TWN/EWPRCD', \n", 43 | " coid = '0050',\n", 44 | " mdate={'gte':'2016-01-01', 'lte':'2020-12-31'}, \n", 45 | " opts={'columns': ['mdate','close_adj']}, \n", 46 | " paginate=True\n", 47 | " )\n", 48 | "\n", 49 | "TW0050['mdate'] = TW0050.loc[:,'mdate'].astype('datetime64[ns]')" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "id": "grave-illness", 55 | "metadata": {}, 56 | "source": [ 57 | "### 1. 將資料整理成月資料" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "id": "completed-service", 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "data": { 68 | "text/html": [ 69 | "
\n", 70 | "\n", 83 | "\n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | "
close_adj
mdate
2016-01-0449.8465
2016-01-0549.4280
2016-01-0648.9257
2016-01-0748.0050
2016-01-0848.0887
......
2020-12-25116.4129
2020-12-28117.4405
2020-12-29117.3427
2020-12-30119.0064
2020-12-31119.6425
\n", 141 | "

1224 rows × 1 columns

\n", 142 | "
" 143 | ], 144 | "text/plain": [ 145 | " close_adj\n", 146 | "mdate \n", 147 | "2016-01-04 49.8465\n", 148 | "2016-01-05 49.4280\n", 149 | "2016-01-06 48.9257\n", 150 | "2016-01-07 48.0050\n", 151 | "2016-01-08 48.0887\n", 152 | "... ...\n", 153 | "2020-12-25 116.4129\n", 154 | "2020-12-28 117.4405\n", 155 | "2020-12-29 117.3427\n", 156 | "2020-12-30 119.0064\n", 157 | "2020-12-31 119.6425\n", 158 | "\n", 159 | "[1224 rows x 1 columns]" 160 | ] 161 | }, 162 | "execution_count": 3, 163 | "metadata": {}, 164 | "output_type": "execute_result" 165 | } 166 | ], 167 | "source": [ 168 | "TW0050 = TW0050.set_index('mdate')\n", 169 | "TW0050" 170 | ] 171 | }, 172 | { 173 | "cell_type": "code", 174 | "execution_count": 4, 175 | "id": "demonstrated-bulgarian", 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "data": { 180 | "text/html": [ 181 | "
\n", 182 | "\n", 195 | "\n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | "
close_adj
mdate
2016-01-0149.8465
2016-02-0149.8465
2016-03-0151.7717
2016-04-0153.4877
2016-05-0150.8510
......
2020-09-01101.1456
2020-10-01100.8520
2020-11-01101.1946
2020-12-01111.8621
2020-12-31119.6425
\n", 253 | "

61 rows × 1 columns

\n", 254 | "
" 255 | ], 256 | "text/plain": [ 257 | " close_adj\n", 258 | "mdate \n", 259 | "2016-01-01 49.8465\n", 260 | "2016-02-01 49.8465\n", 261 | "2016-03-01 51.7717\n", 262 | "2016-04-01 53.4877\n", 263 | "2016-05-01 50.8510\n", 264 | "... ...\n", 265 | "2020-09-01 101.1456\n", 266 | "2020-10-01 100.8520\n", 267 | "2020-11-01 101.1946\n", 268 | "2020-12-01 111.8621\n", 269 | "2020-12-31 119.6425\n", 270 | "\n", 271 | "[61 rows x 1 columns]" 272 | ] 273 | }, 274 | "execution_count": 4, 275 | "metadata": {}, 276 | "output_type": "execute_result" 277 | } 278 | ], 279 | "source": [ 280 | "TW0050_monthly = TW0050.resample('MS').first()\n", 281 | "TW0050_monthly = TW0050_monthly.append(TW0050.iloc[-1])\n", 282 | "TW0050_monthly" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "id": "prompt-peter", 288 | "metadata": {}, 289 | "source": [ 290 | "### 2. 每月月初投入10000新台幣、期間不領回" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 5, 296 | "id": "graduate-occupation", 297 | "metadata": {}, 298 | "outputs": [], 299 | "source": [ 300 | "TW0050_monthly['每月購買股數']= np.floor(10000 / TW0050_monthly['close_adj'])\n", 301 | "TW0050_monthly['每月購買股數'][-1] = 0" 302 | ] 303 | }, 304 | { 305 | "cell_type": "code", 306 | "execution_count": 6, 307 | "id": "velvet-airfare", 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "TW0050_monthly['累積股數'] = TW0050_monthly['每月購買股數'].cumsum()" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 7, 317 | "id": "secure-stand", 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "TW0050_monthly['累積價值(月)'] = round(TW0050_monthly['累積股數'] * TW0050_monthly['close_adj'],2)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 8, 327 | "id": "quiet-romance", 328 | "metadata": {}, 329 | "outputs": [], 330 | "source": [ 331 | "TW0050_monthly['原始價值(月)'] = [10000*i for i in range(len(TW0050_monthly.index))]\n", 332 | "TW0050_monthly['原始價值(月)'] = TW0050_monthly['原始價值(月)'].shift(-1)\n", 333 | "TW0050_monthly['原始價值(月)'][-1] = TW0050_monthly['原始價值(月)'][-2]" 334 | ] 335 | }, 336 | { 337 | "cell_type": "code", 338 | "execution_count": 9, 339 | "id": "wicked-interim", 340 | "metadata": {}, 341 | "outputs": [], 342 | "source": [ 343 | "TW0050_monthly['累積報酬(月)'] = round((TW0050_monthly['累積價值(月)']-TW0050_monthly['原始價值(月)'])/TW0050_monthly['原始價值(月)'], 6) +1" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": 10, 349 | "id": "nuclear-journalist", 350 | "metadata": {}, 351 | "outputs": [ 352 | { 353 | "data": { 354 | "text/html": [ 355 | "
\n", 356 | "\n", 369 | "\n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | "
close_adj每月購買股數累積股數累積價值(月)原始價值(月)累積報酬(月)
mdate
2016-01-0149.8465200.0200.09969.3010000.00.996930
2016-02-0149.8465200.0400.019938.6020000.00.996930
2016-03-0151.7717193.0593.030700.6230000.01.023354
2016-04-0153.4877186.0779.041666.9240000.01.041673
2016-05-0150.8510196.0975.049579.7250000.00.991594
.....................
2020-09-01101.145698.08158.0825145.80570000.01.447624
2020-10-01100.852099.08257.0832734.96580000.01.435750
2020-11-01101.194698.08355.0845480.88590000.01.433018
2020-12-01111.862189.08444.0944563.57600000.01.574273
2020-12-31119.64250.08444.01010261.27600000.01.683769
\n", 492 | "

61 rows × 6 columns

\n", 493 | "
" 494 | ], 495 | "text/plain": [ 496 | " close_adj 每月購買股數 累積股數 累積價值(月) 原始價值(月) 累積報酬(月)\n", 497 | "mdate \n", 498 | "2016-01-01 49.8465 200.0 200.0 9969.30 10000.0 0.996930\n", 499 | "2016-02-01 49.8465 200.0 400.0 19938.60 20000.0 0.996930\n", 500 | "2016-03-01 51.7717 193.0 593.0 30700.62 30000.0 1.023354\n", 501 | "2016-04-01 53.4877 186.0 779.0 41666.92 40000.0 1.041673\n", 502 | "2016-05-01 50.8510 196.0 975.0 49579.72 50000.0 0.991594\n", 503 | "... ... ... ... ... ... ...\n", 504 | "2020-09-01 101.1456 98.0 8158.0 825145.80 570000.0 1.447624\n", 505 | "2020-10-01 100.8520 99.0 8257.0 832734.96 580000.0 1.435750\n", 506 | "2020-11-01 101.1946 98.0 8355.0 845480.88 590000.0 1.433018\n", 507 | "2020-12-01 111.8621 89.0 8444.0 944563.57 600000.0 1.574273\n", 508 | "2020-12-31 119.6425 0.0 8444.0 1010261.27 600000.0 1.683769\n", 509 | "\n", 510 | "[61 rows x 6 columns]" 511 | ] 512 | }, 513 | "execution_count": 10, 514 | "metadata": {}, 515 | "output_type": "execute_result" 516 | } 517 | ], 518 | "source": [ 519 | "TW0050_monthly" 520 | ] 521 | }, 522 | { 523 | "cell_type": "markdown", 524 | "id": "derived-transport", 525 | "metadata": {}, 526 | "source": [ 527 | "### 3. 作圖(累積資產、月報酬)" 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 11, 533 | "id": "humanitarian-spyware", 534 | "metadata": {}, 535 | "outputs": [ 536 | { 537 | "data": { 538 | "image/png": "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\n", 539 | "text/plain": [ 540 | "
" 541 | ] 542 | }, 543 | "metadata": { 544 | "needs_background": "light" 545 | }, 546 | "output_type": "display_data" 547 | } 548 | ], 549 | "source": [ 550 | "plt.figure(figsize = (10, 6))\n", 551 | "plt.plot(TW0050_monthly['累積價值(月)'], lw=1.5, label = '0050')\n", 552 | "plt.plot(TW0050_monthly['原始價值(月)'], lw=1.5, label = 'Original Asset')\n", 553 | "plt.xlabel('Time(Year)')\n", 554 | "plt.ylabel('Value')\n", 555 | "plt.legend(loc = 0) \n", 556 | "plt.grid()" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": 12, 562 | "id": "refined-radiation", 563 | "metadata": {}, 564 | "outputs": [ 565 | { 566 | "data": { 567 | "image/png": "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\n", 568 | "text/plain": [ 569 | "
" 570 | ] 571 | }, 572 | "metadata": { 573 | "needs_background": "light" 574 | }, 575 | "output_type": "display_data" 576 | } 577 | ], 578 | "source": [ 579 | "ret = np.log(TW0050_monthly['累積報酬(月)']/TW0050_monthly['累積報酬(月)'].shift(1))\n", 580 | "\n", 581 | "fig, ax = plt.subplots()\n", 582 | "ret.plot(kind=\"bar\", figsize=(12,6), stacked=True, ax=ax)\n", 583 | "\n", 584 | "##建立一個空陣列,長度為資料總月份的長度\n", 585 | "ticklabels = ['']*len(TW0050_monthly.index)\n", 586 | "\n", 587 | "##每6個月展示出其月份跟日期\n", 588 | "ticklabels[::6] = [item.strftime('%b %d') for item in TW0050_monthly.index[::6]]\n", 589 | "\n", 590 | "##每12個月額外展示出年份\n", 591 | "ticklabels[::12] = [item.strftime('%b %d\\n%Y') for item in TW0050_monthly.index[::12]]\n", 592 | "\n", 593 | "ax.xaxis.set_major_formatter(ticker.FixedFormatter(ticklabels))\n", 594 | "plt.gcf().autofmt_xdate()\n", 595 | "\n", 596 | "ax.axhline(ret.mean(), c='r')\n", 597 | "\n", 598 | "plt.xlabel('Month')\n", 599 | "plt.ylabel('Return')\n", 600 | "plt.title('0050 Monthly return')\n", 601 | "\n", 602 | "plt.show()" 603 | ] 604 | }, 605 | { 606 | "cell_type": "markdown", 607 | "id": "bound-circus", 608 | "metadata": {}, 609 | "source": [ 610 | "### 4. 績效/統計指標" 611 | ] 612 | }, 613 | { 614 | "cell_type": "code", 615 | "execution_count": 13, 616 | "id": "monetary-functionality", 617 | "metadata": {}, 618 | "outputs": [], 619 | "source": [ 620 | "###年報酬\n", 621 | "cagr = (TW0050_monthly['累積報酬(月)'][-1]) ** (1/5) -1\n", 622 | "\n", 623 | "###標準差\n", 624 | "std = ret.std()*np.sqrt(12)\n", 625 | "\n", 626 | "###夏普比率\n", 627 | "sharpe_ratio = (cagr-0.01)/std\n", 628 | "\n", 629 | "###最大回撤\n", 630 | "roll_max = TW0050_monthly['累積價值(月)'].cummax()\n", 631 | "monthly_dd =TW0050_monthly['累積價值(月)']/roll_max - 1.0\n", 632 | "max_dd = monthly_dd.cummin()" 633 | ] 634 | }, 635 | { 636 | "cell_type": "code", 637 | "execution_count": 14, 638 | "id": "dense-falls", 639 | "metadata": {}, 640 | "outputs": [ 641 | { 642 | "data": { 643 | "text/html": [ 644 | "
\n", 645 | "\n", 658 | "\n", 659 | " \n", 660 | " \n", 661 | " \n", 662 | " \n", 663 | " \n", 664 | " \n", 665 | " \n", 666 | " \n", 667 | " \n", 668 | " \n", 669 | " \n", 670 | " \n", 671 | " \n", 672 | " \n", 673 | " \n", 674 | " \n", 675 | " \n", 676 | " \n", 677 | " \n", 678 | " \n", 679 | " \n", 680 | " \n", 681 | " \n", 682 | " \n", 683 | "
0050
年化報酬率(%)10.98
年化標準差(%)15.54
夏普比率0.64
期間最大回撤(%)-15.68
\n", 684 | "
" 685 | ], 686 | "text/plain": [ 687 | " 0050\n", 688 | "年化報酬率(%) 10.98\n", 689 | "年化標準差(%) 15.54\n", 690 | "夏普比率 0.64\n", 691 | "期間最大回撤(%) -15.68" 692 | ] 693 | }, 694 | "execution_count": 14, 695 | "metadata": {}, 696 | "output_type": "execute_result" 697 | } 698 | ], 699 | "source": [ 700 | "pd.DataFrame(columns=['0050'], index=['年化報酬率(%)', '年化標準差(%)', '夏普比率', '期間最大回撤(%)'], \n", 701 | " data = np.round(np.array([100*cagr, 100*std, sharpe_ratio, 100*max_dd[-1]]),2))" 702 | ] 703 | }, 704 | { 705 | "cell_type": "markdown", 706 | "id": "corresponding-guatemala", 707 | "metadata": {}, 708 | "source": [ 709 | "### 附錄:將上述個別的程式碼做成Function" 710 | ] 711 | }, 712 | { 713 | "cell_type": "code", 714 | "execution_count": 15, 715 | "id": "hidden-lodging", 716 | "metadata": {}, 717 | "outputs": [], 718 | "source": [ 719 | "def Dollar_Cost_Averaging(data): \n", 720 | "\n", 721 | " data['每月購買股數']= np.floor(10000 / data['close_adj'])\n", 722 | " data['累積股數'] = data['每月購買股數'].cumsum()\n", 723 | " data['累積價值(月)'] = round(data['累積股數'] * data['close_adj'],2)\n", 724 | " data['原始價值(月)'] = [10000*i for i in range(len(data.index))]\n", 725 | " data['原始價值(月)'] = data['原始價值(月)'].shift(-1)\n", 726 | " data['原始價值(月)'][-1] = data['原始價值(月)'][-2]\n", 727 | " data['累積報酬(月)'] = round((data['累積價值(月)']-data['原始價值(月)'])/data['原始價值(月)'], 6) + 1\n", 728 | " \n", 729 | " return data" 730 | ] 731 | }, 732 | { 733 | "cell_type": "code", 734 | "execution_count": 16, 735 | "id": "accomplished-sierra", 736 | "metadata": {}, 737 | "outputs": [], 738 | "source": [ 739 | "def Performance(data, ticker):\n", 740 | " \n", 741 | " ret = np.log(data['累積報酬(月)']/data['累積報酬(月)'].shift(1))\n", 742 | " \n", 743 | " cagr = (data['累積報酬(月)'][-1]) ** (1/5) -1\n", 744 | " std = ret.std()*np.sqrt(12)\n", 745 | " sharpe_ratio = (cagr-0.01)/std\n", 746 | "\n", 747 | " roll_max = data['累積價值(月)'].cummax()\n", 748 | " monthly_dd = data['累積價值(月)']/roll_max - 1.0\n", 749 | " max_dd = monthly_dd.cummin()\n", 750 | " \n", 751 | " df = pd.DataFrame(columns=[ticker], index=['年化報酬率(%)', '年化標準差(%)', '夏普比率', '期間最大回撤(%)'], \n", 752 | " data = np.round(np.array([100*cagr, 100*std, sharpe_ratio, 100*max_dd[-1]]),2))\n", 753 | " \n", 754 | " return df" 755 | ] 756 | } 757 | ], 758 | "metadata": { 759 | "kernelspec": { 760 | "display_name": "Python 3", 761 | "language": "python", 762 | "name": "python3" 763 | }, 764 | "language_info": { 765 | "codemirror_mode": { 766 | "name": "ipython", 767 | "version": 3 768 | }, 769 | "file_extension": ".py", 770 | "mimetype": "text/x-python", 771 | "name": "python", 772 | "nbconvert_exporter": "python", 773 | "pygments_lexer": "ipython3", 774 | "version": "3.8.5" 775 | } 776 | }, 777 | "nbformat": 4, 778 | "nbformat_minor": 5 779 | } 780 | --------------------------------------------------------------------------------