【TQuant 從 0 到 1 - Day 4】 回測四大架構的基本設定: Initialize的具體設定有什麼?

TQuant
Photo by Austin Distel on Unsplash

前言

TQuant Lab中的 Zipline 提供高品質、擬真的回測架構,透過四大核心函式 —— initialize、handle_data、analyze、run_algorithm,來設置回測環境,使交易策略能夠根據市場條件調整細節,如滑價與手續費,以確保回測結果更貼近真實交易。

本篇一開始會簡單介紹四大框架及應用,之後將重點放在 initialize 並進行詳細說明。

四大框架概述

initialize

initialize 是 Zipline 交易策略中的初始化函式,負責設定回測環境,常見的配置包括滑價、手續費、交易標的與基準指數(benchmark),會在回測開始前被引入。

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

另外,我們也可以利用set_slippage 設定滑價模式,以及使用set_commission 設定手續費模型,後面會簡單介紹這兩個參數設定。

from zipline.api import set_slippage, set_commission
from zipline.finance import slippage, commission
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 介紹功能相同,可以在儲存各種自定義之變數並且在每次交易日中使用。而 data 主要功能為引入每天不同股票的價量資料,例如我們可以利用 data.current取得當天開高低收價,或是 data.history取得歷史的價量資訊。

另外我們也可以使用 record 函式,其功能為記錄每個交易日的資訊並且在最終 run_algorithm 輸出的資料表中,以欄位型式加入所紀錄資訊。其程式編輯方式如下:

record( 欄位名稱 = 資訊)

以下範例為我們下單1000股台積電,並持有到到期。這裡我們紀錄當天交易天數 (context.day)、是否持有部位 (context.has_ordered) 與當天收盤價格 (data.current(symbol(“2330”), “close”))。 handle_data 內部可用的下單函式共有六個不同種類,詳情請見後續教材。

from zipline.api import order, record, symbol
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 主要用於回測的視覺化呈現,方便觀察策略績效與風險管理,會在回測結束後被呼叫。

analyze 含有兩個參數 context, perf。context的功能與上述 initialize 介紹功能相同。而 perf為最終run_algorithm輸出的資料表,因此我們可以提取裡面的特定欄位來繪製圖表。

另外我們也可以使用 record 函式,其功能為記錄每個交易日的資訊並且在最終 run_algorithm 輸出的資料表中,以欄位型式加入所紀錄資訊。其程式編輯方式如下:

record( 欄位名稱 = 資訊)

以下範例我們使用matplotlib 繪製投組價值表與台積電股價走勢表,更多詳細使用方式請見後續教材。

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

run_algorithm 負責策略回測的主要函式,是觸發回測的主要函式。

以下範例我們輸入回測的起始時間(start_date)、結束時間(end_date),填入initialize、analyze、handle_data三大函式,並設置初始資金額度(capital_base)為一百萬元,交易頻率(data_frequency)為每天。其他更多的參數及內建欄位的詳細教學請見後續教材。

from zipline import run_algorithm
import pandas as pd 

start_date = pd.Timestamp('2018-12-30',tz='utc')
end_date = pd.Timestamp('2023-05-26',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'
                       )

輸出結果如下:

Initialize 函式的使用教學

簡介完重要的四大框架,這裡將詳細介紹Initialize函式的內部參數及使用方式,較常見的是來設置交易時的滑價和手續費,以確保回測更接近真實市場情況。另外也可以額外自訂變數和參數,來儲存交易資訊。

設定滑價

set_slippage 用於設定滑價模式,Zipline 提供以下四種滑價模型:

滑價模型說明
FixedSlippage設定一個固定的價差(spread)來模擬交易成本,不能設定成交量限制
VolumeShareSlippage根據交易量佔當天總成交量的比例(volume share)來計算滑價,並考慮價格影響。
FixedBasisPointsSlippage使用固定基點(basis points)來計算滑價,並設置交易量限制。
NoSlippage不設定任何滑價

設定手續費

set_commission 用於設定手續費模型,Zipline 提供以下手續費計算方式:

手續費模型說明
NoCommission設定一個固定的價差(spread)來模擬交易成本,不能設定成交量限制
PerDollar根據交易量佔當天總成交量的比例(volume share)來計算滑價,並考慮價格影響。
PerTrade使用固定基點(basis points)來計算滑價,並設置交易量限制。
Custom_TW_Commission台灣股票市場專用,內含兩個直接成本:手續費(0.1425%)和證交稅(0.3%),同時還可以設定一個最低費用(預設是 20 元)。

1. 手續費
• 買進或賣出時皆須繳交。
• 計算方式為:成交價 × 成交股數 × 0.1425 % × 折扣(折扣預設是 1,代表無折扣)。
• 手續費有最低價格(預設是 20 元)。

2. 證交稅
• 賣出時才要繳交。
• 計算方式為:成交價 × 成交股數 × 證交稅率(證交稅率預設是 0.3%)。

以下為示範的程式碼 :

from zipline.api import set_commission
from zipline.finance import commission
def initialize(context):
    set_slippage(slippage.<其中一種slippage models>)
    set_commission(commission.<其中一種commission models>)

參數 context

context 為一個命名空間 (namespace),可以儲存自己定義的變數和參數,並且在每次交易日中不斷地呼叫出來使用。

舉例來說,我們可以設置一個變數來計算交易日天數與一個變數紀錄是否已經持有計畫買進的股票。

  • context.day = 0
    • 用於計算交易天數,初始值為0,後續隨著每次交易日增加而加一天。
  • context.has_ordered = False
    • 用於判斷是否持有交易股票,初始值為False,代表未持有股票。後續若成功下單則可將狀態改為True。

以下為示範的程式碼 :

from zipline.api import set_slippage, set_commission
from zipline.finance import slippage, commission

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

其他還有可以定義要交易的股票代碼列表,並將這些股票代碼轉換為 Zipline 可識別的 Asset 物件,方便後續交易。另外也可以設置 benchmark。

  • context.tickers = [‘1101’, ‘2330’]
    • 定義要交易的股票代碼列表。
  • context.asset = [symbol(ticker) for ticker in context.tickers]
    • 將股票代碼輸入進 context 中,並轉換為 Asset 物件。
  • set_benchmark(symbol(‘IR0001’))
    • 設定benchmark,將benchmark設為代碼為 ‘IR0001’ 的資產,即發行量加權股價報酬指數。

以下為示範的程式碼 :

from zipline.api import set_slippage, set_commission
from zipline.finance import slippage, commission

def initialize(context):
    context.tickers = ['1101', '2330']
    context.asset = [symbol(ticker) for ticker in context.tickers]
    set_slippage(slippage.FixedSlippage(spread=0.00))
    set_commission(commission.PerDollar(cost=commission_cost))
    set_benchmark(symbol('IR0001'))

總結

在這個章節,我們學會如何運用 initialize 函式設定設定滑價、手續費、交易標的與基準指數等回測參數,並透過 context 變數來儲存交易狀態,確保回測能夠順利運行。我們也在相關連結附上更進階關於TejToolAPI的說明,未來只需結合這些數據進一步分析,便能為投資決策提供更強有力的支持。讓數據為您的投資策略賦能,迎接更加精準和高效的分析體驗!

歡迎投資朋友參考,之後也會持續介紹使用 TEJ 資料庫來建構各式指標,並回測指標績效,所以歡迎對各種交易回測有興趣的讀者,選購 TQuant Lab 的相關方案,用高品質的資料庫,建構出適合自己的交易策略。
溫馨提醒,本次分析僅供參考,不代表任何商品或投資上的建議。

【TQuant Lab 回測系統】解決你的量化金融痛點

全方位提供交易回測所需工具

下一篇 -【TQuant 從 0 到 1 – Day 5】(連結待補)

延伸閱讀

【TQuant 從 0 到 1 – Day 1】 量化交易入門神器:用 TQuant Lab 讓錢自己來敲門,小白秒變量化大神!

【TQuant 從 0 到 1 – Day 2】 避開量化交易的隱形殺手:用 TQuant Lab 精準控制手續費與滑價,讓策略更勝一籌!

【TQuant 從 0 到 1 – Day 3】打造投資數據全視角:股票池篩選與 TejToolAPI 資料獲取

相關連結

返回總覽頁
Procesing