用requests及pandas工具將台灣證交所及期交所的日大盤報價及選擇權報價抓取下來。
程式碼以及output都可以在本文最下方的github連結中找到。本文分為三部分,(1)抓取選擇權報價;(2)抓取台指大盤報價;(3)將選擇權及台指大盤報價合併。
(1)抓取選擇權報價
首先是抓取期交所的選擇權日資料,不過原始網址無法直接設定查詢日期等參數,故需要在requests
中的data
設定參數,當中的參數設定可以用鍵盤的F12
查詢到更加詳細網址所傳達的內容。
# 使用到的套件
import pandas as pd
import numpy as np
import requests
queryDate = '2023/01/04'#選取日期
commodity_id = 'TXO'#台指選代號
MarketCode = '0'#日盤0,夜盤1
#get table
url = 'https://www.taifex.com.tw/cht/3/optDailyMarketReport' #目標網址
#擷取資料設定
payload = {'queryDate':queryDate,
'commodity_id':commodity_id,
'MarketCode':MarketCode}
data = requests.post(url, data=payload) #擷取網站內容
df = pd.read_html(data.text)[2] #轉成DataFrame
display(df)
由於抓取下來的內容有些雜亂,故需要初步整理,先是將欄位名稱重新設定,再將不需要的欄位去除。
#sort table
df.columns = df.iloc[3] #重新命名欄位名稱
df = df.iloc[4:-1,:] #擷取需要row
df['開盤價'] = df['開盤價'].replace('-', np.nan) #去除不必要的資訊
df.dropna(inplace=True) #將空值nan去除
display(df)
最後則是篩選出需要的資料。
#整理需要的資訊
df['日期'] = queryDate #日期設定
#欄位擷取
df = df[['日期', '契約', '到期月份(週別)', '履約價', '買賣權', '開盤價', '最高價', '最低價', '最後成交價',
'*盤後交易時段成交量', '*一般交易時段成交量', '*合計成交量', '*未沖銷契約量']]
display(df)
(2)抓取台指大盤報價
由於步驟相似於抓取選擇權報價的方式,故不分步驟拆開描述,但不一樣的地方是需要將民國年分轉為西元年,且需要將原先是字串(str)型態的開盤價等欄位的資料欄位,轉為浮點數(float)型態。
#目標網址
url = 'https://www.twse.com.tw/zh/indicesReport/MI_5MINS_HIST'
date = 20230114
#擷取資料設定
payload = {'date':date}
data = requests.post(url, data=payload) #擷取網站內容
import json
#用json編譯
data = json.loads(data.text)
#轉成DataFrame
df = pd.DataFrame(data['data'])
#columns重新命名
df.columns = data['fields']
df[['民國年', '月', '日']] = df['日期'].str.split('/', expand=True) #將日期拆分
df['西元年'] = df['民國年'].astype(int) + 1911 #民國年+1911=西元年
df['日期'] = df['西元年'].astype(str) +'/'+ df['月'] +'/'+ df['日'] #重新將日期調整成西元格式
df = df[['日期', '開盤指數', '最高指數', '最低指數', '收盤指數']]
#資料型態轉換
df['開盤指數'] = df['開盤指數'].str.replace(',','').astype(float)
df['最高指數'] = df['最高指數'].str.replace(',','').astype(float)
df['最低指數'] = df['最低指數'].str.replace(',','').astype(float)
df['收盤指數'] = df['收盤指數'].str.replace(',','').astype(float)
display(df)
(3)將選擇權及台指大盤報價合併
首先是將抓取選擇權及大盤報價的程式碼變成函示庫。
def option_data(queryDate, commodity_id, MarketCode):
# queryDate = '2023/01/04'#選取日期
# commodity_id = 'TXO'#台指選代號
# MarketCode = '0'#日盤0,夜盤1
#get table
url = 'https://www.taifex.com.tw/cht/3/optDailyMarketReport' #目標網址
payload = {'queryDate':queryDate,
'commodity_id':commodity_id,
'MarketCode':MarketCode}
data = requests.post(url, data=payload) #擷取網站內容
df = pd.read_html(data.text)[2] #轉成DataFrame
#sort table
df.columns = df.iloc[3] #重新命名欄位名稱
df = df.iloc[4:-1,:] #擷取需要row
df['開盤價'] = df['開盤價'].replace('-', np.nan) #去除不必要的資訊
df.dropna(inplace=True) #將空值nan去除
#整理需要的資訊
df['日期'] = queryDate
df = df[['日期', '契約', '到期月份(週別)', '履約價', '買賣權', '開盤價', '最高價', '最低價', '最後成交價',
'*盤後交易時段成交量', '*一般交易時段成交量', '*合計成交量', '*未沖銷契約量']]
return df
def TWSE_data(date):
url = 'https://www.twse.com.tw/zh/indicesReport/MI_5MINS_HIST'
# date = 20230104
payload = {'date':date}
data = requests.post(url, data=payload) #擷取網站內容
data = json.loads(data.text)
df = pd.DataFrame(data['data'])
df.columns = data['fields']
df[['民國年', '月', '日']] = df['日期'].str.split('/', expand=True) #將日期拆分
df['西元年'] = df['民國年'].astype(int) + 1911 #民國年+1911=西元年
df['日期'] = df['西元年'].astype(str) +'/'+ df['月'] +'/'+ df['日'] #重新將日期調整成西元格式
df = df[['日期', '開盤指數', '最高指數', '最低指數', '收盤指數']]
df['開盤指數'] = df['開盤指數'].str.replace(',','').astype(float)
df['最高指數'] = df['最高指數'].str.replace(',','').astype(float)
df['最低指數'] = df['最低指數'].str.replace(',','').astype(float)
df['收盤指數'] = df['收盤指數'].str.replace(',','').astype(float)
return df
import pandas as pd
import numpy as np
import requests
import json
option = option_data('2023/01/04', 'TXO', '0')
display(option)
TWSE = TWSE_data('20230104')
display(TWSE)
接著是根據選擇權報價的"日期"欄位,將大盤報價合併上去。
#將大盤報價合併到選擇權資料
data = pd.merge(option, TWSE, on='日期', how='left')
#可以找到價平附近的資料
data['收盤差距'] = abs(data['履約價'].astype(float) - data['收盤指數'])
data
由於選擇權報價資料有很多合約,故可以先根據選擇權價平附近的報價做初步搜尋。
data.loc[data['收盤差距']<200]#找價平附近的報價
本文程式碼在
https://github.com/MinKuanIsHere/OptionPricing/blob/main/TaiwanOptionQuoteAndIndexQuote.ipynb