#!/usr/bin/env python # coding: utf-8 # # Part 0: Import 套件 # In[ ]: #下載資料套件 import urllib3 from bs4 import BeautifulSoup #資料處理套件 import pandas as pd from datetime import datetime, date #畫圖套件 import matplotlib.pyplot as plt get_ipython().run_line_magic('matplotlib', 'inline') from plotly.subplots import make_subplots import plotly.graph_objects as go # # Part 1: 下載期交所 臺指選擇權 每日交易行情 # ### 股海小英雄youtube影片:[【Python 爬蟲】台指選擇權Put/Call比免費下載 (上)|股市多空頭趨勢預測](https://youtu.be/RqodmAWC8EE) # ### 資料來源:[期交所 臺指選擇權 每日交易行情](https://www.taifex.com.tw/cht/3/dlOptDailyMarketView) # **注意:查詢區間不可超過30日** # 用urllib3下載選擇權每日交易行情資料 # In[ ]: http = urllib3.PoolManager() url = "https://www.taifex.com.tw/cht/3/dlOptDataDown" res = http.request( 'POST', url, fields={ 'down_type': 1, 'commodity_id': 'TXO', 'queryStartDate': '2021/08/04', 'queryEndDate': '2021/08/11' } ) html_doc = res.data html_doc # 用BeautifulSoup解析資料 # In[ ]: soup = BeautifulSoup(html_doc, 'html.parser') soup # 把資料依行數切割 # In[ ]: soup_str = str(soup) lines = soup_str.split('\r\n') for i in range(5): print(lines[i]) print() # 把下載的選擇權每日交易行情資料存入dataframe內 # In[ ]: # 新增空的dataframe,定義欄位名稱 df = pd.DataFrame(columns = lines[0].split(',')) # 把選擇權資料一行一行寫入dataframe內 for i in range(1, len(lines) - 1): list_ = lines[i].split(',')[:-1] df_length = len(df) df.loc[df_length] = list_ #顯示dataframe前20行的資料 df.head(20) # # Part 2: 將下載的臺指選擇權 每日交易行情 另存成csv檔 # In[ ]: df.to_csv('options.csv') # # Part 3: 畫出臺指選擇權每日交易行情 # ### 資料轉型:把日期從字串(string)換成時間(datetime)/浮點數(float) # In[ ]: # 資料轉型 for col in [0, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]: for row in range(df.shape[0]): # 把"日期"從字串(string)換成時間(datetime) if col == 0: day = df.iloc[row,0].split('/') df.iloc[row, 0] = datetime(int(day[0]), int(day[1]), int(day[2])) # 把字串(string)換成浮點數(float): "履約價", "開盤價", "最高價", "最低價", "收盤價", "成交量", "結算價", "未沖銷契約數", "最後最佳買價", "最後最佳賣價", "歷史最高價", "歷史最低價" elif col != 0 and df.iloc[row, col] != '-': df.iloc[row, col] = float(df.iloc[row,col]) # ### 資料篩選:取出臺指選擇權202108W2的資料 # In[ ]: df.head(20) # In[ ]: df.describe() # In[ ]: df['到期月份(週別)'].unique() # 選到期月份(週別)是'202108W2'的資料 # In[ ]: df.loc[df['到期月份(週別)'] == '202108W2'] # 選到期月份(週別)是'202108W2'&買權的資料 # In[ ]: df.loc[(df['到期月份(週別)'] == '202108W2') & (df['買賣權'] == '買權')] # 選到期月份(週別)是'202108W2'&買權&履約價17800的資料 # In[ ]: df.loc[(df['到期月份(週別)'] == '202108W2') & (df['買賣權'] == '買權') & (df['履約價'] == 17800)] # 選到期月份(週別)是'202108W2'&買權&履約價17800&一般交易時段的資料 # In[ ]: df.loc[(df['到期月份(週別)'] == '202108W2') & (df['買賣權'] == '買權') & (df['履約價'] == 17800) & (df['交易時段'] == '一般')] # 用get_options函式篩選資料 # In[ ]: def get_options(option_df, contract_period, put_or_call, strike_price, trade_period): option_df = df.loc[(df['到期月份(週別)'] == contract_period) & \ (df['買賣權'] == put_or_call) & \ (df['履約價'] == strike_price) & \ (df['交易時段'] == trade_period)] return option_df # In[ ]: get_options(df, '202108W2', '買權', 17800, '一般') # 拿選擇權履約價17400-17700的資料 # In[ ]: txo_17400_c = get_options(df, '202108W2', '買權', 17400, '一般') txo_17500_c = get_options(df, '202108W2', '買權', 17500, '一般') txo_17600_c = get_options(df, '202108W2', '買權', 17600, '一般') txo_17700_c = get_options(df, '202108W2', '買權', 17700, '一般') txo_17400_p = get_options(df, '202108W2', '賣權', 17400, '一般') txo_17500_p = get_options(df, '202108W2', '賣權', 17500, '一般') txo_17600_p = get_options(df, '202108W2', '賣權', 17600, '一般') txo_17700_p = get_options(df, '202108W2', '賣權', 17700, '一般') # ### 用matplotlib套件:畫出選擇權202108W2走勢圖 # In[ ]: fig = plt.figure(figsize = (20, 5)) plt.title('TXO Option 202108W2 Call 17400 Historical Data') plt.plot(txo_17400_c['交易日期'], txo_17400_c['收盤價']) plt.legend(['Close']) # ### 用plotly套件:畫出選擇權202108W2各履約價走勢圖 # In[ ]: # Initialize figure with subplots fig = make_subplots( rows=7, cols=2, subplot_titles=("買權", "賣權") ) # Add traces fig.add_trace(go.Scatter(x = txo_17400_c["交易日期"], y = txo_17400_c["收盤價"], name = "買權17400"), row=1, col=1) fig.add_trace(go.Scatter(x = txo_17500_c["交易日期"], y = txo_17500_c["收盤價"], name = "買權17500"), row=2, col=1) fig.add_trace(go.Scatter(x = txo_17600_c["交易日期"], y = txo_17600_c["收盤價"], name = "買權17600"), row=3, col=1) fig.add_trace(go.Scatter(x = txo_17700_c["交易日期"], y = txo_17700_c["收盤價"], name = "買權17700"), row=4, col=1) fig.add_trace(go.Scatter(x = txo_17400_p["交易日期"], y = txo_17400_p["收盤價"], name = "賣權17400"), row=1, col=2) fig.add_trace(go.Scatter(x = txo_17500_p["交易日期"], y = txo_17500_p["收盤價"], name = "賣權17500"), row=2, col=2) fig.add_trace(go.Scatter(x = txo_17600_p["交易日期"], y = txo_17600_p["收盤價"], name = "賣權17600"), row=3, col=2) fig.add_trace(go.Scatter(x = txo_17700_p["交易日期"], y = txo_17700_p["收盤價"], name = "賣權17700"), row=4, col=2) # Update yaxis properties fig.update_yaxes(title_text="17400", row=1, col=2) fig.update_yaxes(title_text="17500", row=2, col=2) fig.update_yaxes(title_text="17600", row=3, col=2) fig.update_yaxes(title_text="17700", row=4, col=2) # Update title and height fig.update_layout(title_text="台指選 每日交易行情 - 202108W2", width = 1000, height=2000) fig.show()