【新手入門】TQuant Lab 新手上路

TEJ 台灣經濟新報
TEJ-API 金融資料分析
15 min readAug 29, 2023

介紹 TQuant Lab 回測平台

Photo by Talha Hassan on Unsplash

本文關鍵字: TQuant Lab、量化交易、程式交易、回測

本文重點概要

  • 文章難度:★☆☆☆☆
  • TQuant Lab 回測平台介紹。
  • TQuant Lab 使用方法演示。

前言

TQuant Lab 為 TEJ 以知名 Zipline 為底層所延伸開發之回測平台。TQuant Lab 所有證券相關資訊皆來自 TEJ 獨家提供的資料庫,保障使用資料的高質量;此外,由於以 Zipline 為基底開發,程式架構已經過多年第三方驗證,確保程式上的正確性;第三,TQuant Lab 針對不同交易限制與成本皆有參數可供調整,方便使用者打造最擬真的交易環境。若有興趣者,歡迎與我們聯繫以獲得更多資訊。

模組安裝

TQuant Lab 提供 Windows, Mac OS 與 Google Colab 三種作業系統或環境的安裝。安裝模組前請務必預先安裝 Anaconda,Anaconda 安裝教學可以參考 Anaconda介紹及安裝教學

YML 安裝

請預先下載下列安裝包:

開啟 Anaconda prompt 並且輸入以下程式碼,建立虛擬環境並安裝所需模

Window 使用者
# 將下載好的 zipline-tej.yml 檔案放在以下路徑中
$ cd <C:\Users\username\Downloads>
# 創建虛擬環境
$ conda env create -f zipline-tej.yml
# 開啟虛擬環境
$ conda activate zipline-tej

Mac 使用者
# 將下載好的 zipline-tej.yml 檔案放在以下路徑中
$ cd <C:\Users\username\Downloads>
# 創建虛擬環境
$ conda env create -f zipline-tej_mac.yml
# 開啟虛擬環境
$ conda activate zipline-tej

手動安裝

若您對於 Python 相當孰悉,也可以手動創建虛擬環境,並逐一安裝所需的依賴包。

# create virtual env
$ conda create -n <env_name> python=3.8

# activate virtual env
$ conda activate <env_name>

# download dependency packages
$ conda install -c conda-forge -y ta-lib
$ conda install -y notebook=6.4.11
$ conda install -c conda-forge nb_conda_kernels
$ conda install -y xlrd=2.0.1
$ conda install -y openpyxl=3.0.9
$ pip install zipline-tej

Google Colab 安裝

由於 TQuant Lab 目前僅支持 Python 3.8 版本,因此先透過下方程式碼新增 Python 3.8 的執行階段。

!wget -O mini.sh https://repo.anaconda.com/miniconda/Miniconda3-py38_4.8.2-Linux-x86_64.sh
!chmod +x mini.sh
!bash ./mini.sh -b -f -p /usr/local
!conda install -q -y jupyter
!conda install -q -y google-colab -c conda-forge
!python -m ipykernel install --name "Python3.8" --user
!rm mini.sh
!pip install pandas==1.2.5

接著選擇列表中的 執行階段 >> 變更執行階段類型 >> 執行階段類型 中選擇 Python 3.8 >> 點擊 儲存。並執行以下程式碼,下載 zipline-tej,若出現 yfinancepandas 版本問題請無視。

!conda install -y ta-lib -c conda-forge
!pip install zipline-tej

注意,我們需要先下載 TA-lib,這樣我們才能成功下載 zipline-tej

價量資料導入

TQuant Lab 從 TEJ 建置之資料庫抓取價量資料,且以資料包 (bundle) 形式將資料存儲於 RAM 當中。我們可以透過設定環境變數決定需導入資產以及時間區間。可設定環境變數有:

  • os.environ[“TEJAPI_BASE”]: 連結 TEJ 資料庫域名。
  • os.environ[“TEJAPI_KEY”]: 識別使用者。
  • os.environ[“ticker”]: 所欲抓取資產。
  • os.environ[“mdate”]: 所欲抓取時間區間。

設置完環境變數後,使用 !zipline ingest -b tquant 將資料導入本地端的資料包,並且將資料包命名為 tquant。

import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

os.environ['TEJAPI_BASE'] = "https://api.tej.com.tw"
os.environ['TEJAPI_KEY'] = "YOUR KEY"
os.environ['ticker'] = "IR0001 2330 2337 0050 2545"
os.environ['mdate'] = "20200821 20230821"

!zipline ingest -b tquant

載入資料後,我們可以透過以下程式碼檢視所載入資料。

from zipline.data.data_portal import get_bundle
data_bundle = get_bundle(
bundle_name = 'tquant',
calendar_name = 'TEJ',
start_dt = pd.Timestamp("2020-08-21", tz = 'utc'),
end_dt = pd.Timestamp("2023-08-21", tz = 'utc')
)
data_bundle.head(10)
資料包 (bundle) 表格呈現

策略回測

於此例,我們以買入持有台積電投資策略為範例,使用 TQuant Lab 建立策略並回測,首先引入所需模組。

from zipline.api import set_slippage, set_commission
from zipline.finance import slippage, commission
from zipline.api import order, record, symbol
from zipline import run_algorithm

Initialize 函式

initialize 為構建交易策略的重要函式,會在回測開始前被呼叫一次,主要任務為設定回測環境,常見用於設定滑價或手續費。分別可以使用:

  1. zipline.api.set_slippage:
    設定滑價模式,TQuant Lab 共提供四種滑價計算方法,詳請請見 — zipline slippage
  2. zipline.api.set_commission:
    設定手續費模式,TQuant Lab 共提供三種手續費計算方法,詳請請見 — zipline commission

常見的寫法如下:

def initialize(context):
set_slippage(slippage.FixedSlippage())
set_commission(commission.PerShare(cost=0.00285))

除此之外,我們可以注意到 initialize 含有一個參數 context,context 為一個命名空間 (namespace),可以在儲存各種自定義之變數並且在每次交易日中循環呼叫。舉例來說,我們設置一個變數 (context.day = 0) 來計算交易日天數與一個變數 (context.has_ordered = False) 紀錄是否已經持有台積電股票。

def initialize(context):
context.day = 0
context.has_ordered = False
set_slippage(slippage.FixedSlippage())
set_commission(commission.PerShare(cost=0.00285))

Handle_data 函式

handle_data 為構建交易策略的重要函式,會在回測開始後每天被呼叫,主要任務為設定交易策略、下單與紀錄交易資訊。

其中 handle_data 含有兩種參數 -- context , data。 context 與上述 initialize 介紹功能相同,這裡為了記錄交易天數與否持有台積電股票,我們設定為:

def handle_data(context, data):

# 每次交易日加 1 天。
context.day += 1

# 判別是否持有台積電,請注意我們在 initialize 設定 context.has_ordered 為 False。
if not context.has_ordered:

接著我們引入交易下單函式,下單函式共有六個不同種類,請見 Zipline Order (order & order_target)Zipline Order (percent & target_percent)Zipline Order (value & target_value),這裡使用最基礎的下單函式:

zipline.api.order

買進或賣出 n 股的資產標的。

Parameters:

  • asset: zipline.assets.Asset
    欲下單之資產,請注意資料型態為 zipline 獨有的 Asset 型態。
  • amount: int
    欲下單股數。
  • limit_price: float, optional
    限價。
  • stop_price: float, optional
    停價。

加入下單函式 order(symbol(“2330”),其中 symbol(“2330”) 就是 zipline 中的 Asset 資料型態。之後,我們會將 context.has_ordered 調整成 True,此時下個交易日就不會再度下單,更改完程式如下:

def handle_data(context, data):

context.day += 1
if not context.has_ordered:

# 下單台積電股票一張 == 1000股
order(symbol("2330", 1000)

# 設定 context.has_ordered 為 True 以避免下次交易日下單
context.has_ordered = True

加入下單函式 order(symbol(“2330”),其中 symbol(“2330”) 就是 zipline 中的 Asset 資料型態。之後,我們會將 context.has_ordered 調整成 True,此時下個交易日就不會再度下單,更改完程式如下:

def handle_data(context, data):

context.day += 1
if not context.has_ordered:

# 下單台積電股票一張 == 1000股
order(symbol("2330", 1000)

# 設定 context.has_ordered 為 True 以避免下次交易日下單
context.has_ordered = True

最後為了記錄交易天數、是否持有部位與當日價格,我們使用 record 函式,其功能為記錄每個交易日的資訊並且在最終 run_algorithm 輸出的資料表中,以欄位型式加入所紀錄資訊。其程式編輯方式如下:

record(欄位名稱 = 資訊)

這裡我們紀錄當天交易天數 (context.day)、是否持有部位 (context.has_ordered) 與當天收盤價格 (data.current(symbol(“2330”), “close”)) ,其中上面所提到的 data 就是在 handle_data 中的 data, data 主要功能為保存每天股價的價量資料並且提供呼叫,於本實例我們欲紀錄當天收盤價,於是用到 data.current() 函式。

zipline.data.current

呼叫股票的當日價量資訊。

Parameters:

  • assets: zipline.asset.Asset
    所欲呼叫的股票,請注意資料型態為 zipline 獨有的 Asset 型態。
  • fields: str
    所欲呼叫的價量資訊,提供 ‘close’, ‘open’, ‘high’, ‘low’ 與 ‘volume’。

由於我們希望記錄台積電當日收盤價格,因此程式編輯如下:

def handle_data(context, data):
context.day += 1
if not context.has_ordered:
order(symbol("2330", 1000)
context.has_ordered = True

record(
trade_days = context.day,
has_ordered = context.has_ordered,
TSMC = data.current(symbol("2330"), "close")
)

Analyze 函式

analyze 主要用於回測後視覺化策略績效與風險,這裡我們以 matplotlib 繪製投組價值表與台積電股價走勢表。其中 analyze 有兩個參數 contextperf,context 就與上述相同,perf 就是最終 run_algorithm 輸出的資料表 -- results。我們可以提取裡面特定欄位來繪製圖表。此例我們匯出投資組合價值與台積電收盤價的變化圖。

import matplotlib.pyplot as plt
def analyze(context, perf):
ax1 = plt.subplot(211)
perf.portfolio_value.plot(ax=ax1,title='portfolio values')
ax2 = plt.subplot(212, sharex=ax1)
perf['TSMC'].plot(ax=ax2,title='TSMC close')
plt.gcf().set_size_inches(18, 8)
plt.show()

Run_algorithm 函式

使用上述函式進行回測,該函式會輸出 pd.DataFrame 此資料表含有投資組合的績效與風險表現。其輸入參數為:

  • start: pd.Timestamp or datetime
    回測起始日期。
  • end: pd.Timestamp or datetime
    回測結束日期。
  • initialize: callable 呼叫 initialize
    函式以用於回測。
  • capital_base: int
    初始資金額度。
  • handle_data: callable, optional 呼叫 handle_data
    函式以用於回測。
  • before_trading_start: callable, optional
    呼叫 before_trading_start 函式以用於回測。
  • analyze: callable, optional
    呼叫 analyze 函式以用於回測。
  • data_frequency: {“daily”, “minute”}, optional
    設置交易頻率。
  • bundle: str, optional
    設置回測用的 bundle。
  • trading_calendar: TradingCalendar, optional
    設置交易日曆。
  • benchmark_returns: pd.Series, optional
    設置指標報酬率。
  • treasury_returns: pd.Series, optional
    設置無風險利率。

更詳細的資訊,請見 TSMC buy and hold strategy

start_date = pd.Timestamp('2020-08-21',tz='utc')
end_date = pd.Timestamp('2023-08-21',tz='utc')

results = run_algorithm(start= start_date,
end=end_date,
initialize=initialize,
capital_base=1e6,
analyze=analyze,
handle_data=handle_data,
data_frequency='daily',
bundle='tquant'
)
analyze 函式匯出圖表
績效與風險表格

結論

本文主要目的為讓使用者了解 TQuant Lab 的使用方法,TQuant Lab 為本公司推出的量化回測平台,相較於使用者自行建立的回測平台,TQuant Lab 提供高正確率的價量資料、高準確率的績效風險計算、高擬真度的交易環境模擬。未來我們會提供更多部屬於 TQuant Lab 之交易策略文章,請持續關注並多多支持。

原始碼

延伸閱讀

相關連結

給我們鼓勵
之後會持續分享更多財金資料庫的應用
如果你的覺得今天的文章不錯,可以幫我們在下面的 掌聲 icon 點 1下
如果覺得超讚,可以按住 掌聲 icon 不放直到 50 下
有任何想法歡迎點選 留言 icon和我們討論

--

--

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

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