最近在 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:收盤價
>>> 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]
可見 FinLab 會一次傳回所有上市股票從 2007 至今的收盤價, 但免費帳戶每天可下載資料量為 500MB, 上面的 get() 指令已用掉 25.4MB 額度.
>>> 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]
>>> 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]
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 影音教學" 頁面則有多部實用的量化投資教學影片 :
沒有留言 :
張貼留言