股市大事件與股價表現之糾葛— 以CVAW3.0實現

結合CVAW3.0和Jieba分詞技術結合TEJ API提供之股市重大事件觀測股價。

CVAW
Photo by Surface on Unsplash

本文重點概要

  • 文章難度:★☆☆☆☆
  • 以TEJ API提供的股市重大消息摘要進行情緒分析。

前言

現行財金新聞及相關社群不勝枚舉,新聞所蘊含之潛在價值提供資訊相對少量的投資者進行判斷,但「水能載舟,亦能覆舟。」,筆者對於新聞與股價的悄然聯結起了好奇心,因此使用了TEJ API資料庫歸納整理的公司重大事件摘要及CVAW3.0情緒指標和Jieba分詞技術來觀察其與股價可能擁有之關聯。

CVAW3.0 — 是一個含有3,553個中文辭彙的情感詞典。每個詞都擁有特定的 valence和 arousal值。其中, valence表示正面和負面情緒的程度,arousal表示平靜和興奮的程度。兩個維度的範圍從1(高度負面或平靜)到9(高度正面或興奮),本文為呈現正負面之對比感,將範圍調整自-5到4之間。

Jieba — 是Python Based 的開源中文斷詞程式。jieba使用了 HMM 模型(Hidden Markov Model)及 Viterbi 算法來辨識新詞(字典詞庫中不存在的詞)。

編輯環境與模組需求

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

資料導入

資料期間從 2022–06–01 至 2022–07–31,以台積電(2330)作為分析對象,抓取期間內重大消息,每日開盤價、收盤價、最高價、最低價。並導入CVAW3.0辭彙庫和Jieba套件進行分詞及情緒評分。

import tejapi
import jieba
import jieba.analyse
import pandas as pd
import matplotlib.pyplot as plttejapi.ApiConfig.api_key = "Your Key"
tejapi.ApiConfig.api_base="http://10.10.10.66"
tejapi.ApiConfig.ignoretz = True

首先,我們先將 CVAW3.0 下載的辭彙庫檔案引入。

cvaw3 = pd.read_csv('Your Path\cvaw3.csv',index_col='Word')

接著連接TEJ API撈取台積電(2330)的每日股價以及金融大事記。

news = tejapi.get('TWN/AWNEWS', coid='2330', mdate = {'gte':'2022-06-01','lte':'2022-07-30'} , opts = {'columns':['mdate','newstxt']})
stocks_price = tejapi.get("TWN/APRCD", coid="2330" , mdate = {'gte':'2022-06-01','lte':'2022-07-30'} , opts={'columns':['mdate','open_d','high_d','low_d','close_d']})

對照CVAW3.0辭彙庫計算Valence和Arousal值

爾後需要將對應之Valence和Arousal值存入news中,因此我們先創建四個欄位並將欄位值設為NAN。

news['Valence_Avg'] = float('nan')
news['Valence_Total'] = float('nan')
news['Arousal_Avg'] = float('nan')
news['Arousal_Total'] = float('nan')

開始計算Valence和Arousal的平均值及總和。

for i in range(len(news['newstxt'])):
seg_list = jieba.cut(news['newstxt'][i]) # Jieba套件
result=[]
sum_V = 0
sum_A = 0
count = 0
for w in seg_list : # 讀取每一行分词
if w in cvaw3.index:
result.append(w)
sum_V=sum_V+cvaw3['Valence_Mean'][str(w)]-5
sum_A=sum_A+cvaw3['Arousal_Mean'][str(w)]-5
count=count+1

if count > 0: # 紀錄筆數
news.at[i, 'Valence_Avg'] = sum_V / count
news.at[i, 'Valence_Total'] = sum_V
news.at[i, 'Arousal_Avg'] = sum_A / count
news.at[i, 'Arousal_Total'] = sum_A
else: # 分詞不在CVAW3.0 辭彙庫裡
news.at[i, 'Valence_Avg'] = 0
news.at[i, 'Valence_Total'] = sum_V
news.at[i, 'Arousal_Avg'] = 0
news.at[i, 'Arousal_Total'] = sum_A

創建六、七月的日期DataFrame。因金融大事記並非每日皆有紀錄,為了往後繪製圖形能不出錯,我們需用Merge的方式將空缺日期補上。

date_range = pd.date_range(start='2022-06-01' , end='2022-07-30' , freq='D')
full_dates = pd.DataFrame({'mdate' : date_range})

merged_data = pd.merge(full_dates, stocks_price, on='mdate', how='left')

並再將修正過的stocks_price與news合併,並指定缺失值所需填充的值。

merged_data = pd.merge(merged_data, news, on='mdate', how='left')
merged_data = merged_data.fillna({'open_d': 0, 'high_d': 0, 'low_d': 0, 'close_d': 0, 'newstxt': ''})

繪製圖形

#--------------------------繪圖--------------------------#
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(30, 8), sharex=True)
date_1 = pd.to_datetime('2022-06-01')
date_2 = pd.to_datetime('2022-07-30')

# 繪製 'Stock Prices' 子圖中的四條折線
ax1.plot(merged_data['mdate'], merged_data['open_d'], label='Open_d', color='blue')
ax1.plot(merged_data['mdate'], merged_data['close_d'], label='Close_d', color='green')
ax1.plot(merged_data['mdate'], merged_data['high_d'], label='High_d', color='red')
ax1.plot(merged_data['mdate'], merged_data['low_d'], label='Low_d', color='purple')

# 添加垂直對照線
for date in merged_data['mdate']:
ax1.axvline(x=date, color='gray', linestyle='--', linewidth=0.8)

# 添加標題和標籤
ax1.set_title('Stock Prices Over Time')
ax1.set_ylabel('Value')

# 添加 'Stock Prices' 子圖的圖例
ax1.legend()

# 繪製 'Valence_Avg' 子圖中的 Valence 折線
ax2.plot(merged_data['mdate'], merged_data['Valence_Avg'], label='Valence_Avg', color='orange')
# 添加垂直對照線
for date in merged_data['mdate']:
ax2.axvline(x=date, color='gray', linestyle='--', linewidth=0.8 )

# 添加標題和標籤
ax2.set_title('Valence Average Over Time')
ax2.set_xlabel('Date')
ax2.set_ylabel('Value')

# 添加 'Valence_Avg' 子圖的圖例
ax2.legend()

# 調整布局,以防止重疊
plt.tight_layout()

# 顯示圖形
plt.show()
輸出圖形
輸出圖型_標記

圖表分析

觀察圖形後發現,在螢光標記處,發現情緒指標與隔日股價會呈負相關,表示今日的金融大事記若為負面辭彙較多之內容,隔日價格就會有下降之趨勢,雖不是每筆資料都擁有相同的結果,但我們可以由此間接了解新聞對於投資人的影響,及其潛移默化股價可能性的程度。

原始碼

Github Gist原始碼

結語

本次實作透過 CVAW3.0 及 Jieba套件實現情緒指標與股價的微妙關係,我們僅用TEJ API所提供的有效資料,就能實作自身所想像的各類型之分析,省時又省力的情況下,也能提供投資人更多元的評估指標。

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

延伸閱讀

結合TEJAPI及LLM的對話式乖離率交易策略實作

現金增資宣告效果,以事件研究法為例

相關連結

返回總覽頁