選舉行情?用 TEJ API 做總統大選行情事件研究

本文重點概要

  • 文章難度:★☆☆☆☆
  • 分析大盤股價歷年總統大選行情

前言

2024 年 1 月是我國總統大選的時期,網路上充斥著選舉的相關新聞,其中也不乏將選舉代入對股市的預期,對投資人心理產生影響。然而所謂的「選舉行情」真的存在嗎?本文將運用 TEJ API 對歷年總統大選年的大盤股價進行量化分析。

編輯環境與模組需求

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

資料導入

資料期間從 1971-01-05 至 2023–12–22,抓取加權指數(Y9999)調整後收盤價進行分析比較。

import tejapi
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
tejapi.ApiConfig.api_key = "Your Key"
tejapi.ApiConfig.ignoretz = True

data = tejapi.get('TWN/APRCD1',
                coid = 'Y9999',
                paginate = True,
                chinese_column_name = True
                )
data.reset_index(inplace=True, drop=True)

紀錄歷屆總統大選選舉日時間。

election_date = [pd.Timestamp('1972-03-21', tz = 'UTC'),
                 pd.Timestamp('1978-03-21', tz = 'UTC'),
                 pd.Timestamp('1984-03-21', tz = 'UTC'),
                 pd.Timestamp('1990-03-21', tz = 'UTC'),
                 pd.Timestamp('1996-03-23', tz = 'UTC'),
                 pd.Timestamp('2000-03-18', tz = 'UTC'),
                 pd.Timestamp('2004-03-20', tz = 'UTC'),
                 pd.Timestamp('2008-03-22', tz = 'UTC'),
                 pd.Timestamp('2012-01-14', tz = 'UTC'),
                 pd.Timestamp('2016-01-16', tz = 'UTC'),
                 pd.Timestamp('2020-01-11', tz = 'UTC')]

建立選舉事件點

我們將大盤指數的收盤價與時間序列提取出來,將他們結合後製成圖表,並在圖表上標記出選舉日,以此看出大選是否真的有選舉行情出現。

提取收盤價與時間序列

close = data.loc[:,'收盤價(元)']
close_d = close.to_frame()
time = data.loc[:, '年月日']
timeline = time.to_frame()
close_d, timeline
選舉行情分析
提取的收盤價和時間序列

標記選舉日、製圖

將選舉日期輸入 target_date 中並轉成 datetime 格式。

target_date = []
for election in election_date:
    target_date.append(election)
target_date = pd.to_datetime(target_date)
target_date

將每個 target_date 中的日期都在圖中以黑虛線標記出來。

plt.figure(figsize = (24, 6))
plt.plot(timeline['年月日'], close_d['收盤價(元)'])

plt.xlim(pd.to_datetime('1995-01-01'))


for date in target_date:
    plt.axvline(x=date, color='black', linestyle='-.', linewidth=1)

plt.legend(['Closing Price'])
plt.show()
選舉行情分析
台股加權指數

其實從這邊就可以看出大選後的選舉行情行情沒有一個明顯的走向,可以說相當不一致。例如 1996 年、 2016 年的選後表現較好,2000 年、2008 年、2020 年的表現較差,不過這三年都是分別因為科技泡沫、金融風暴與新冠疫情爆發所導致的下跌,選舉年剛好都碰上這些嚴重衰退的年份,因此實在很難看出對股市的影響。

回測歷屆總統選舉後台股加權指數報酬率

我們如果想知道選前選後的某個時間區段是否有因選舉行情而被影響的話,可以利用這個函數,count_return函數會先判斷我們要的時間窗口是正幾天或是負幾天,n 為正代表往後算(預設為90),負的代表往前算,再將我們輸入的時間段設為目標,最後回傳這個時間列表的頭尾日期相減之報酬率。

def count_return(time, n = 90):
  if n < 0:
    test = tejapi.get('TWN/APRCD1',
                    coid = 'Y9999',
                      mdate = {'gte': time - pd.Timedelta(days = abs(n)), 'lte': time})
    if len(test) == 0 or (test['mdate'].iloc[-1]!= time):
      test = tejapi.get('TWN/APRCD1',
                  coid = 'Y9999',
                    mdate = {'gte': time - pd.Timedelta(days = abs(n) + 1), 'lte': time + pd.Timedelta(days = 2)})
    first_value = test['close_adj'].iloc[0]
    last_value = test['close_adj'].iloc[-1]
  else:
    test = tejapi.get('TWN/APRCD1',
                coid = 'Y9999',
                  mdate = {'gte': time, 'lte': time + pd.Timedelta(days = n)})
    if len(test) == 0 or (test['mdate'].iloc[0]!= time):
      test = tejapi.get('TWN/APRCD1',
                  coid = 'Y9999',
                  mdate = {'gte': time - pd.Timedelta(days = 2), 'lte': time + pd.Timedelta(days = n + 1)})
    first_value = test['close_adj'].iloc[0]
    last_value = test['close_adj'].iloc[-1]
  final = ((last_value - first_value) / first_value) * 100
  return round(final, 2)

利用這個函數,我們就可以進行總統大選的回測。將選前與選後的目標天數設定好後,輸入進字串。

data_last_90 = []
data_last_60 = []
data_last_30 = []
data_last_7 = []
data_7 = []
data_30 = []
data_60 = []
data_90 = []
data_180 = []

for i in range(7):
    data_last_90.append(count_return(election_date[i], n = -90))
    data_last_60.append(count_return(election_date[i], n = -60))
    data_last_30.append(count_return(election_date[i], n = -30))
    data_last_7.append(count_return(election_date[i], n = -7))
    data_7.append(count_return(election_date[i], n = 7))
    data_30.append(count_return(election_date[i], n = 30))
    data_60.append(count_return(election_date[i], n = 60))
    data_90.append(count_return(election_date[i], n = 90))
    data_180.append(count_return(election_date[i], n = 180))

選舉行情分析

製成表格。

frame = {
    '前90天': data_last_90,
    '前60天': data_last_60,
    '前30天': data_last_30,
    '前7天': data_last_7,
    '後7天': data_7,
    '後30天': data_30,
    '後60天': data_60,
    '後90天': data_90,
    '後180天': data_180
}

years = ['1996', '2000', '2004', '2008', '2012', '2016', '2020']
df = pd.DataFrame(frame, index = years)
df
選舉行情分析
選舉日前(後)各個時間段的報酬率變化

上圖呈現的是選舉日前後某些固定天數的漲跌幅列表,可以看到在選後 30 天內有一個短線上漲的趨勢,直到第 30 天左右達到最大值,之後股市便走向疲弱,一路走跌到選舉後 180 天,甚至在第 200 天也是常見超過 -10%的跌幅,筆者推測這是由於大選皆集中在 Q1 ,適逢消費旺季和農曆過年行情,而歷史上經濟衰退年例如 2000 年和 2008 年的衰退段都在 Q3 左右,與大選年重合,才造成如此現象。

fig, axs = plt.subplots(2, 2, figsize=(10, 8))

axs[0, 0].plot(timeline['年月日'], close_d['收盤價(元)'])
axs[0, 0].set_xlim(election_date[0] - pd.Timedelta(days=60), election_date[0] + pd.Timedelta(days=180))
axs[0, 0].set_ylim(4500, 7000)
axs[0, 0].set_title('1996')
axs[0, 1].plot(timeline['年月日'], close_d['收盤價(元)'])
axs[0, 1].set_xlim(election_date[1] - pd.Timedelta(days=60), election_date[1] + pd.Timedelta(days=180))
axs[0, 1].set_ylim(7000, 11000)
axs[0, 1].set_title('2000')
axs[1, 0].plot(timeline['年月日'], close_d['收盤價(元)'])
axs[1, 0].set_xlim(election_date[3] - pd.Timedelta(days=60), election_date[3] + pd.Timedelta(days=180))
axs[1, 0].set_ylim(5000, 10000)
axs[1, 0].set_title('2008')
axs[1, 1].plot(timeline['年月日'], close_d['收盤價(元)'])
axs[1, 1].set_xlim(election_date[6] - pd.Timedelta(days=60), election_date[6] + pd.Timedelta(days=180))
axs[1, 1].set_ylim(8500, 13000)
axs[1, 1].set_title('2020')

# 只顯示月份
for ax in axs.flatten():
    ax.plot(timeline['年月日'], close_d['收盤價(元)'])
    ax.xaxis.set_major_formatter(mdates.DateFormatter('%m'))
    ax.xaxis.set_major_locator(mdates.MonthLocator())

    # 垂直線
    for date in target_date:
        ax.axvline(x=date, color='black', linestyle='-.', linewidth=1)

plt.tight_layout()
plt.show()
選舉行情分析
除了1996 年,另外三年選舉年皆碰上衰退年,在選舉後半年內都有股市下跌的趨勢

結論

從數據上來看,選舉後股市在短線上確實有小許的漲勢,但介入的時機點變得很重要,就算以更詳細的統計數據來看,這些資料也不足以提高太多的勝率,無法單靠選舉行情做主要決策。而從長線上來看,選舉只是一個持有期間必經的單獨事件,對台股的影響程度極小,最好還是回歸公司基本面、護城河等等考慮為佳。

本次實作透過 TEJ API 實現總統大選行情事件分析,我們僅用 TEJ API 所提供的有效資料,就能實作自身所想像的各類型之分析,省時又省力的情況下,也能提供投資人更多元的評估指標。選購 TEJ E-Shop 的相關方案,用高品質的資料庫,建構出適合自己的交易策略。

溫馨提醒,本次策略僅供參考,不代表任何商品或投資上的建議

Github 原始碼

總統大選行情事件研究

延伸閱讀

相關連結

返回總覽頁