【新手入門】Google Colab 運行 TQuant Lab 使用教學及常見錯誤

TEJ 台灣經濟新報
TEJ-API 金融資料分析
12 min readJul 10, 2024
TQuant Lab 使用教學
Photo by Jametlene Reskp on Unsplash

本文重點摘要

  • 文章難度:★☆☆☆☆
  • 在 Google Colab 的 TQuant Lab 使用教學
  • 簡易測試,選擇營收最高的五間公司(任意產業),回測報酬率
  • 安裝字型,讓 Pyfolio 套件能順利繪圖

前言

對於想使用 TQuant Lab 的同學們來說,除了原本的 GitHub 安裝教學,現在提供了一個更快速、簡潔的方式,讓我們可以在 Google Colab 上直接使用,無需設定虛擬環境,大大降低了使用門檻。

在 Google Colab 安裝 TQuant Lab 套件

只需簡單兩行代碼,完成環境設定

(因應近期 Google Colab 改版,需要新增 dask, distributed降版指令)

!pip install zipline-tej
!pip install pandas==1.5.3
!pip install dask==2.30.0 # dask 降版
!pip install distributed==2.30.0 # distributed 降版

遇到彈跳視窗顯示錯誤,直接按「重新啟動工作階段」即可

TQuant Lab 使用教學

最終運行完成會出現以下錯誤訊息,但無需理會,實際上已經可以正常使用

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
cudf-cu12 24.4.1 requires pandas<2.2.2dev0,>=2.0, but you have pandas 1.5.3 which is incompatible.
google-colab 1.0.0 requires pandas==2.0.3, but you have pandas 1.5.3 which is incompatible.

TQuant Lab 使用教學:選擇營收最高的五家半導體公司進行回測

載入常用套件

import os 
os.environ['TEJAPI_BASE'] = 'https://api.tej.com.tw'
os.environ['TEJAPI_KEY'] = 'Your_Key'
import datetime
import tejapi
import pandas as pd
import numpy as np

先找出所有是半導體及電腦產業的公司

from zipline.sources.TEJ_Api_Data import get_universe

pool = get_universe(start = '2023-07-02',
end = '2024-07-02',
mkt_bd_e = 'TSE', # 已上市之股票
stktp_e = 'Common Stock', # 普通股
sub_ind_e=['M2324 Semiconductor', 'M2325 Computer and Peripheral Equipment'])

看他們的營收,並選擇前五高的,並儲存其股票代碼

import TejToolAPI

start_time = pd.Timestamp('2023-07-02')
end_time = pd.Timestamp('2024-07-02')
data = TejToolAPI.get_history_data(start = start_time,
end = end_time,
ticker = pool,
fin_type = 'Q', # 為累計資料,舉例來說,Q3累計:1月~9月的資料。
columns = ['主產業別_中文', '常續ROE', '營業毛利率', '營運產生現金流量', '投資產生現金流量', '負債比率', 'per_tej', '營業總收入'],
transfer_to_chinese = True)
data = data.drop_duplicates(subset=['股票代碼'], keep='last').reset_index(drop=True)
data = data.nlargest(5, '營業總收入_Q') #找出最高的5間
data
TQuant Lab 使用教學
tickers = data['股票代碼'].unique()

start = '2023-01-01'
end = '2024-07-02'
os.environ['mdate'] = start + ' ' + end
os.environ['ticker'] = ' '.join(tickers) + ' ' + 'IR0001'
!zipline ingest -b tquant

將資料載入本地電腦

start = '2023-01-01'
end = '2024-07-02'

os.environ['mdate'] = start + ' ' + end
os.environ['ticker'] = ' '.join(tickers) + ' ' + 'IR0001'
!zipline ingest -b tquant
from zipline.data import bundles
bundle_data = bundles.load('tquant')
from zipline.api import *
from zipline.finance import commission, slippage
def initialize(context):
context.day = 0
context.tickers = tickers
set_slippage(slippage.VolumeShareSlippage(volume_limit = 0.025, price_impact = 0.1))
set_commission(commission.Custom_TW_Commission(min_trade_cost = 20, discount = 1.0, tax = 0.003))
set_benchmark(symbol('IR0001'))
set_liquidity_risk_management_rule(['全額交割股票(Full-Cash Delivery Securities)', '漲停股票(Limit Up)', '跌停股票(Limit Down)', '開盤即鎖死(Limited Whole Day)'])
def handle_data(context, data):
#回測第一天買進
if context.day == 0:
for ticker in context.tickers:
order_percent(symbol(ticker), 1 / len(tickers))
context.day += 1
import matplotlib.pyplot as plt
capital_base = 1e6 # 設定初始資金
def analyze(context, results):
fig = plt.figure()
ax1 = fig.add_subplot(111)
results['benchmark_cum'] = results.benchmark_return.add(1).cumprod() * capital_base
results[['portfolio_value', 'benchmark_cum']].plot(ax = ax1, label = 'Portfolio Value($)')
ax1.set_ylabel('Portfolio value (TWD)')
plt.legend(loc = 'upper left')
plt.gcf().set_size_inches(18, 8)
plt.grid()
plt.show()
from zipline import run_algorithm
start_date = pd.Timestamp('20230101', tz = 'utc')
end_date = pd.Timestamp('20240702', tz = 'utc') # 轉換成時間序列格式
results = run_algorithm(
start = start_date,
end = end_date,
initialize = initialize,
handle_data = handle_data,
analyze = analyze,
bundle = 'tquant',
capital_base = capital_base,
)
results
TQuant Lab 使用教學

使用 Pyfolio 會遇到的字型問題以及解決方式

from pyfolio.utils import extract_rets_pos_txn_from_zipline
import pyfolio as pf

# 從 results 資料表中取出 returns, positions & transactions
returns, positions, transactions = extract_rets_pos_txn_from_zipline(results) # 從 results 資料表中取出 returns, positions & transactions
benchmark_rets = results.benchmark_return # 取出 benchmark 的報酬率
# 繪製夏普比率圖
from pyfolio.plotting import plot_rolling_sharpe
plot_rolling_sharpe(returns, factor_returns=benchmark_rets)
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: Microsoft JhengHei
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: Microsoft JhengHei
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: Microsoft JhengHei
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: Microsoft JhengHei
WARNING:matplotlib.font_manager:findfont: Generic family 'sans-serif' not found because none of the following families were found: Microsoft JhengHei

即使圖表已成功繪製,但仍可能出現字體缺失的警告訊息。為了解決這個問題,我們可以自行載入字體

!wget -O MicrosoftJhengHei.ttf https://drive.google.com/uc?id=1nMlvxPOPUGkHxYD5kuP8Ur37EmKlZAW_&export=download
!wget -O ArialUnicodeMS.ttf https://drive.google.com/uc?id=1Y4O8Flv7lfrzHqOE8dkFTSctyYOpAJ0N&export=download
matplotlib.font_manager.fontManager.addfont('MicrosoftJhengHei.ttf')
matplotlib.rc('font', family='sans-serif')

matplotlib.font_manager.fontManager.addfont('ArialUnicodeMS.ttf')
matplotlib.rc('font', family='sans-serif')

再試一次後,警告訊息將不再出現

plot_rolling_sharpe(returns, factor_returns=benchmark_rets)
TQuant Lab 使用教學

結論

本次介紹,在測試的部分幾乎都參考了這篇:『巴菲特選股策略』的代碼內容,如果有任何問題,都可以查看原始延伸閱讀的內容。

另外,這次的介紹讓大家不需額外安裝虛擬環境,一大堆的設定才能使用 TQuant Lab,而是更方便的就可以開始操作,小編認為這是一個非常棒的方式,推薦大家!

Github 原始碼

延伸閱讀

相關連結

--

--

TEJ 台灣經濟新報
TEJ-API 金融資料分析

TEJ 為台灣本土第一大財經資訊公司,成立於 1990 年,提供金融市場基本分析所需資訊,以及信用風險、法遵科技、資產評價、量化分析及 ESG 等解決方案及顧問服務。鑒於財務金融領域日趨多元與複雜,TEJ 結合實務與學術界的精英人才,致力於開發機器學習、人工智慧 AI 及自然語言處理 NLP 等新技術,持續提供創新服務