├── 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 | " coid | \n",
394 | " mdate | \n",
395 | " fld014 | \n",
396 | " cls60 | \n",
397 | " close_d | \n",
398 | "
\n",
399 | " \n",
400 | " | None | \n",
401 | " | \n",
402 | " | \n",
403 | " | \n",
404 | " | \n",
405 | " | \n",
406 | "
\n",
407 | " \n",
408 | " \n",
409 | " \n",
410 | " | 0 | \n",
411 | " 1271 | \n",
412 | " 2021-01-18 | \n",
413 | " 70.30 | \n",
414 | " 70.3000 | \n",
415 | " 70.3 | \n",
416 | "
\n",
417 | " \n",
418 | " | 1 | \n",
419 | " 1271 | \n",
420 | " 2021-01-19 | \n",
421 | " 69.70 | \n",
422 | " 69.7000 | \n",
423 | " 69.1 | \n",
424 | "
\n",
425 | " \n",
426 | " | 2 | \n",
427 | " 1271 | \n",
428 | " 2021-01-20 | \n",
429 | " 69.60 | \n",
430 | " 69.6000 | \n",
431 | " 69.4 | \n",
432 | "
\n",
433 | " \n",
434 | " | 3 | \n",
435 | " 1271 | \n",
436 | " 2021-01-21 | \n",
437 | " 69.10 | \n",
438 | " 69.1000 | \n",
439 | " 67.6 | \n",
440 | "
\n",
441 | " \n",
442 | " | 4 | \n",
443 | " 1271 | \n",
444 | " 2021-01-22 | \n",
445 | " 69.12 | \n",
446 | " 69.1200 | \n",
447 | " 69.2 | \n",
448 | "
\n",
449 | " \n",
450 | " | ... | \n",
451 | " ... | \n",
452 | " ... | \n",
453 | " ... | \n",
454 | " ... | \n",
455 | " ... | \n",
456 | "
\n",
457 | " \n",
458 | " | 126739 | \n",
459 | " 8436 | \n",
460 | " 2022-12-26 | \n",
461 | " 165.75 | \n",
462 | " 132.6083 | \n",
463 | " 175.0 | \n",
464 | "
\n",
465 | " \n",
466 | " | 126740 | \n",
467 | " 8436 | \n",
468 | " 2022-12-27 | \n",
469 | " 167.75 | \n",
470 | " 133.5083 | \n",
471 | " 177.5 | \n",
472 | "
\n",
473 | " \n",
474 | " | 126741 | \n",
475 | " 8436 | \n",
476 | " 2022-12-28 | \n",
477 | " 168.65 | \n",
478 | " 134.2917 | \n",
479 | " 171.0 | \n",
480 | "
\n",
481 | " \n",
482 | " | 126742 | \n",
483 | " 8436 | \n",
484 | " 2022-12-29 | \n",
485 | " 169.90 | \n",
486 | " 135.0917 | \n",
487 | " 172.0 | \n",
488 | "
\n",
489 | " \n",
490 | " | 126743 | \n",
491 | " 8436 | \n",
492 | " 2022-12-30 | \n",
493 | " 171.25 | \n",
494 | " 135.8083 | \n",
495 | " 171.0 | \n",
496 | "
\n",
497 | " \n",
498 | "
\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 | " SMB | \n",
300 | " HML | \n",
301 | "
\n",
302 | " \n",
303 | " | 年月日 | \n",
304 | " | \n",
305 | " | \n",
306 | "
\n",
307 | " \n",
308 | " \n",
309 | " \n",
310 | " | 2014-01-02 | \n",
311 | " 0.727428 | \n",
312 | " 0.423522 | \n",
313 | "
\n",
314 | " \n",
315 | " | 2014-01-03 | \n",
316 | " 1.214870 | \n",
317 | " 0.678727 | \n",
318 | "
\n",
319 | " \n",
320 | " | 2014-01-06 | \n",
321 | " 0.623517 | \n",
322 | " 0.075185 | \n",
323 | "
\n",
324 | " \n",
325 | " | 2014-01-07 | \n",
326 | " 0.642468 | \n",
327 | " 0.697764 | \n",
328 | "
\n",
329 | " \n",
330 | " | 2014-01-08 | \n",
331 | " 0.241418 | \n",
332 | " 0.260657 | \n",
333 | "
\n",
334 | " \n",
335 | " | ... | \n",
336 | " ... | \n",
337 | " ... | \n",
338 | "
\n",
339 | " \n",
340 | " | 2022-07-25 | \n",
341 | " 0.322174 | \n",
342 | " 0.767774 | \n",
343 | "
\n",
344 | " \n",
345 | " | 2022-07-26 | \n",
346 | " 0.053480 | \n",
347 | " 0.787060 | \n",
348 | "
\n",
349 | " \n",
350 | " | 2022-07-27 | \n",
351 | " -0.290234 | \n",
352 | " -1.005587 | \n",
353 | "
\n",
354 | " \n",
355 | " | 2022-07-28 | \n",
356 | " -0.106124 | \n",
357 | " 0.418247 | \n",
358 | "
\n",
359 | " \n",
360 | " | 2022-07-29 | \n",
361 | " 0.065884 | \n",
362 | " -0.549442 | \n",
363 | "
\n",
364 | " \n",
365 | "
\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 | " SMB | \n",
459 | " HML | \n",
460 | " rm | \n",
461 | "
\n",
462 | " \n",
463 | " | 年月日 | \n",
464 | " | \n",
465 | " | \n",
466 | " | \n",
467 | "
\n",
468 | " \n",
469 | " \n",
470 | " \n",
471 | " | 2014-01-02 | \n",
472 | " 0.727428 | \n",
473 | " 0.423522 | \n",
474 | " 0.0120 | \n",
475 | "
\n",
476 | " \n",
477 | " | 2014-01-03 | \n",
478 | " 1.214870 | \n",
479 | " 0.678727 | \n",
480 | " -0.7663 | \n",
481 | "
\n",
482 | " \n",
483 | " | 2014-01-06 | \n",
484 | " 0.623517 | \n",
485 | " 0.075185 | \n",
486 | " -0.5444 | \n",
487 | "
\n",
488 | " \n",
489 | " | 2014-01-07 | \n",
490 | " 0.642468 | \n",
491 | " 0.697764 | \n",
492 | " 0.1446 | \n",
493 | "
\n",
494 | " \n",
495 | " | 2014-01-08 | \n",
496 | " 0.241418 | \n",
497 | " 0.260657 | \n",
498 | " 0.5135 | \n",
499 | "
\n",
500 | " \n",
501 | " | ... | \n",
502 | " ... | \n",
503 | " ... | \n",
504 | " ... | \n",
505 | "
\n",
506 | " \n",
507 | " | 2022-06-24 | \n",
508 | " 0.067493 | \n",
509 | " 0.737971 | \n",
510 | " 0.8360 | \n",
511 | "
\n",
512 | " \n",
513 | " | 2022-06-27 | \n",
514 | " 0.029549 | \n",
515 | " -0.991883 | \n",
516 | " 1.5989 | \n",
517 | "
\n",
518 | " \n",
519 | " | 2022-06-28 | \n",
520 | " -0.021501 | \n",
521 | " 0.649327 | \n",
522 | " -0.6952 | \n",
523 | "
\n",
524 | " \n",
525 | " | 2022-06-29 | \n",
526 | " 0.699726 | \n",
527 | " -0.251527 | \n",
528 | " -1.2940 | \n",
529 | "
\n",
530 | " \n",
531 | " | 2022-06-30 | \n",
532 | " 0.283322 | \n",
533 | " 0.301092 | \n",
534 | " -2.7191 | \n",
535 | "
\n",
536 | " \n",
537 | "
\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 | " | 2014-01-02 | \n",
606 | " 1101 | \n",
607 | " -1.8378 | \n",
608 | "
\n",
609 | " \n",
610 | " | 2014-01-02 | \n",
611 | " 1102 | \n",
612 | " -1.2953 | \n",
613 | "
\n",
614 | " \n",
615 | " | 2014-01-02 | \n",
616 | " 1104 | \n",
617 | " 0.1770 | \n",
618 | "
\n",
619 | " \n",
620 | " | 2014-01-02 | \n",
621 | " 1110 | \n",
622 | " 1.7143 | \n",
623 | "
\n",
624 | " \n",
625 | " | 2014-01-02 | \n",
626 | " 1203 | \n",
627 | " 0.0000 | \n",
628 | "
\n",
629 | " \n",
630 | " | ... | \n",
631 | " ... | \n",
632 | " ... | \n",
633 | "
\n",
634 | " \n",
635 | " | 2022-06-30 | \n",
636 | " 8440 | \n",
637 | " 9.9836 | \n",
638 | "
\n",
639 | " \n",
640 | " | 2022-06-30 | \n",
641 | " 8446 | \n",
642 | " -0.2710 | \n",
643 | "
\n",
644 | " \n",
645 | " | 2022-06-30 | \n",
646 | " 8928 | \n",
647 | " -6.1002 | \n",
648 | "
\n",
649 | " \n",
650 | " | 2022-06-30 | \n",
651 | " 9928 | \n",
652 | " 3.0488 | \n",
653 | "
\n",
654 | " \n",
655 | " | 2022-06-30 | \n",
656 | " 9950 | \n",
657 | " -9.1912 | \n",
658 | "
\n",
659 | " \n",
660 | "
\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 | " alpha | \n",
771 | " alpha0.2 | \n",
772 | " alpha0.8 | \n",
773 | "
\n",
774 | " \n",
775 | " | 年月日 | \n",
776 | " | \n",
777 | " | \n",
778 | " | \n",
779 | " | \n",
780 | "
\n",
781 | " \n",
782 | " \n",
783 | " \n",
784 | " | 2014-06-30 | \n",
785 | " 1210 | \n",
786 | " 0.216635 | \n",
787 | " -0.142295 | \n",
788 | " 0.141690 | \n",
789 | "
\n",
790 | " \n",
791 | " | 2014-06-30 | \n",
792 | " 1527 | \n",
793 | " 0.168521 | \n",
794 | " -0.142295 | \n",
795 | " 0.141690 | \n",
796 | "
\n",
797 | " \n",
798 | " | 2014-06-30 | \n",
799 | " 1582 | \n",
800 | " 0.237503 | \n",
801 | " -0.142295 | \n",
802 | " 0.141690 | \n",
803 | "
\n",
804 | " \n",
805 | " | 2014-06-30 | \n",
806 | " 1583 | \n",
807 | " 0.585237 | \n",
808 | " -0.142295 | \n",
809 | " 0.141690 | \n",
810 | "
\n",
811 | " \n",
812 | " | 2014-06-30 | \n",
813 | " 1711 | \n",
814 | " 0.192855 | \n",
815 | " -0.142295 | \n",
816 | " 0.141690 | \n",
817 | "
\n",
818 | " \n",
819 | " | ... | \n",
820 | " ... | \n",
821 | " ... | \n",
822 | " ... | \n",
823 | " ... | \n",
824 | "
\n",
825 | " \n",
826 | " | 2022-06-30 | \n",
827 | " 8409 | \n",
828 | " 0.490293 | \n",
829 | " -0.087633 | \n",
830 | " 0.134834 | \n",
831 | "
\n",
832 | " \n",
833 | " | 2022-06-30 | \n",
834 | " 8433 | \n",
835 | " 0.220098 | \n",
836 | " -0.087633 | \n",
837 | " 0.134834 | \n",
838 | "
\n",
839 | " \n",
840 | " | 2022-06-30 | \n",
841 | " 8928 | \n",
842 | " 0.279140 | \n",
843 | " -0.087633 | \n",
844 | " 0.134834 | \n",
845 | "
\n",
846 | " \n",
847 | " | 2022-06-30 | \n",
848 | " 8941 | \n",
849 | " 0.141910 | \n",
850 | " -0.087633 | \n",
851 | " 0.134834 | \n",
852 | "
\n",
853 | " \n",
854 | " | 2022-06-30 | \n",
855 | " 9950 | \n",
856 | " 0.295723 | \n",
857 | " -0.087633 | \n",
858 | " 0.134834 | \n",
859 | "
\n",
860 | " \n",
861 | "
\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+ioqKc2t19991488038cILLyA5ORndu3dHYmIi8vLy8M8//2DLli1o3749fvjhh3I9b0hICObPn49HHnkEbdu2Vd7vbdu24a+//kLHjh2xZcsWaDSlExANGjTAwoULMXz4cDRu3Bhdu3ZFvXr1YDAYcObMGfz666+oXr06Dh8+7PZ4REZGYvny5ejXrx/uuusudOvWDU2bNkVubi7+/vtvnD17FqdOnXK63+jRo7Fx40ZcunQJzzzzDPz9/d3uA/3LeTsiI/KmnTt3ikcffVQkJCQIPz8/ERgYKBo3biyee+45l98obb+dfvPNN6J169YiICBAhIaGigcffFD1G7AQQrz77ruiQYMGwsfHRwCw+wbu6tuwyWQS8+fPFy1bthT+/v7C399f3HrrrWLevHnCZDI5tcc1ZIhKSkrEzJkzRdeuXUWtWrWEr6+viIyMFHfccYf48MMPnTYQdMU2i7Fo0SLRrFkz4efnJyIjI8WwYcPEhQsXnO7jToZI9s8//4hRo0aJhIQEodfrRUREhLj99tud9vcRwrKXz3//+1/RuHFj4e/vLwIDA0VSUpLo27evWLp0qd3y9KvZtm2bePDBB0X16tWFXq8XMTEx4r777hMrV650avvFF1+Idu3aiaCgIOHr6ysaNWokXnvtNVFYWOjU1t0MkRBCvPrqq0pGZtWqVWX2/9dffxUPPfSQiImJEXq9XkRGRopmzZqJZ599VuzatavcfZKtX79etGnTRvj7+4uwsDDRq1cvcejQIdGjRw8BwGnPIyGE+Pvvv8XQoUNF7dq1hY+PjwgPDxeNGzcWTzzxhNi0aZNd22vNEMn2798vHnnkEREbGyv0er2IiooSHTp0UN0KQQhL9i4yMrLMrQmoauDFXYmu0WeffYbHHnsMixYtUi41UZVNnz4dL7/8MjZv3qy6RQBVHSaTCXXq1EFJSYlSQF7ZnTx5EklJSWjXrt0NrXGiyo9F1UREdE2ys7NRUFBgd0wIgddeew1nzpwp81prlc0777wDIUSZ09dUNbCGiIiIrsmOHTswYMAA3HvvvUhISEBeXh527NiBvXv3olatWqqbYVYmZ86cwfLly3Hs2DEsWrQIzZo1w0MPPeTtbpGXMSAiIqJrUr9+ffTs2RO//fYb1q9fD6PRiLi4OIwdOxaTJ09WLe6uTE6ePIkXXngBAQEB6NKlCz788EO7InCqmlhDRERERFVepcoQPf3000hPT3c6fu+992LEiBGq99m+fTtWrFiB9PR0REdHY8iQIXab1QkhkJKSgk2bNiE/Px8NGjTAiBEjXG6tT0RERFVPpcoQ5ebmwmw2K7fPnDmD1157DdOmTUPjxo2d2h85cgTTpk3D4MGDceutt2Lr1q1Yt24dZs6cidq1awMA1q5di7Vr1+Lpp59GVFQUVqxYgTNnzmDWrFmq14giIiKiqqdSTZqGhIQgLCxM+e+PP/5AjRo1lKs5O1q/fj2aN2+OXr16IS4uDgMHDkSdOnWUDcaEEFi/fj0efPBBtGrVCvHx8RgzZgyysrJUr7hMREREVVOlCohsGY1G/Prrr7jrrrtcXmTw6NGjaNKkid2xZs2a4dixYwCAtLQ0ZGdno2nTpsr5gIAAJCUl4ejRozeu80RERPSvUqlqiGz9/vvvyM/PL3Ojt+zsbKerRoeGhiI7O1s5Lx9z1UaNwWCwu8K4JEnw9/dHVlaWcmkAd0iShMjISGRkZKASzVTetDjensXx9iyOt2dxvD2rosZbp9MhPDy8fG3dfpYbbPPmzWjevDkiIiI8/txr1qzBqlWrlNuJiYmYOXNmuQf1aiIjIyvkcah8ON6exfH2LI63Z3G8PcuT410pA6L09HT8/fffmDBhQpntwsLCkJOTY3csJycHYWFhynn5mG0wk5OTg4SEBJeP26dPH/Ts2VO5LU/ZpaenX3eGKDo6GqmpqfyG4QEcb8/ieHsWx9uzON6eVVHjrdPpUL169fK1dftZbqDNmzcjNDTUbvm8mnr16mHfvn3o0aOHcuzvv/9GcnIyACAqKgphYWHYt2+fEgAVFBTg+PHjuPfee10+rl6vh16vVz1XEb8IQgj+QnkQx9uzON6exfH2LI63Z3lyvCtdUbXZbMbPP/+Mjh07QqvV2p2bN28eli9frtzu3r07/vrrL3zzzTc4f/48UlJScOLECXTt2hWAJcLs3r07Vq9ejd27d+PMmTOYN28ewsPD0apVK4++LiIiIqq8Kl2GaN++fcjIyMBdd93ldC4jI8NuxVn9+vUxduxYfPnll/jiiy8QExODiRMnKnsQAcADDzyA4uJiLFiwAAUFBWjQoAEmT57MPYiIiIhIUak2Zqzs0tPT7VafXStJkhATE4OLFy8y5eoBHG/P4nh7FsfbszjenlVR463X68tdQ1TppsyIiIiIPI0BEREREVV5DIiIiIioymNARERERFUeAyIiIiKq8hgQERERUZXHgIiIiIiqvEq3MWNVIl25Ak1ODkRAAMxeuIgtERERWTBD5EWBCxeixh13IPj1173dFSIioiqNAZE36SwJOslk8nJHiIiIqjYGRF4k5IvXGo3e7QgREVEVx4DIm+SAyGz2bj+IiIiqOAZE3mQNiCRmiIiIiLyKAZEXCWaIiIiIKgUGRN7EGiIiIqJKgQGRFwl5lRkDIiIiIq9iQORNGuvwc8qMiIjIqxgQeRMzRERERJUCAyIvUoqquTEjERGRVzEg8iYGRERERJUCAyJvkvchYkBERETkVQyIvIhTZkRERJUDAyJvYkBERERUKTAg8iauMiMiIqoUGBB5keA+RERERJUCAyJvsmaIeOkOIiIi72JA5E3ylBlriIiIiLyKAZEXKVNmDIiIiIi8igGRN8lTZgyIiIiIvIoBkRcJbsxIRERUKTAg8ibuQ0RERFQpMCDyJjlDxFVmREREXqXzdgccZWZmYtmyZdi7dy+Ki4sRHR2N0aNHo27duqrt58+fjy1btjgdj4uLw6xZswAAKSkpWLVqld352NhYzJkzp8L7fy2US3dwHyIiIiKvqlQBUV5eHqZMmYLGjRtj8uTJCAkJwcWLFxEYGOjyPo899hiGDBmi3DaZTJg4cSJat25t165WrVqYMmWKclujqQTJMTkgYoaIiIjIqypVQLRu3TpUq1YNo0ePVo5FRUWVeZ+AgAAEBAQot3///Xfk5+fjrrvusmun0WgQFhZWof29bvI+RMwQEREReVWlCoh2796NZs2aYdasWTh48CAiIiJw77334p577in3Y/z0009o0qQJqlevbnc8NTUVTz75JPR6PerVq4fBgwcjMjJS9TEMBgMMBoNyW5Ik+Pv7K/92l3xf5TFsMkTX87ikzmm86YbieHsWx9uzON6e5Y3xloQQwmPPdhXy1FePHj3Qpk0bnDhxAosWLcLIkSPRqVOnq94/MzMTo0ePxtixY9G2bVvl+J9//omioiLExsYiKysLq1atQmZmJt59910l0LHlWHOUmJiImTNnXv8LdJSaCsTEAJLEOiIiIiIvqlQZIrPZjLp162Lw4MEALIHImTNnsGHDhnIFRFu2bEFgYCBuv/12u+MtWrRQ/h0fH4/k5GSMHj0a27dvR+fOnZ0ep0+fPujZs6dyW45Q09PTYbyOeh9JkhAdHY3U1FQIIaC5fBk1AEAIXDx/HqgMdU03EcfxphuL4+1ZHG/P4nh7VkWNt06nc5oxctnW7We5AcLDwxEXF2d3LC4uDjt37rzqfYUQ2Lx5M+68807odGW/rMDAQMTGxiI1NVX1vF6vh16vd/k810sIASEEzDYBkDAaARfPSddHHm/yDI63Z3G8PYvj7VmeHO9KlZKoX78+Lly4YHfswoUL5YruDh48iNTUVNWMj6OioiKkpqZ6v8hariECuNKMiIjIiypVQNSjRw8cO3YMq1evRmpqKrZu3YpNmzbhvvvuU9osX74c8+bNc7rvTz/9hOTkZNSuXdvp3JIlS3Dw4EGkpaXhyJEjePvtt6HRaNC+ffsb+nquyiaTxZVmRERE3lOppsySkpIwYcIELF++HF999RWioqIwdOhQ3HnnnUqbrKwsZGRk2N2voKAAO3fuxLBhw1QfNzMzE3PnzsWVK1cQEhKCBg0aYMaMGQgJCbmRL+eqhG3NEDNEREREXlOpAiIAaNmyJVq2bOny/NNPP+10LCAgAMuWLXN5n/Hjx1dE1yqeba0Tr2dGRETkNZVqyqzKsckQ8Yr3RERE3sOAyJskqfR6ZgyIiIiIvIYBkbfJV7xnQEREROQ1DIi8jBkiIiIi72NA5G284j0REZHXMSDyNl7xnoiIyOsYEHmZshcRM0RERERew4DI2+S9iFhDRERE5DUMiLzNmiHiKjMiIiLvYUDkZYIZIiIiIq9jQORtXGVGRETkdQyIvE3emJGrzIiIiLyGAZGXCWaIiIiIvI4BkbexhoiIiMjrGBB5G1eZEREReR0DIi/jKjMiIiLvY0DkbcwQEREReR0DIi9jhoiIiMj7GBB5G1eZEREReR0DIm/jPkRERERex4DIy7gPERERkfcxIPI21hARERF5HQMib+MqMyIiIq9jQORlXGVGRETkfQyIvM2aIWJARERE5D0MiLzNmiHilBkREZH3MCDyMq4yIyIi8j4GRN4mB0Tch4iIiMhrGBB5m7wxIzNEREREXsOAyMu4yoyIiMj7GBB5G/chIiIi8jqdtzvgKDMzE8uWLcPevXtRXFyM6OhojB49GnXr1lVtf+DAAbz88stOxz/++GOEhYUpt3/44Qd88803yM7ORnx8PIYPH46kpKQb9TLKjRkiIiIi76tUAVFeXh6mTJmCxo0bY/LkyQgJCcHFixcRGBh41fvOmTMHAQEByu2QkBDl39u2bcOSJUswcuRIJCcn47vvvsOMGTMwZ84chIaG3pDXUm7ch4iIiMjrKlVAtG7dOlSrVg2jR49WjkVFRZXrvqGhoS4Dp2+//RZ333037rrrLgDAyJEj8ccff2Dz5s3o3bv3dff7unAfIiIiIq+rVAHR7t270axZM8yaNQsHDx5EREQE7r33Xtxzzz1Xve+kSZNgMBhQq1YtPPTQQ2jQoAEAwGg04uTJk3aBj0ajQZMmTXD06FHVxzIYDDAYDMptSZLg7++v/Ntd8n3tHkNedm8yXddjkzPV8aYbhuPtWRxvz+J4e5Y3xrtSBURpaWnYsGEDevTogT59+uDEiRNYtGgRdDodOnXqpHqf8PBwjBw5EnXr1oXBYMCmTZvw8ssvY8aMGahTpw5yc3NhNpvt6okAICwsDBcuXFB9zDVr1mDVqlXK7cTERMycORPVq1evkNcZHR1t2xEAQJCfH4JiYirk8cme3XjTDcfx9iyOt2dxvD3Lk+NdqQIis9mMunXrYvDgwQAsgciZM2ewYcMGlwFRbGwsYmNjldv169fHpUuX8N133+GZZ55xqx99+vRBz549ldtyhJqeng7jdewXJEkSoqOjkZqaCiEEACCooADBAPJzcpB78aLbj03O1MabbhyOt2dxvD2L4+1ZFTXeOp2u3MmMShUQhYeHIy4uzu5YXFwcdu7ceU2Pk5SUhMOHDwOwFFdrNBpkZ2fbtcnOznbKGsn0ej30er3quYr4RRBCKI9ju8qMv2Q3hu14043H8fYsjrdncbw9y5PjXan2Iapfv77TNNaFCxeuearq9OnTCA8PB2CJDuvUqYP9+/cr581mM/bv34969epdf6evF1eZEREReV2lCoh69OiBY8eOYfXq1UhNTcXWrVuxadMm3HfffUqb5cuXY968ecrt7777Drt27UJqairOnDmDzz77DPv377e7T8+ePbFp0yb8/PPPOHfuHD755BMUFxe7nIbzKK4yIyIi8rpKNWWWlJSECRMmYPny5fjqq68QFRWFoUOH4s4771TaZGVlISMjQ7ltNBqxZMkSZGZmwtfXF/Hx8ZgyZQpuueUWpU3btm2Rm5uLlJQUZGdnIyEhAZMnT3Y5ZeZJvNo9ERGR91WqgAgAWrZsiZYtW7o8//TTT9vdfuCBB/DAAw9c9XG7du2Krl27Xnf/Khyvdk9EROR1lWrKrEri1e6JiIi8jgGRlwlmiIiIiLyOAZG3sYaIiIjI6xgQeZngKjMiIiKvY0DkbdyHiIiIyOsYEHkbM0RERERex4DIy7gPERERkfdd1z5EBoMBp06dQk5ODurXr4+QkJCK6lfVIQdEzBARERF5jdsB0fr167Fy5UoUFBQAgLI7dG5uLp599lkMGTIEnTt3rrCO3rTkfYgYEBEREXmNW1NmmzdvxuLFi9G8eXOMGjXK7lxISAgaN26Mbdu2VUgHb3aCGSIiIiKvcysg+vbbb3Hbbbdh3LhxqpfZqFOnDs6ePXvdnasSGBARERF5nVsBUWpqKlq0aOHyfFBQEPLy8tzuVJUirzJjUTUREZHXuBUQBQQEIDc31+X5c+fOVYoryf8bCHkfIl66g4iIyGvcCohatGiBTZs2IT8/3+nc2bNnsWnTpjKvWE82rBkiLrsnIiLyHrdWmQ0cOBAvvvginnvuOSXw+fnnn/HTTz9h586dCA8PR79+/Sq0ozctbsxIRETkdW4FRBEREXjzzTfxxRdfKKvJfv31V/j5+aFdu3YYMmQI9yQqJ8FLdxAREXmd2/sQhYaG4qmnnsJTTz2F3NxcmM1mhISEQKPh5tfXRJ4yY0BERETkNde1U7WM2SD3CW7MSERE5HVupXO+/PJLTJw40eX5SZMmYeXKlW53qkrhPkRERERe51ZAtGPHjjL3IWrRogV3qi4vOUPEVWZERERe41ZAlJGRgRo1arg8HxUVhYyMDLc7VZUol+7gPkRERERe41ZA5Ofnh/T0dJfn09LSoNfr3e5UlSIHRMwQEREReY1bAVGjRo2wceNGZGZmOp3LyMjAxo0b0bhx4+vuXJUg70PEDBEREZHXuL0x4wsvvID//Oc/6Ny5M+Li4gBYdqnevHkzhBAYMGBAhXb0ZqXsQ8QMERERkde4FRDFxsbilVdewcKFC/Hdd9/ZnWvYsCEee+wxJUiiq+A+RERERF7n9j5E8fHxePnll5Gbm4u0tDQAlmJq7kl0jeRVZkJYCqu5sSUREZHHXffGjCEhIQyCroOyygywZIkYEBEREXlcuQKiLVu2AAA6dOgASZKU21fTsWNH93tWVdgGREYjwNV5REREHleugOiDDz4AALRr1w46nU65fTUMiMpBV/oWSGYzhBe7QkREVFWVKyCaN2+epbH1w1u+TddP2E6RcaUZERGRV5QrIKpevbryb6PRiIKCAgQFBaFatWo3rGNVhk2GiCvNiIiIvOOai6o1Gg2ef/55PPLII+jevXuFdygzMxPLli3D3r17UVxcjOjoaIwePRp169ZVbb9z5078+OOPOH36NIxGI+Li4vDQQw+hefPmSpuUlBSsWrXK7n6xsbGYM2dOhff/mtlkiCSTiVNmREREXuBWQBQZGQnjDZjeycvLw5QpU9C4cWNMnjwZISEhuHjxIgIDA13e59ChQ2jatCkGDRqEwMBAbN68GTNnzsTrr7+OxMREpV2tWrUwZcoUu9dRKUgShFYLyWRihoiIiMhL3Fp2361bN/zwww/o3LkzgoKCKqwz69atQ7Vq1TB69GjlWFRUVJn3GTZsmN3twYMHY/fu3dizZ49dQKTRaBAWFlZhfa1QWi1gMlmCIiIiIvI4twIis9kMvV6PZ555BnfccQeioqLg4+Pj1K5nz57X9Li7d+9Gs2bNMGvWLBw8eBARERG49957cc8991xT3woLC50CtdTUVDz55JPQ6/WoV68eBg8ejMjISNXHMBgMMBgMym1JkuDv76/8213yfR0fQ2i1kGBZZXY9j0/2XI033Rgcb8/ieHsWx9uzvDHekhDimstWynudshUrVlzT4w4ZMgQA0KNHD7Rp0wYnTpzAokWLMHLkSHTq1Klcj7Fu3TqsXbsWc+bMQWhoKADgzz//RFFREWJjY5GVlYVVq1YhMzMT7777rhLo2HKsOUpMTMTMmTOv6bVck5AQ4MoV4OhRIDn5xj0PERERqXIrQ3Sjlt2bzWbUrVsXgwcPBmAJRM6cOYMNGzaUKyDaunUrVq1ahYkTJyrBEAC0aNFC+Xd8fDySk5MxevRobN++HZ07d3Z6nD59+thlt+QINT09/bpqpyRJQnR0NFJTU2Ebh9bQaqEBkHbxIkwVOAVZ1bkab7oxON6exfH2LI63Z1XUeOt0OruV8mW2decJyvvg1yo8PNzporBxcXHYuXPnVe/722+/4aOPPsJ//vMfNG3atMy2gYGBiI2NRWpqqup5vV4PvYsdoyviF0EIYfc4tle85y9axXMcb7qxON6exfH2LI63Z3lyvK/rWmZ5eXn4+++/kZ6eDsASKDVp0gTBwcFuPV79+vVx4cIFu2MXLly4agC2detWfPjhhxg/fjxuvfXWqz5PUVERUlNTceedd7rVzwrHK94TERF5ldsBUUpKCtatW+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 | " close_adj | \n",
88 | "
\n",
89 | " \n",
90 | " | mdate | \n",
91 | " | \n",
92 | "
\n",
93 | " \n",
94 | " \n",
95 | " \n",
96 | " | 2016-01-04 | \n",
97 | " 49.8465 | \n",
98 | "
\n",
99 | " \n",
100 | " | 2016-01-05 | \n",
101 | " 49.4280 | \n",
102 | "
\n",
103 | " \n",
104 | " | 2016-01-06 | \n",
105 | " 48.9257 | \n",
106 | "
\n",
107 | " \n",
108 | " | 2016-01-07 | \n",
109 | " 48.0050 | \n",
110 | "
\n",
111 | " \n",
112 | " | 2016-01-08 | \n",
113 | " 48.0887 | \n",
114 | "
\n",
115 | " \n",
116 | " | ... | \n",
117 | " ... | \n",
118 | "
\n",
119 | " \n",
120 | " | 2020-12-25 | \n",
121 | " 116.4129 | \n",
122 | "
\n",
123 | " \n",
124 | " | 2020-12-28 | \n",
125 | " 117.4405 | \n",
126 | "
\n",
127 | " \n",
128 | " | 2020-12-29 | \n",
129 | " 117.3427 | \n",
130 | "
\n",
131 | " \n",
132 | " | 2020-12-30 | \n",
133 | " 119.0064 | \n",
134 | "
\n",
135 | " \n",
136 | " | 2020-12-31 | \n",
137 | " 119.6425 | \n",
138 | "
\n",
139 | " \n",
140 | "
\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 | " close_adj | \n",
200 | "
\n",
201 | " \n",
202 | " | mdate | \n",
203 | " | \n",
204 | "
\n",
205 | " \n",
206 | " \n",
207 | " \n",
208 | " | 2016-01-01 | \n",
209 | " 49.8465 | \n",
210 | "
\n",
211 | " \n",
212 | " | 2016-02-01 | \n",
213 | " 49.8465 | \n",
214 | "
\n",
215 | " \n",
216 | " | 2016-03-01 | \n",
217 | " 51.7717 | \n",
218 | "
\n",
219 | " \n",
220 | " | 2016-04-01 | \n",
221 | " 53.4877 | \n",
222 | "
\n",
223 | " \n",
224 | " | 2016-05-01 | \n",
225 | " 50.8510 | \n",
226 | "
\n",
227 | " \n",
228 | " | ... | \n",
229 | " ... | \n",
230 | "
\n",
231 | " \n",
232 | " | 2020-09-01 | \n",
233 | " 101.1456 | \n",
234 | "
\n",
235 | " \n",
236 | " | 2020-10-01 | \n",
237 | " 100.8520 | \n",
238 | "
\n",
239 | " \n",
240 | " | 2020-11-01 | \n",
241 | " 101.1946 | \n",
242 | "
\n",
243 | " \n",
244 | " | 2020-12-01 | \n",
245 | " 111.8621 | \n",
246 | "
\n",
247 | " \n",
248 | " | 2020-12-31 | \n",
249 | " 119.6425 | \n",
250 | "
\n",
251 | " \n",
252 | "
\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 | " close_adj | \n",
374 | " 每月購買股數 | \n",
375 | " 累積股數 | \n",
376 | " 累積價值(月) | \n",
377 | " 原始價值(月) | \n",
378 | " 累積報酬(月) | \n",
379 | "
\n",
380 | " \n",
381 | " | mdate | \n",
382 | " | \n",
383 | " | \n",
384 | " | \n",
385 | " | \n",
386 | " | \n",
387 | " | \n",
388 | "
\n",
389 | " \n",
390 | " \n",
391 | " \n",
392 | " | 2016-01-01 | \n",
393 | " 49.8465 | \n",
394 | " 200.0 | \n",
395 | " 200.0 | \n",
396 | " 9969.30 | \n",
397 | " 10000.0 | \n",
398 | " 0.996930 | \n",
399 | "
\n",
400 | " \n",
401 | " | 2016-02-01 | \n",
402 | " 49.8465 | \n",
403 | " 200.0 | \n",
404 | " 400.0 | \n",
405 | " 19938.60 | \n",
406 | " 20000.0 | \n",
407 | " 0.996930 | \n",
408 | "
\n",
409 | " \n",
410 | " | 2016-03-01 | \n",
411 | " 51.7717 | \n",
412 | " 193.0 | \n",
413 | " 593.0 | \n",
414 | " 30700.62 | \n",
415 | " 30000.0 | \n",
416 | " 1.023354 | \n",
417 | "
\n",
418 | " \n",
419 | " | 2016-04-01 | \n",
420 | " 53.4877 | \n",
421 | " 186.0 | \n",
422 | " 779.0 | \n",
423 | " 41666.92 | \n",
424 | " 40000.0 | \n",
425 | " 1.041673 | \n",
426 | "
\n",
427 | " \n",
428 | " | 2016-05-01 | \n",
429 | " 50.8510 | \n",
430 | " 196.0 | \n",
431 | " 975.0 | \n",
432 | " 49579.72 | \n",
433 | " 50000.0 | \n",
434 | " 0.991594 | \n",
435 | "
\n",
436 | " \n",
437 | " | ... | \n",
438 | " ... | \n",
439 | " ... | \n",
440 | " ... | \n",
441 | " ... | \n",
442 | " ... | \n",
443 | " ... | \n",
444 | "
\n",
445 | " \n",
446 | " | 2020-09-01 | \n",
447 | " 101.1456 | \n",
448 | " 98.0 | \n",
449 | " 8158.0 | \n",
450 | " 825145.80 | \n",
451 | " 570000.0 | \n",
452 | " 1.447624 | \n",
453 | "
\n",
454 | " \n",
455 | " | 2020-10-01 | \n",
456 | " 100.8520 | \n",
457 | " 99.0 | \n",
458 | " 8257.0 | \n",
459 | " 832734.96 | \n",
460 | " 580000.0 | \n",
461 | " 1.435750 | \n",
462 | "
\n",
463 | " \n",
464 | " | 2020-11-01 | \n",
465 | " 101.1946 | \n",
466 | " 98.0 | \n",
467 | " 8355.0 | \n",
468 | " 845480.88 | \n",
469 | " 590000.0 | \n",
470 | " 1.433018 | \n",
471 | "
\n",
472 | " \n",
473 | " | 2020-12-01 | \n",
474 | " 111.8621 | \n",
475 | " 89.0 | \n",
476 | " 8444.0 | \n",
477 | " 944563.57 | \n",
478 | " 600000.0 | \n",
479 | " 1.574273 | \n",
480 | "
\n",
481 | " \n",
482 | " | 2020-12-31 | \n",
483 | " 119.6425 | \n",
484 | " 0.0 | \n",
485 | " 8444.0 | \n",
486 | " 1010261.27 | \n",
487 | " 600000.0 | \n",
488 | " 1.683769 | \n",
489 | "
\n",
490 | " \n",
491 | "
\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 | " 0050 | \n",
663 | "
\n",
664 | " \n",
665 | " \n",
666 | " \n",
667 | " | 年化報酬率(%) | \n",
668 | " 10.98 | \n",
669 | "
\n",
670 | " \n",
671 | " | 年化標準差(%) | \n",
672 | " 15.54 | \n",
673 | "
\n",
674 | " \n",
675 | " | 夏普比率 | \n",
676 | " 0.64 | \n",
677 | "
\n",
678 | " \n",
679 | " | 期間最大回撤(%) | \n",
680 | " -15.68 | \n",
681 | "
\n",
682 | " \n",
683 | "
\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 |
--------------------------------------------------------------------------------