2024年12月6日 星期五

Python 學習筆記 : 用 FinLab 套件取得股票資料 (一) 盤後資訊

最近在 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 影音教學" 頁面則有多部實用的量化投資教學影片 : 


沒有留言:

張貼留言