本文重點概要
- 文章難度:★★☆☆☆
- 介紹威廉指標及指標進場時機。
- 以 TQuant Lab 回測平台撰寫威廉指標策略策略並回測風險與績效。
前言
威廉指標又稱為威廉指數、wmsr 或 W%R,其英文名稱是 The Williams Percent Range,由美國知名交易員拉裏·威廉姆斯 (Larry Williams)於 1973 年所創造,是技術分析常見的指標之一。
威廉指標是最早被應用於判斷市場價格是否處於超買或超賣狀態的指標,投資人常使用的 KD 線等其它一樣用於判斷超買或超賣的指標是在威廉指標的基礎上發展出來的。
威廉指標的計算方式如下:
- (N 日最高價 - 收盤價)÷(N 日最高價 - N 日最低價)× 100% ×(-1)
根據上述公式可以得知,威廉指標的數值介於 0 到 -100 區間,當指標的數值在 0 到 -50 時,表示股價處於強勢階段;當指標的數值落在 -51 到 -100 時,表示股價處於弱勢階段。 另外,當指標數值小於 -80 ,意味著股價可能處於超賣狀態,是買入的好時機;而當指標的數值位於大於 -20 時,則表示股價可能處於超買狀態,是賣出的好時機。
此外,威廉指標的時間參數對於指標的影響程度相當大,因此投資人需要根據自己的習慣設置適合自己的參數。
威廉指標策略
本文採用威廉指標來判斷股票超買超賣的時機點,利用以下進出場規則建立交易策略並進行回測:
- 當威廉指標 ≤ -80 時買入該股票,因市場過冷,股票處於超賣階段。
- 當威廉指標 ≥ -20 時賣出該股票,因市場過熱,股票屬於超買階段。
此外,本文將 N 值設為 100 日,而非在計算威廉指標時較為常見的窗格,最後也會使用業界經常使用的14日進行回測比較。
編輯環境與模組需求
本文使用 Windows 11 以及 Jupyter Notebook 作為編輯器。
資料導入
本策略從 2021-01-01 到 2023-12-31 共三年,以電子股:鴻海精密(2317)、國巨(2327)、台積電(2330)、宏碁(2353)、華碩(2357)、廣達(2382)作為實例,並以報酬指數(IR0001)作為大盤進行績效比較。
import os os.environ['TEJAPI_KEY'] = "your key" os.environ['TEJAPI_BASE'] = "https://api.tej.com.tw" import pandas as pd import numpy as np import matplotlib.pyplot as plt from zipline.data import bundles from zipline.utils.calendar_utils import get_calendar from zipline.sources.TEJ_Api_Data import get_Benchmark_Return start = '2021-01-01' end = '2023-12-31' os.environ['ticker'] = 'IR0001 2317 2327 2330 2353 2357 2382' os.environ['mdate'] = start+' '+end !zipline ingest -b tquant
建立 Pipeline 函式
建立 Custom Factor 函數
CustomFactor 可以讓使用者自行設計所需的客製化因子,於本次案例我們用以處理:
威廉指標(Wmsr)
from zipline.data import bundles from zipline.sources.TEJ_Api_Data import get_Benchmark_Return from zipline.pipeline.mixins import SingleInputMixin from zipline.pipeline.data import TWEquityPricing from zipline.pipeline.factors import CustomFactor from zipline.pipeline import Pipeline from zipline.TQresearch.tej_pipeline import run_pipeline from zipline.pipeline.filters import StaticAssets from zipline.utils.math_utils import nanmax, nanmin class Wmsr(CustomFactor): inputs = [TWEquityPricing.close, TWEquityPricing.high, TWEquityPricing.low] window_length = 100 def compute(self, today, assets, out, close, high, low): highest_highs = nanmax(high, axis=0) lowest_lows = nanmin(low, axis=0) williams_index = ((highest_highs - close[-1]) / (highest_highs - lowest_lows)) * 100 * -1 out[:] = williams_index
Pipeline() 提供使用者快速處理多檔標的的量化指標與價量資料的功能,於本次案例我們用以處理:
- 該股票當前股價(curr_price)start_dt, end_dt = pd.Timestamp(start, tz='utc'), pd.Timestamp(end, tz='utc') bundle = bundles.load('tquant') benchmark_asset = bundle.asset_finder.lookup_symbol('IR0001',as_of_date = None) def make_pipeline(): wmsr = Wmsr() curr_price = TWEquityPricing.close.latest return Pipeline( columns = { 'curr_price':curr_price, 'Williams_index' : wmsr, }, screen = ~StaticAssets([benchmark_asset]) ) my_pipeline = run_pipeline(make_pipeline(),start_dt, end_dt) my_pipeline.tail(20)
建立 initialize 函式
initialize() 函式用於定義交易開始前的每日交易環境,與此例中我們設置:
- 滑價成本
- 台股市場手續費模型
- 加權報酬指數 ( IR0001 ) 作為 Benchmark
- 將 Pipeline 設計的威廉指標導入交易流程中from zipline.finance import slippage, commission from zipline.api import * from zipline.api import set_slippage, set_commission, set_benchmark, attach_pipeline, order, order_target, symbol, pipeline_output, record def initialize(context): 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)) attach_pipeline(make_pipeline(), 'mystrats') set_benchmark(symbol('IR0001'))
建立 handle_data 函式
handle_data() 為構建威廉指標策略的重要函式,會在回測開始後每天被呼叫,主要任務為設定交易策略、下單與紀錄交易資訊。
- 當威廉指標 ≤ -80 且當前資金 ≥ 該股票當前價格 * 1000,則購入該股。
- 當威廉指標 ≥ -20,賣出持股。def handle_data(context, data): out_dir = pipeline_output('mystrats') for i in out_dir.index: curr_price = out_dir.loc[i, 'curr_price'] w_value = out_dir.loc[i, 'Williams_index'] stock_position = context.portfolio.positions[i].amount cash_position = context.portfolio.cash if stock_position == 0 and cash_position >= curr_price * 1000: if w_value <= -80: order(i, 1000) elif stock_position > 0: if w_value <= -80 and cash_position >= curr_price * 1000: order(i, 1000) elif w_value >= -20: order_target(i, 0)
執行交易策略
使用 run_algorithm() 執行上述設定的威廉指標策略,設置交易期間為 start_dt(2021-01-01) 到 end_dt(2023-12-31),使用資料集 tquant,初始資金為一千萬元。其中輸出的 results 就是每日績效與交易的明細表。
from zipline import run_algorithm start_date = pd.Timestamp('2021-01-01',tz='utc') end_date = pd.Timestamp('2023-12-31',tz='utc') results = run_algorithm(start = start_date, end = end_date, initialize = initialize, capital_base = 1e7, handle_data = handle_data, data_frequency = 'daily', bundle = 'tquant' ) results
利用 Pyfolio 進行績效評估
import pyfolio as pf from pyfolio.utils import extract_rets_pos_txn_from_zipline returns, positions, transactions = pf.utils.extract_rets_pos_txn_from_zipline(results) benchmark_rets = results.benchmark_return # Creating a Full Tear Sheet pf.create_full_tear_sheet(returns, positions = positions, transactions = transactions, benchmark_rets = benchmark_rets, round_trips=False)
在這 34 個月中,威廉指標策略獲得 11.696% 的年化報酬,累計報酬 37.708%,獲利表現不錯,總體來說比大盤好一點;但年化波動率與最大回撤分別為 18.221% 與 -34.638%,顯示出採用威廉指標策略的市場波動風險較大。真實採用時因波動太大,無法僅依靠威廉指標進行量化交易,可以搭配前篇文章 TQuant Lab 一目均衡表策略,一套自成體系的技術分析指標所提的移動指損或是移動平均線的方式與威廉指標進行搭配,增加投資的穩定性。
此圖僅改變時間參數,亦顯示出威廉指標的時間參數對於的影響非常巨大,由於威廉指標相較其他技術指標,對價格的反應較為敏感,若僅依照快線(短天數)的威廉指標進行買賣,可能會過度頻繁操作,也容易產生誤判。
結論
本次策略使威廉指標進行回測模擬,運用指標顯示超賣時入場,超買時出場,回測結果發現與大盤相比時有獲得較多的報酬,但投資人會承受過大的市場波動風險,且時間參數對於指標影響非常巨大。因此要提醒投資人在投資時,須注意自身習慣調整為適合的參數。另外也要注意,威廉指標僅是一個技術指標,在投資時應搭配其他輔助判斷,進而增加投資的穩定性及可靠性。
之後也會持續介紹使用 TEJ 資料庫來建構各式指標,並回測指標績效,所以歡迎對各種交易回測有興趣的讀者,選購 TQuant Lab 的相關方案,用高品質的資料庫,建構出適合自己的交易策略。
溫馨提醒,本次策略僅供參考,不代表任何商品或投資上的建議。
【TQuant Lab回測系統】解決你的量化金融痛點
全方位提供交易回測所需工具
留言 0