TQuant Lab 阿隆指標交易策略

TQuant Lab 阿隆指標交易策略
Photo by Vlad Zaytsev on Unsplash

本文重點概要

  • 文章難度:★★☆☆☆
  • 以Aroon-up、Arron-down兩條線判斷進場、出場時機。
  • 本文改編自阿隆指標,以 TQuant Lab 回測平台撰寫交易策略並回測風險與績效。

前言

阿隆指標(Aroon Indicator)是一種用於測量金融市場趨勢強度和方向的技術分析工具。它由 Tushar Chande 於 1995 年開發。該指標由兩條線組成,即Aroon Up 和 Aroon Down。

  • Aroon Up:(窗口天數 − 上一次最高高點距今天數) / 窗口天數 × 100
    該線測量給定時間段內自最高高點以來的周期數。它反映了上漲趨勢的強度。當 Aroon Up 線接近 100 時,表示強勁的上漲趨勢。
  • Aroon Down:(窗口天數 − 上一次最低低點距今天數) / 窗口天數 × 100
    該線測量給定時間段內自最低低點以來的周期數。它反映了下跌趨勢的強度。當 Aroon Down 線接近 100 時,表示強勁的下跌趨勢。

阿隆指標的取值範圍在0到100之間。當 Aroon Up 高於 Aroon Down 時,表明上漲趨勢占優勢;當 Aroon Down 高於 Aroon Up 時,表示下跌趨勢占優勢。交易者和分析師利用這些信息來識別潛在的趨勢變化,因為兩條線的交叉可能預示著市場方向的轉變。

交易策略

當 Aroon Up 大於 80 且 Aroon Down 小於 45 時,表示目前上漲趨勢高,視為進場的訊號,以隔日開盤價買入一單位。

當 Aroon Up 小於 45 、 Aroon Down 大於 55 且 兩指標相差大於 15 時,視為接下來有可能股價跌落的訊號,以隔日開盤價拋售持有部位。

當 Aroon Up 大於 55 、 Aroon Down 小於 45 且 兩指標相差大於 15 時,以及滿足本金充足時,則繼續加碼一單位。

編輯環境與模組需求

本文使用 Mac 作業系統以及 jupyter notebook 作為編輯器。

資料導入

資料期間從 2018–01–01 至 2020–12–31,以電子股:鴻海精密(2317)、仁寶電腦(2324)、國巨(2327)、台積電(2330)、聯強(2347)、宏碁(2353)、鴻準(2354)、華碩(2357)、瑞昱(2379)、廣達(2382)、研華(2395) 作為實例,抓取未調整的開、高、收、低價格資料,並以報酬指數(IR0001)作為大盤進行績效比較。

import os
import pandas as pd
import numpy as np
import tejapi
os.environ['TEJAPI_KEY'] = 'Your key'os.environ['TEJAPI_BASE'] = "https://api.tej.com.tw"
os.environ['mdate'] = '20180101 20201231'
os.environ['ticker'] = 'IR0001 2317 2324 2327 2330 2347 2353 2354 2357 2379 2382 2395'
!zipline ingest -b tquant
from zipline.api import set_slippage, set_commission, set_benchmark, attach_pipeline, order, order_target, symbol, pipeline_output, record
from zipline.finance import commission, slippage
from zipline.data import bundles
from zipline import run_algorithm
from zipline.pipeline import Pipeline, CustomFactor
from zipline.pipeline.filters import StaticAssets, StaticSids
from zipline.pipeline.factors import BollingerBands, Aroon
from zipline.pipeline.data import EquityPricing
from zipline.pipeline.mixins import LatestMixin
from zipline.master import run_pipeline

設定 Benchmark

首先,我們先載入 bundle 資料,接著抓取大盤資料(coid : IR0001)作為 benchmark。

bundle = bundles.load('tquant')
ir0001_asset = bundle.asset_finder.lookup_symbol('IR0001',as_of_date = None)

建立 Pipeline 函式

Pipeline() 提供使用者快速處理多檔標的的量化指標與價量資料的功能,於本次案例我們用以處理:

  • Aroon-up、Aroon-down指標計算(內建 factor函式:Aroon
def make_pipeline():
    curr_price = EquityPricing.close.latest
    
    alroon = Aroon(inputs = [EquityPricing.low, EquityPricing.high], 
                   window_length=25, 
                   mask = curr_price < 5000)
    up, down = alroon.up, alroon.down
    

    return Pipeline(
        columns = {
            'up':  up,
            'down':  down,
            'curr_price': curr_price,

        },
        screen = ~StaticAssets([ir0001_asset])
    )

建立 initialize 函式

inintialize 函式用於定義交易開始前的每日交易環境,與此例中我們設置:

  • 流動性滑價
  • 交易手續費
  • 報酬指數(IR0001)作為基準
  • 將 Pipeline 導入交易流程中
def initialize(context):
    context.last_buy_price = 0
    set_slippage(slippage.VolumeShareSlippage())
    set_commission(commission.PerShare(cost=0.00285))
    set_benchmark(symbol('IR0001'))
    attach_pipeline(make_pipeline(), 'mystrategy')
    context.last_signal_price = 0

建立 handle_date 函式

handle_data 函式用於處理每天的交易策略或行動,其中:

預設交易訊號參數buysell皆為 False

  • buy: 當日指標達到買入條件時,產生買入訊號,將布林值變更為 True。
  • sell: 當日指標達到賣出條件時,產生賣出訊號,將布林值變更為 True。
def handle_data(context, data):
    out_dir = pipeline_output('mystrategy')
    for i in out_dir.index: 
        sym = i.symbol # 標的代碼
        up = out_dir.loc[i, 'up']
        down = out_dir.loc[i, 'down']
        curr_price = out_dir.loc[i, 'curr_price']

        cash_position = context.portfolio.cash
        stock_position = context.portfolio.positions[i].amount

        buy, sell = False, False

        record(
            **{
                f'price_{sym}':curr_price,
                f'up_{sym}':up,
                f'down_{sym}':down,
                f'buy_{sym}':buy,
                f'sell_{sym}':sell
            }
        )

        if stock_position == 0:
            if down < 45 and up > 80:
                order(i, 1000)
                context.last_signal_price = curr_price
                buy = True
                record(
                    **{
                        f'buy_{sym}':buy
                    }
                )              

        elif stock_position > 0:
            if (up - down) > 15 and (down < 45) and (up > 55) and (cash_position >= curr_price * 1000):
                order(i, 1000)
                context.last_signal_price = curr_price
                buy = True
                record(
                    #globals()[f'buy_{sym}'] = buy
                    **{
                        f'buy_{sym}':buy
                    }
                )

            elif (down - up > 15) and (down > 55) and (up < 45):
                order_target(i, 0)
                context.last_signal_price = 0
                sell = True
                record(
                    **{
                        f'sell_{sym}':sell
                    }
                )
            else:
                pass
        else:
            pass

建立 analyze 函式

多半用於繪製績效圖表,由於本案例將使用 pyfolio 視覺化買賣點與投組價值變化,因此將analyze函式留空。

def analyze(context, perf):
    pass

執行交易策略

使用 run_algorithm 執行上述所編撰的交易策略,設置交易期間為 2018-01-01 到 2020–12–31,所使用資料集為 tquant,初始資金為 1,000,000 元。其中輸出的 results 就是每日績效與交易的明細表。

results = run_algorithm(
    start = pd.Timestamp('2018-01-01', tz='UTC'),
    end = pd.Timestamp('2020-12-31', tz ='UTC'),
    initialize=initialize,
    bundle='tquant',
    analyze=analyze,
    capital_base=10e6,
    handle_data = handle_data
)

results
交易明細表
交易明細表

利用 pyfolio 進行視覺化

進行視覺化前,我們需要先將results中的資料細分為以下部分:

  • return: 投組每日報酬
  • positions: 持有部位資料表
  • transactions: 交易明細資料表
from pyfolio.utils import extract_rets_pos_txn_from_zipline

returns, positions, transactions = extract_rets_pos_txn_from_zipline(results)
benchmark_rets = results.benchmark_return

# 時區標準化
returns.index = returns.index.tz_localize(None).tz_localize('UTC')
positions.index = positions.index.tz_localize(None).tz_localize('UTC')
transactions.index = transactions.index.tz_localize(None).tz_localize('UTC')
benchmark_rets.index = benchmark_rets.index.tz_localize(None).tz_localize('UTC')

最後,透過pyfolio.tears.create_full_tear_sheet可以一次生成多張報表及圖表。

pyfolio.tears.create_full_tear_sheet(returns=returns,
                                     positions=positions,
                                     transactions=transactions,
                                     benchmark_rets=benchmark_rets)

原始碼

結語

本次實作透過 TQuant Lab 實現阿龍指標交易策略,相較於未使用TQuant Lab 撰寫,程式難度大幅下降,並且提供更詳細的參數設定及評估指標。

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

延伸閱讀

相關連結

返回總覽頁
Procesing