Table of Contents
MACD代表“移動平均收斂/發散指標”(Moving Average Convergence Divergence),是一種常用於技術分析的工具,用於衡量一個資產的趨勢變化和動能。
MACD由兩個主要組件組成:
MACD的計算步驟如下:
MACD的值可以是正值、負值或零,它們之間的相對位置和變化提供了一些關於資產價格趨勢的信息。
主要的MACD信號包括:
此外,MACD的柱狀圖(MACD柱)是快線與慢線之間差值的表示,柱的高度顯示了快線和慢線之間的差異。當MACD柱由負變成正,可能暗示著趨勢可能正在轉為上升。
本文使用 Mac 作業系統以及 jupyter notebook 作為編輯器。
在進入文章主軸之前,我們先傳入域名與金鑰,接著進行資料導入,
本篇實作使用台積電(2330)作為範例,並設定時間區段為 2018/12/30 ~ 2023/05/26 。
import os
import pandas as pd
import numpy as np
os.environ['TEJAPI_BASE'] = 'https://api.tej.com.tw'
os.environ['TEJAPI_KEY'] = 'your_key'
os.environ['mdate'] = '20181230 20230526'
os.environ['ticker'] = '2330'
# 使用 ingest 將股價資料導入暫存,並且命名該股票組合 (bundle) 為 tquant
!zipline ingest -b tquant
import talib
from zipline.api import order_target, record, symbol
from zipline.finance import commission, slippage
import matplotlib.pyplot as plt
首先,我們先建立 initialize 函式inintialize
函式用於定義交易開始前的交易環境,與此例中我們設置:
def initialize(context):
context.sym = symbol('2330')
context.i = 0
context.invested = False
context.set_commission(commission.PerDollar(cost=0.00285))
context.set_slippage(slippage.VolumeShareSlippage())
handle_data
函式用於處理每天的交易策略或行動,其中:
我們使用talib
來計算移動平均,並設定短期平均窗口期為 12 日、長期平均窗口期為 26日、MACD 線的窗口期為 9 日。
而除了預設輸出的報表資訊,我們還想記錄在交易策略執行時的收盤價、快線指數、慢線指數、是否買入、是否賣出等資訊,因此在最後的record
增加輸出欄位。
def handle_data(context, data):
trailing_window = data.history(context.sym, 'price', 35, '1d')#35 = 26 + 9
if trailing_window.isnull().values.any():
return
short_ema = talib.EMA(trailing_window.values, timeperiod = 12)
long_ema = talib.EMA(trailing_window.values, timeperiod = 26)
dif = short_ema - long_ema
MACD = talib.EMA(dif, timeperiod = 9)
bar = dif - MACD
buy = False
sell = False
# Trading logic
#condition1
if (dif[-2] < MACD[-2]) and (dif[-1] > MACD[-1]) and (bar[-2] < 0) and (bar[-1] > 0):
order_target(context.sym, 1000)
context.invested = True
buy = True
#condition2
elif (dif[-2] > MACD[-2]) and (dif[-1] < MACD[-1]) and (bar[-2] > 0) and (bar[-1] < 0) and context.invested:
order_target(context.sym, 0)
context.invested = False
sell = True
# Save values for later inspection
record(TSMC = data.current(symbol('2330'), 'close'),
dif = dif[-1],
MACD = MACD[-1],
bar = bar[-1],
buy = buy,
sell = sell)
在analyze
中使用 matplotlib.pyplot 繪製 投資組合價值折線圖 與 MACD 指標圖。
我們計畫輸出兩張圖表,第一張為投資組合價值折線圖,負責記錄投資組合價值的變化趨勢;第二張為 MACD 指標圖,負責記錄 快線、慢線、MACD柱的趨勢變化,以及買賣點的標記。
# Note: this function can be removed if running
# this algorithm on quantopian.com
def analyze(context=None, results=None):
import matplotlib.pyplot as plt
import logbook
logbook.StderrHandler().push_application()
log = logbook.Logger('Algorithm')
fig = plt.figure()
ax1 = fig.add_subplot(211)
results.portfolio_value.plot(ax=ax1)
ax1.set_ylabel('Portfolio value (TWD)')
ax2 = fig.add_subplot(212)
ax2.set_ylabel('MACD')
# If data has been record()ed, then plot it.
# Otherwise, log the fact that no data has been recorded.
if 'dif' in results and 'MACD' in results:
results[['dif', 'MACD']].plot(ax=ax2)
ax2.plot(
results.index[results["buy"] == True],
results.loc[results["buy"] == True, 'MACD'],
'^',
markersize=10,
color='m',
)
ax2.plot(
results.index[results["sell"] == True],
results.loc[results["sell"] == True, 'MACD'],
'v',
markersize=10,
color='k',
)
ax3 = ax2.twinx()
colors = ["red" if i > 0 else "green" for i in results['bar']]
ax3.bar(results.index, results['bar'], color=colors, alpha=0.5, width=0.4, label='MACD Bar')
lines, labels = ax2.get_legend_handles_labels()
bars, bar_labels = ax3.get_legend_handles_labels()
ax2.legend(lines + bars, labels + bar_labels, loc='upper right')
plt.gcf().set_size_inches(18, 8)
else:
msg = 'TSMC - dif and MACD data not captured using record().'
ax2.annotate(msg, xy=(0.1, 0.5))
log.info(msg)
plt.show()
使用 run_algorithm
執行上述所編撰的交易策略,設置交易期間為 2018-12-30 到 2023-05-26,初始資金為 100,000 元,所使用資料集為 tquant,其中輸出的變數 results 就是每日績效與交易的明細表。
from zipline import run_algorithm
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'
)
由上述報表中,我們可以看到投組價值約增加了百分之三十,而經由MACD 指標圖可以明確了解每個交易動作的時間點及趨勢表現。透過TQuant Lab,能大幅度的減少程式碼的複雜度,使用少量程式碼即可實現複雜回測系統。然而需要注意的是,雖然MACD是一個流行的技術分析工具,但它並非絕對可靠,單獨使用可能會產生虛假的信號。通常,技術分析者會將MACD與其他指標和分析方法結合使用,以做出更準確的判斷。
溫馨提醒,本次策略與標的僅供參考,不代表任何商品或投資上的建議。之後也會介紹使用TEJ資料庫來建構各式指標,並回測指標績效,所以歡迎對各種交易回測有興趣的讀者,選購 TEJ E-Shop 的相關方案,用高品質的資料庫,建構出適合自己的交易策略。
電子報訂閱