昨日稍微介紹了為什麼要取得這些資料,今天來實作取得資料,並且寫入Table LegalDailyFutureOption
!
今天會從期交所取得:三大法人-區分期貨與選擇權二類-依日期的資料。
本日程式碼使用:d6_3LegalPersonTrade.py
我們可以下載csv檔:
https://www.taifex.com.tw/data_gov/taifex_open_data.asp?data_name=MarketDataOfMajorInstitutionalTradersDividedByFuturesAndOptionsBytheDate
觀察一下我們的內容,我們會需要用到全部的資料,因此把這些資料全部列到資料庫中。這些資料分別為:
因此資料庫的SQL碼會是:
CREATE TABLE `finance`.`LegalDailyFutureOption` (
`ID` INT NOT NULL AUTO_INCREMENT,
`TradeDate` DATE NOT NULL,
`TradeGroup` VARCHAR(10) NOT NULL,
`FutureLongQty` INT NOT NULL DEFAULT 0,
`OptionLongQty` INT NOT NULL DEFAULT 0,
`FutureLongAmount` INT NOT NULL DEFAULT 0,
`OptionLongAmount` INT NOT NULL DEFAULT 0,
`FutureShortQty` INT NOT NULL DEFAULT 0,
`OptionShortQty` INT NOT NULL DEFAULT 0,
`FutureShortAmount` INT NOT NULL DEFAULT 0,
`OptionShortAmount` INT NOT NULL DEFAULT 0,
`FutureNetQty` INT NOT NULL DEFAULT 0,
`OptionNetQty` INT NOT NULL DEFAULT 0,
`FutureNetAmount` INT NOT NULL DEFAULT 0,
`OptionNetAmount` INT NOT NULL DEFAULT 0,
`FutureLongOIQty` INT NOT NULL DEFAULT 0,
`OptionLongOIQty` INT NOT NULL DEFAULT 0,
`FutureLongOIAmount` INT NOT NULL DEFAULT 0,
`OptionLongOIAmount` INT NOT NULL DEFAULT 0,
`FutureShortOIQty` INT NOT NULL DEFAULT 0,
`OptionShortOIQty` INT NOT NULL DEFAULT 0,
`FutureShortOIAmount` INT NOT NULL DEFAULT 0,
`OptionShortOIAmount` INT NOT NULL DEFAULT 0,
`FutureOINetQty` INT NOT NULL DEFAULT 0,
`OptionOINetQty` INT NOT NULL DEFAULT 0,
`FutureOINetAmount` INT NOT NULL DEFAULT 0,
`OptionOINetAmount` INT NOT NULL DEFAULT 0,
`CreateTime` DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`));
其中把數量、金額全部預設為0
,並且不提供空值,這樣資料比較乾淨,不必額外處理異常數值狀況,直接排除0
就可以。
資料表準備好,接著就是寫入資料。
本次作法是把這個功能變成一個單獨的物件,因此建立一個名為legal_daily_future_option
的class
。並且提供屬性,讓後面比較方便取得資料:
self.title = "三大法人-區分期貨與選擇權二類-依日期"
self.url = "https://www.taifex.com.tw/data_gov/taifex_open_data.asp?data_name=MarketDataOfMajorInstitutionalTradersDividedByFuturesAndOptionsBytheDate"
self.df = None # 把資料從csv轉乘datframe
self.csv = self.get_csv_data() # 取得網路上的資料,格式為csv
其中url
保留彈性,萬一網址修改了還可以使用參數法去改。
在政府提供的資料格式為:csv
,因此建立一個get_csv_data
的功能來取得伺服器中的資料,把它存成csv
和dataframe
。雖然csv這次沒有用到,但這可以抓到資料後直接存成一個csv檔,當做資料備源,例如當格式改掉後,還有個參考依據,並補匯入資料。
因此主要的功能會在這邊:
try:
csv = requests.get(self.url)
df = pandas.read_csv(StringIO(csv.text)) # 有header
print(df) # debug
self.df = df
except Exception as exc:
print(exc)
return False
這部份跟之前類似,就不多說明。
這次把連結單獨拉出來,成為一個模組。這樣不用每次與資料庫連結時,都寫一樣的參數和方法,可直接呼叫使用,或是修改資料庫資訊,以後如果要使用Azure或是搬到其他地方,也可以直接修改這個模組,而不用動到其他程式。(我這就是滾動式進步XD)
因此建立一個叫做db_connect.py
的檔案,裡面建立之前的MySQL連線:
import pymysql
class mysql_connect:
def __init__(self) -> None:
self.db_settings = {
"host": "127.0.0.1",
"port": 3306,
"user": "root",
"password": "pwd",
"db": "finance",
}
def connect(self):
conn = pymysql.connect(**self.db_settings)
return conn
就這樣簡簡單單的完成。記住"password": "pwd"
這邊要輸入自己的密碼,其他資料也是輸入自己的連線資訊喔!
接著就是在原本的模組中,建立一個功能,用來把資料匯入MySQL中:
def insert_mysql(self) -> bool:
# 計數器:計算新增了幾筆
counter = 0
try:
# 建立connection物件
my_connt_obj = db_connect.mysql_connect()
conn = my_connt_obj.connect()
with conn.cursor() as cursor:
# 新增SQL語法
for _, row in self.df.iterrows():
trade_date = str(row[0])
cmd = f"""INSERT INTO LegalDailyFutureOption
(TradeDate, TradeGroup,
FutureLongQty, OptionLongQty,
FutureLongAmount, OptionLongAmount,
FutureShortQty, OptionShortQty,
FutureShortAmount, OptionShortAmount,
FutureNetQty, OptionNetQty,
FutureNetAmount, OptionNetAmount,
FutureLongOIQty, OptionLongOIQty,
FutureLongOIAmount, OptionLongOIAmount,
FutureShortOIQty, OptionShortOIQty,
FutureShortOIAmount, OptionShortOIAmount,
FutureOINetQty, OptionOINetQty,
FutureOINetAmount, OptionOINetAmount)
values('{"{}-{}-{}".format(trade_date[:4],trade_date[4:6],trade_date[6:])}',
'{row[1]}',
{row[2]}, {row[3]},
{row[4]}, {row[5]},
{row[6]}, {row[7]},
{row[8]}, {row[9]},
{row[10]}, {row[11]},
{row[12]}, {row[13]},
{row[14]}, {row[15]},
{row[16]}, {row[17]},
{row[18]}, {row[19]},
{row[20]}, {row[21]},
{row[22]}, {row[23]},
{row[24]}, {row[25]});"""
cursor.execute(cmd)
counter += 1
conn.commit()
except Exception as exc:
print(exc)
return False
print(f"===Finish: {counter}==")
return True
最後執行他,就大功告成囉~
會顯示的結果如下:
日期 身份別 期貨多方交易口數 選擇權多方交易口數 期貨多方交易契約金額(千元) ... 選擇權空方未平倉契約金額(千元) 期貨多空未平倉口數淨額 選擇權多空未平倉口數淨額 期貨多空未平倉契約金額淨額(千元) 選擇權多空未平倉契約金額淨額(千元)
0 20210906 自營商 41537 247258 46023473 ... 824397 6922 24371 31180664 343273
1 20210906 投信 27 2 76092 ... 0 2417 62 3763399 61
2 20210906 外資及陸資 380498 140362 372794596 ... 986546 -230431 -38464 -111817854 -499753
[3 rows x 26 columns]
===Finish: 3==
True
這篇以為一下子就可以完成,殊不知寫了很多。不過,還是無法使用網友提供建議的pandas
的to_sql
功能,等之後學會再導入吧!