最近在 Hahow 學校企業版複習之前看完的 FinLab 量化投資課程, 覺得 FinLab 搭建的股票資料庫與 Python 工具很不錯, 應該站在巨人的肩膀上往前 (錢) 看才對, 不應自己造輪子. 今天申請了 FinLab API 金鑰來測試其功能.
1. 註冊 FinLab 帳號與申請 API 金鑰 :
進入 FinLab 官網按右上角的 "登入" 鈕 :
FinLab 帳號只與 Google 帳號綁定, 按 "Sign in with Google" 選擇 Gmail 帳號綁定 :
登入成功後按右上角的登入者頭像進入訂閱方案頁面 :
新登入之使用者皆為免費帳戶, FinLab 提供免費帳戶試用每月 API 用量為 500MB 資料量額度, 在 "免費試用" 框中按 "複製" 鈕將 API 驗證碼 (權杖) 複製到記事本檔案中儲存 :
我習慣使用 dotenv 套件來取得儲存在檔案中的金鑰, 故將其儲存於目前工作目錄下的 env 檔案中 (純文字) 的 FINLAB_API :
從隱藏檔案 .env 中讀取金鑰的方法參考 :
以 dotenv 為例 :
>>> from dotenv import load_dotenv
>>> import os
>>> load_dotenv()
True
>>> token=os.environ.get('FinLab_TOKEN')
2. 安裝 finlab 套件 :
使用 pip 安裝 finlab 套件 :
D:\python\test>pip install finlab
Collecting finlab
Downloading finlab-1.2.17-cp310-cp310-win_amd64.whl.metadata (5.0 kB)
Requirement already satisfied: requests in c:\users\tony1\appdata\roaming\python\python310\site-packages (from finlab) (2.31.0)
Requirement already satisfied: numpy>=1.21.6 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from finlab) (1.24.3)
Requirement already satisfied: pandas>=1.5.3 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from finlab) (2.0.3)
Requirement already satisfied: pyarrow>=2.0.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from finlab) (13.0.0)
Collecting lz4 (from finlab)
Downloading lz4-4.3.3-cp310-cp310-win_amd64.whl.metadata (3.8 kB)
Collecting Cython (from finlab)
Downloading Cython-3.0.11-cp310-cp310-win_amd64.whl.metadata (3.2 kB)
Requirement already satisfied: tqdm in c:\users\tony1\appdata\roaming\python\python310\site-packages (from finlab) (4.66.1)
Requirement already satisfied: jinja2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from finlab) (3.1.2)
Requirement already satisfied: python-dateutil>=2.8.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas>=1.5.3->finlab) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas>=1.5.3->finlab) (2023.3)
Requirement already satisfied: tzdata>=2022.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pandas>=1.5.3->finlab) (2023.3)
Requirement already satisfied: MarkupSafe>=2.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from jinja2->finlab) (2.1.3)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->finlab) (3.2.0)
Requirement already satisfied: idna<4,>=2.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->finlab) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from requests->finlab) (1.26.19)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests->finlab) (2023.7.22)
Requirement already satisfied: colorama in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from tqdm->finlab) (0.4.6)
Requirement already satisfied: six>=1.5 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from python-dateutil>=2.8.2->pandas>=1.5.3->finlab) (1.16.0)
Downloading finlab-1.2.17-cp310-cp310-win_amd64.whl (1.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.5/1.5 MB 4.2 MB/s eta 0:00:00
Downloading Cython-3.0.11-cp310-cp310-win_amd64.whl (2.8 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.8/2.8 MB 9.5 MB/s eta 0:00:00
Downloading lz4-4.3.3-cp310-cp310-win_amd64.whl (99 kB)
Installing collected packages: lz4, Cython, finlab
Successfully installed Cython-3.0.11 finlab-1.2.17 lz4-4.3.3
檢視版本 :
>>> import finlab
>>> finlab.__version__
'1.2.17'
3. 查詢 FinLab 財經資料庫 :
用 dir() 檢視 FinLab 套件 :
>>> dir(finlab)
['LoginPanel', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'get_token', 'getpass', 'logger', 'logging', 'login', 'os', 'pkgutil']
呼叫 login() 函式並傳入 Token 即可登入 FinLab :
>>> finlab.login(token)
輸入成功!
這樣就可以從 finlab 套件匯入 data 模組來取得股票資料了 :
>>> from finlab import data
>>> type(data)
<class 'module'>
此 data 模組應該是 finlab 使用了 pkgutil 模組來延遲載入的子模組, 因此在上面用 dir(finlab) 檢視套件內容時並未出現在套件的命名空間裡, 不過它實際上是存在與可匯入的. 用下列程式碼即可看到所載入的模組內容 :
>>> import pkgutil
print([mod.name for mod in pkgutil.iter_modules(finlab.__path__)])
['analysis', 'backtest', 'cli', 'core', 'data', 'dataframe', 'ffn_core', 'market_info', 'ml', 'online', 'optimize', 'plot', 'portfolio', 'tools', 'utils']
用 dir() 檢視 data 模組內容 :
>>> dir(data)
['BytesIO', 'CacheStorage', 'FileStorage', 'Union', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_storage', 'clear', 'datetime', 'fetch_data', 'finlab', 'force_cloud_download', 'gc', 'get', 'get_bucket_name', 'get_input_args', 'get_strategies', 'has_index_name', 'has_print_free_user_warning', 'hash', 'hashlib', 'indicator', 'json', 'logger', 'logging', 'lru_cache', 'math', 'not_available_universe_stocks', 'np', 'os', 'pd', 'pickle', 'process_data', 're', 'refine_stock_id', 'role', 'search', 'set_storage', 'set_universe', 'set_us_universe', 'shutil', 'sys', 'truncate_end', 'truncate_start', 'universe', 'universe_stocks', 'us_universe', 'use_local_data_only']
其中的 get() 函式可傳入 "目錄名稱:資料庫名稱" 取得指定的財經資料, 例如要查詢證券的收盤價, 目錄為 "price", 資料庫名稱為 "收盤價", get() 會傳回一個 DataFrame :
>>> Close=data.get('price:收盤價')
Due to your status as a free user, the most recent data has been shortened or limited.
Daily usage: 25.4 / 500 MB - price:收盤價
注意, 免費帳戶每天可下載資料量為 500MB, 上面的 get() 指令已用掉 25.4MB 額度.
檢視 DataFrame 內容 :
>>> Close
symbol 0015 0050 0051 0052 ... 9955 9958 9960 9962
date ...
2007-04-23 9.54 57.85 32.83 38.40 ... 72.40 NaN 46.00 49.60
2007-04-24 9.54 58.10 32.99 38.65 ... 71.60 NaN 45.90 50.40
2007-04-25 9.52 57.60 32.80 38.59 ... 71.60 NaN 49.10 49.10
2007-04-26 9.59 57.70 32.80 38.60 ... 71.00 NaN 48.90 48.00
2007-04-27 9.55 57.50 32.72 38.40 ... 69.50 NaN 48.60 46.50
... ... ... ... ... ... ... ... ... ...
2024-12-02 NaN 191.70 77.45 188.15 ... 29.35 180.0 26.05 15.35
2024-12-03 NaN 194.30 78.05 190.90 ... 29.55 181.0 26.30 15.50
2024-12-04 NaN 195.45 78.50 192.90 ... 29.75 184.0 26.20 15.60
2024-12-05 NaN 196.50 78.65 193.80 ... 29.90 181.0 26.25 15.65
2024-12-06 NaN 195.75 78.60 192.50 ... 29.50 179.0 26.35 15.60
[4340 rows x 2554 columns]
檢視前 5 筆 :
>>> Close.head()
symbol 0015 0050 0051 0052 0053 ... 9951 9955 9958 9960 9962
date ...
2007-04-23 9.54 57.85 32.83 38.40 NaN ... 51.3 72.4 NaN 46.0 49.6
2007-04-24 9.54 58.10 32.99 38.65 NaN ... 50.5 71.6 NaN 45.9 50.4
2007-04-25 9.52 57.60 32.80 38.59 NaN ... 49.9 71.6 NaN 49.1 49.1
2007-04-26 9.59 57.70 32.80 38.60 NaN ... 49.5 71.0 NaN 48.9 48.0
2007-04-27 9.55 57.50 32.72 38.40 NaN ... 48.8 69.5 NaN 48.6 46.5
[5 rows x 2554 columns]
檢視最後 5 筆 :
>>> Close.tail()
symbol 0015 0050 0051 0052 ... 9955 9958 9960 9962
date ...
2024-12-02 NaN 191.70 77.45 188.15 ... 29.35 180.0 26.05 15.35
2024-12-03 NaN 194.30 78.05 190.90 ... 29.55 181.0 26.30 15.50
2024-12-04 NaN 195.45 78.50 192.90 ... 29.75 184.0 26.20 15.60
2024-12-05 NaN 196.50 78.65 193.80 ... 29.90 181.0 26.25 15.65
2024-12-06 NaN 195.75 78.60 192.50 ... 29.50 179.0 26.35 15.60
[5 rows x 2554 columns]
可見與 Yahoo Finance 以及 FinMind 不同的是, FinLab 的 data.get('price:收盤價') 會一次傳回所有上市股票從 2007 至今的收盤價, 但如果要取得繪製 K 線圖的其他價格例如開盤價, 最低價, 最高價, 與成交量等, 必須個別下載後再自行組裝為新的 DataFrame :
>>> Open=data.get('price:開盤價')
Daily usage: 25.5 / 500 MB - price:開盤價
>>> High=data.get('price:最高價')
Daily usage: 51.0 / 500 MB - price:最高價
>>> Low=data.get('price:最低價')
Daily usage: 76.4 / 500 MB - price:最低價
>>> Volume=data.get('price:成交股數')
Daily usage: 112.1 / 500 MB - price:成交股數
先將全部 OLCV 組成字典 (注意, mpfinance 要求欄位名稱首字母要大寫) :
>>> ohlcv={
'Open': Open[stock_id],
'High': High[stock_id],
'Low': Low[stock_id],
'Close': Close[stock_id],
'Volume': Volume[stock_id]
}
然後轉成 DataFrame :
>>> df=pd.DataFrame(ohlcv)
>>> df.head()
Open High Low Close Volume
date
2007-04-23 57.55 58.10 57.50 57.85 8571000.0
2007-04-24 57.90 58.10 57.60 58.10 2483010.0
2007-04-25 57.80 57.85 57.45 57.60 1232000.0
2007-04-26 57.95 58.00 57.55 57.70 6357000.0
2007-04-27 57.70 57.80 57.20 57.50 1070000.0
這樣就可以用切片取出指定日前範圍的價量資料 :
>>> df['2024-11-01':'2024-12-06']
Open High Low Close Volume
date
2024-11-01 186.15 190.55 185.95 190.50 21072030.0
2024-11-04 191.05 193.20 190.80 192.95 7681874.0
2024-11-05 191.55 194.70 191.40 193.65 10565332.0
2024-11-06 194.05 198.05 193.50 195.20 17354391.0
2024-11-07 194.90 198.05 194.50 197.45 13976813.0
2024-11-08 199.40 200.00 198.70 199.00 13571143.0
2024-11-11 198.85 199.10 196.80 199.10 12949097.0
2024-11-12 195.20 195.85 194.00 194.00 28057434.0
2024-11-13 193.85 194.00 192.50 192.75 9953901.0
2024-11-14 192.30 192.50 190.10 191.00 13318035.0
2024-11-15 192.05 192.85 190.85 192.35 7809314.0
2024-11-18 191.45 191.70 189.60 189.65 14637016.0
2024-11-19 190.70 192.95 190.20 192.25 7932841.0
2024-11-20 192.80 193.35 190.75 191.45 12509186.0
2024-11-21 190.00 190.15 188.60 189.35 17071862.0
2024-11-22 191.10 193.20 191.10 193.05 8291408.0
2024-11-25 194.70 194.75 192.25 192.35 8215118.0
2024-11-26 190.10 190.30 188.80 189.85 12427002.0
2024-11-27 189.15 189.45 187.00 187.10 15890418.0
2024-11-28 187.00 187.10 185.45 186.80 14338446.0
2024-11-29 184.95 188.00 184.50 187.25 8696529.0
2024-12-02 188.50 191.70 188.50 191.70 11039116.0
2024-12-03 194.30 194.85 193.75 194.30 10613810.0
2024-12-04 194.70 195.45 194.05 195.45 6981025.0
2024-12-05 195.75 196.60 195.65 196.50 8091796.0
2024-12-06 196.50 196.70 195.00 195.75 7203008.0
然後用 kbar.py 模組來畫 K 線圖, 參考 :
>>> import kbar
>>> kb=kbar.KBar(df['2024-11-01':'2024-12-06'])
>>> kb.plot(title='台灣五十 (data : FinLab)')
結果如下 :
另外, FinLab 很特別的地方是可以指定市場與產業別來取得盤後資料, 這要先呼叫 set_universe() 函式並傳入 market 與 category 參數, 例如指定上市股票中的半導體類 :
>>> data.set_universe(market='TSE', category='半導體')
Daily usage: 0.1 / 500 MB - security_categories
>>> Close=data.get('price:收盤價')
>>> Close
symbol 2302 2303 2329 2330 ... 8150 8162 8261 8271
date ...
2007-04-23 6.70 19.10 11.95 68.6 ... NaN NaN 46.8 NaN
2007-04-24 6.66 19.15 12.00 69.8 ... NaN NaN 50.0 NaN
2007-04-25 6.76 19.05 11.50 69.3 ... NaN NaN 48.8 NaN
2007-04-26 6.80 19.05 11.50 69.9 ... NaN NaN 48.4 NaN
2007-04-27 6.75 19.05 11.50 69.0 ... NaN NaN 48.8 NaN
... ... ... ... ... ... ... ... ... ...
2024-12-02 19.80 44.60 35.05 1035.0 ... 32.40 39.25 90.2 47.65
2024-12-03 19.85 44.80 36.20 1055.0 ... 32.10 38.95 90.2 47.60
2024-12-04 20.65 44.45 36.35 1070.0 ... 32.10 39.40 95.4 48.15
2024-12-05 20.35 43.60 36.30 1075.0 ... 32.40 39.20 93.1 48.30
2024-12-06 19.75 43.50 36.40 1065.0 ... 32.15 41.00 97.5 48.95
[4340 rows x 88 columns]
這樣就只傳回指定市場與產業之股票資料了.
market 參數可傳入下列值 :
- ALL:包含台股全市場的股票 (上市, 上櫃, 興櫃, 公開發行等)
- TSE:台股上市股票
- OTC:台股上櫃股票
- TSE_OTC:台股上市+上櫃的股票
- ETF:國內及國外相關的 ETF 股票
category 參數可傳入下列值 (包含 30 個產業):
光電業、其他電子業、化學工業、半導體、塑膠工業、存託憑證、建材營造
文化創意業、橡膠工業、水泥工業、汽車工業、油電燃氣業、玻璃陶瓷、生技醫療
紡織纖維、航運業、觀光事業、貿易百貨、資訊服務業、農業科技、通信網路業
造紙工業、金融、鋼鐵工業、電器電纜、電子商務、電子通路業、電子零組件
電機機械、電腦及週邊、食品工業
更多 FinLab 財經資料庫可按官網左方導覽列中的 "財經資料庫" 查詢 :
每一個資料庫都有附查詢指令, 非常方便, 右上角標 "vip" 者僅限付費帳戶可用; 而標 "free" 者則開放免費帳戶在每天總查詢量 500MB 限制下使用.
FinLab 官網的 "大盤綜合指標" 頁面網我覺得很不錯, 提供了一窺台股市場概況與台灣經濟趨勢的豐富圖表.
"Python 影音教學" 頁面則有多部實用的量化投資教學影片 :
2025-01-01 補充 :
本周重看 Hahow 企業版的 FinLab 課程, 覺得 FinLab 平台很不錯, 其教學文件網址如下 :
沒有留言 :
張貼留言