#!/usr/bin/env python # coding: utf-8 # # Part 0: Import 套件 # In[1]: #下載資料套件 import urllib3 from bs4 import BeautifulSoup #資料處理套件 import pandas as pd from datetime import datetime, date, timedelta #畫圖套件 import matplotlib.pyplot as plt get_ipython().run_line_magic('matplotlib', 'inline') # # Part 1: 下載期交所30天內選擇權Put/Call比 # 台灣期貨交易所: 臺指選擇權 Put/Call Ratios 統計表 https://www.taifex.com.tw/cht/3/pcRatio # **注意:查詢區間不可超過30日** # In[2]: from IPython.display import Image Image("img/pc_ratio_error.png") # # Part 2: 下載期交所30天以上選擇權Put/Call比 # In[3]: from IPython.display import Image Image("img/pc_ratio_1.png") # In[4]: from IPython.display import Image Image("img/pc_ratio_2.png") # ### 自製函式1 (date_range):切分30天以上的日期 # In[5]: def date_range(start_year, start_month, start_day, end_year, end_month, end_day): # 將開始日跟結束日轉為時間型態 start_date = date(start_year, start_month, start_day) end_date = date(end_year, end_month, end_day) # 在開始日與結束日區間內 以每30天為單位切分 不含結束日 date_list = pd.date_range(start_date, end_date, freq='30D').tolist() # 加上結束日 if date_list[-1] != end_date: date_list.append(end_date) return date_list # In[6]: date_list_sample = date_range(start_year = 2021, start_month = 1, start_day = 1, end_year = 2021, end_month = 3, end_day = 31) for day in date_list_sample: print(day) # ### 自製函式2 (pc_ratio):下載選擇權Put/Call比 # In[7]: from IPython.display import Image Image("img/pc_ratio_2.png") # In[8]: def pc_ratio(date_list): # 設定urllib物件,下載網址,儲存資料的df http = urllib3.PoolManager() url = "https://www.taifex.com.tw/cht/3/pcRatio" df = pd.DataFrame() # 下載期交所P/C比的迴圈 for idx in range(len(date_list) - 1): # 設定下載資料的起始日 queryStartDate & queryEndDate if idx == 0: start_date = date_list[idx].strftime("%Y/%m/%d") else: start_date = (date_list[idx] + timedelta(days = 1)).strftime("%Y/%m/%d") end_date = date_list[idx + 1].strftime("%Y/%m/%d") print("迴圈索引值: ", idx, "; 下載時間區間: ", start_date, "-",end_date) # 從期交所下載資料 res = http.request( 'POST', url, fields={ 'queryStartDate': start_date, 'queryEndDate': end_date } ) html_doc = res.data table = BeautifulSoup(html_doc, 'html.parser').table pc_ratio_df = pd.read_html(str(table))[3] df = df.append(pc_ratio_df, ignore_index = True) # 日期欄位資料型態從文字轉為時間 for row in range(df.shape[0]): date2 = df.iloc[row,0].split('/') df.iloc[row, 0] = datetime(int(date2[0]), int(date2[1]), int(date2[2])) # dataframe 按照日期排序 df.sort_values("日期", inplace=True, ignore_index = True) # 設定 dataframe 的欄位名稱 df.columns = ['日期', '賣權成交量', '買權成交量', '買賣權成交量比率%', '賣權未平倉量', '買權未平倉量', '買賣權未平倉量比率%'] return df # ### 用自製函式1&2: 下載期交所“30天以上”選擇權Put/Call比¶ # In[9]: date_list = date_range(start_year = 2021, start_month = 1, start_day = 1, end_year = 2021, end_month = 3, end_day = 31) for day in date_list: print(day) # In[10]: df = pc_ratio(date_list) df # # Part 3: 畫出選擇權Put/Call比 # In[11]: fig = plt.figure(figsize = (12, 5)) plt.title('Put/Call Ratio') plt.plot(df['日期'], df['買賣權成交量比率%']) plt.plot(df['日期'], df['買賣權未平倉量比率%']) plt.legend(['Volume%', 'Open Interest Volume%'])