理財達人競賽

Table of Contents

Hits

1. 理財達人競賽#1:回到過去

1.1. 背景

正所謂「你不理財、財不離開你」,啊不是,是「你不理財、財不理你」。很多提早實現財富自由的人都是以定期定額的方式達成目標的。有沒有想過,如果你從小六開始,連續六年每個月固定投入一筆金額到某個項目中,到現在的損益狀況會是如何呢?

為了提高各組同學的參與興趣,我打算提供每組以下資源:

  • 時光機一部
  • 虛擬貨幣 144,000: 6 年*12 個月*每個月 2000

現在,你和你的組員可以乘坐時光機回到六年前,將每個月的 2000 元分成兩筆(每筆 1000 元),各自選擇兩種投資商品,然後以試算表來計算貴組六年來的損益情形。也許你會發現,即使這六年中歷經了武漢肺炎+俄烏戰爭,只要選擇夠好的投資標的,你仍然能從這種定期定額的懶人投資法中獲取龐大的利潤。

如果你們在初賽結束後對這種作弊投資成果還滿意,不妨從現在開始,六年後你概碩班畢業正要進入職場,那時就有一筆不小財富囉。

1.2. 競賽目標

  • 成為賺最多的人: 這表示貴組獨具慧眼,能挑選出最能賺錢的投資產品
  • 成為賠最多的人: 這表示貴組具有放空潛力,以後大家要投資跟貴組反著做就對了

1.3. 競賽規則

1.3.1. 投資期限

2018 年 1 月 1 日 至 2023 年 12 月 31 日

1.3.2. 投資規則說明

  • 分兩種投資項目,每個項目每月投入 1000 元
  • 兩種投資項目中需包含至少一檔台股
  • 股票若有配股配息一律併入下月購買資金,只要基於真實數據均可列入計算(各股配息資訊需自行搜尋)
  • 假設所有股票均提供零股買賣,且零股可以小數點買進(現實中股票最低買賣單位為 1 股)
  • 假設零股交易價格與一般交易相同(現實中零股買賣價格不同於市價)
  • 選擇其他投資商品如基金、期貨、選擇權、政府公債者需請自行研究獲利計算規則
  • 為了符合懶人定期定額投資法則,六年中只能於每月 第一個交易日 買進投資商品(不可短進短出)
  • 六年中只定期買進,不進行賣出
  • 不考慮手續費、證交稅等額外因素
  • 只能選擇可持續交易六年之投資商品(即六年內未下市的投資產品)

1.4. 小組任務

1.4.1. 研究投資標的:

  • 小組討論投資項目
  • 上傳投資計劃至 Padlet,格式不拘,可以是一個 Padlet mind map、一張圖表、一個完整的 PDF/word 檔、或是兩三段文字說明

1.4.2. 搜尋資料: Google

  • 收集六年中計算每月累計資金所需資訊

1.4.3. 計算投報率:Excel / Google sheet

  • 計算每項獲利
  • 製表(範例如下)

    2024-03-27_10-34-01_2024-03-27_09-22-39.png

    Figure 1: 黃金投資記錄

    2024-03-27_10-34-38_2024-03-27_09-58-20.png

    Figure 2: 股票投資記錄

1.4.4. 資料視覺化: Google Colab + Python / Excel

  • 合併組員數據計算全部獲利
  • 繪圖

    2024-03-27_10-35-33_2024-03-27_10-35-23.png

    Figure 3: 投報率分析

1.5. 資料上傳

  1. 先到這裡登錄貴組六年後的累積財富
  2. 請各組至理財達人競賽#1填寫投資成果
  3. DEADLINE: <2024-04-04 Thu> 23:55

1.6. 奬品

1.6.1. 正投報率冠軍小組:

  • 期末成績+5
  • SNIKERS*2

    2024-03-27_11-00-26.png

    2024-03-27_11-00-26.png

1.6.2. 負投報率冠軍小組:

  • 組員期末成績+3
  • SNIKERS*1

    2024-03-27_11-00-26.png

1.7. 關於分組

好像還有很多同學是自己一組,為了降低你的負擔,建議還是找好合作組員,後續許多作業或競賽仍是以組為單位,沒作業就沒有學期成績哦….

2. 理財達人競賽#2:卷積出你的財富(CNN)

2.1. 背景

回到過去的競賽雖然讓人很有成就感,但畢竟不現實,預測未來還是比較有利可圖,那麼,理財達人競賽 PART 2 正式開始。

2.2. 小組任務

在上週的課程中,我們示範了如何利用卷積神經網路來進行股價預測實作,雖然成效有限,但至少是個開始,現在,要請貴組動手打造你們的預測模型。

探究預測失準的原因,也許可能大概的因素有

  • 參考資料不夠: 就是特徵值太少,畢竟我們只拿每日收盤價價來當成唯一的特徵值
  • 預測天數: 是拿 5 天或 10 天或 50 天當成基礎來預測下一天會更合理?
  • 訓練集與測試集的比例: 如何調整?
  • epoch: 多訓練幾回效回會好一點嗎?
  • 模型架構: 如何調整,有哪些 layer 可以玩
  • 資料標準化

請貴小組開個會討論一下,然後利用 90 分鐘(包含資料蒐集、模型建置、模型訓練) 建好你們的模型,為節省訓練時間,你們可以每個組員分頭訓練不同的模型架構,比較一下不同模型的預測能力。

最終,你的模型要能做到這件事:

  1. 輸入某支股票代號(教師等一下會公佈)
  2. 輸出這支股票未來五天的股價預測結果(各組要實際 DEMO 執行預測回報股價)

2.3. 競賽規則

2.3.1. 預測對象

待公佈

2.3.2. 預測日期

2024 年 5 月 13 日 至 2024 年 5 月 17 日

2.3.3. 評分準則

  • 計算五天中每組預測股價與當日收盤價之差異
  • 逐日統計各組 RMSE
  • 逐日公佈即時競賽狀況

2.3.4. 各組得分計算

  • 以各組 RMSE 值反向排名
  • 第 1 組 100 分
  • 第 2 組 95 分
  • 第 3 組 90 分
  • 第 4 組 85 分
  • 第 5 組 80 分
  • 其餘各組得分依此類推

2.4. 小組成果

各組成績以下列簡陃程式計算並以圖表呈現,每日台股收盤後由教師手動更新

 1: import numpy as np
 2: import math
 3: import matplotlib.pyplot as plt
 4: # 資料設定
 5: x = ['5/13', '5/14', '5/15', '5/16', '5/17']
 6: targ = [107.50, 107.50, 108.50, 110, 108]
 7: groups = {
 8:     '第1組': [105.1712, 108.3763, 101.7562, 105.2869, 108.5946],
 9:     '第3組': [114.5000, 120.0000, 113.5000, 118.0000, 110.0148],
10:     '第4組': [105.07, 104.30, 103.73, 103.17, 102.61],
11:     '第5組': [109, 114, 120, 113, 118],
12:     '第7組': [93.9930, 93.9738, 93.6052, 93.6210, 93.3136],
13:     '第9組': [112.55,116.03,118.13,121.25,123.14],
14: #    '第10組': [3207, 3207, 3207, 3207, 3207], 這組差太多,圖畫出來各組會失真
15:     '第12組': [101.9411, 101.5433, 101.5148, 101.7162, 101.3434]
16: 
17: }
18: 
19: # 中文字型
20: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
21: plt.rcParams['axes.unicode_minus'] = False
22: 
23: # 繪製折線圖
24: plt.figure(figsize=(8, 6))
25: for group, data in groups.items():
26:     plt.plot(x, data, linestyle='--', linewidth=2, label=group)
27: plt.plot(x, targ, color='black', linestyle='-', linewidth=3, label='實際股價')
28: plt.xlabel('日期', fontsize=16)
29: plt.ylabel('股價', fontsize=16)
30: plt.legend()
31: 
32: plt.xticks(rotation=45)
33: plt.savefig('images/2024-pred-result1.png', dpi=300)
34: 
35: # RMSE
36: diffs = {group: math.sqrt(sum((x - y) ** 2 for x, y in zip(targ, data)) / 5) for group, data in groups.items()}
37: 
38: # 排多
39: sorted_groups = dict(sorted(diffs.items(), key=lambda item: item[1]))
40: 
41: colors = plt.cm.viridis(np.linspace(0, 1, len(groups)))
42: # bar chart
43: plt.figure(figsize=(8, 6))
44: bars = plt.barh(list(sorted_groups.keys()), list(sorted_groups.values()), align='center', alpha=0.7, color=colors)
45: plt.xlabel('RMSE')
46: 
47: # 加名次
48: for bar, rank in zip(bars, range(1, len(groups)+1)):
49:     plt.text(bar.get_width(), bar.get_y() + bar.get_height()/2, f'第{rank}名', va='center')
50: 
51: plt.savefig('images/2024-pred-result-2.png', dpi=300)

2024-pred-result1.png

Figure 4: CNN 各組股價預測

2024-pred-result-2.png

Figure 5: CNN 各組預測精確程度排名

3. 理財達人競賽#3:記憶出你的財富(LSTM)

一切背景規則同理財達人競賽#2,這次使用時間序列相關的模型,你們可以用 RNN、LSTM 或是自己去研究一下 GRU 怎麼玩

3.1. 小組成果

各組成績以下列簡陃程式計算並以圖表呈現,每日台股收盤後由教師手動更新

 1: import matplotlib.pyplot as plt
 2: import numpy as np
 3: import math
 4: 
 5: # 資料設定
 6: x = ['5/13', '5/14', '5/15', '5/16', '5/17']
 7: targ = [107.50, 107.50, 108.50, 110, 108]
 8: groups = {
 9:     '曾冠瑋': [116.6510, 115.4949, 114.1296, 112.8014, 111.5725],
10:     '第1組':  [100.4786, 100.2301, 100.4846, 99.9666,  100.1632],
11:     '第3組':  [102.7566, 103.1368, 101.1603, 96.9089, 96.2285],
12:     '第7組':  [99.7970,  99.5915,  99.4426, 99.3627, 99.2382],
13:     '第9組':  [60.2819,  61.4160,  61.5905, 62.8991, 63.8587],
14:     '第13組': [63.98398 ,63.7081 ,63.010 ,62.5587, 62.6470]
15: }
16: 
17: # 中文字型
18: plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
19: plt.rcParams['axes.unicode_minus'] = False
20: 
21: # 繪製折線圖
22: plt.figure(figsize=(8, 6))
23: for group, data in groups.items():
24:     plt.plot(x, data, linestyle='--', linewidth=2, label=group)
25: plt.plot(x, targ, color='black', linestyle='-', linewidth=3, label='實際股價')
26: plt.xlabel('日期', fontsize=16)
27: plt.ylabel('股價', fontsize=16)
28: plt.legend()
29: plt.xticks(rotation=45)
30: plt.savefig('images/2024-pred-result-LSTM.png', dpi=300)
31: 
32: # RMSE
33: diffs = {group: math.sqrt(sum((x - y) ** 2 for x, y in zip(targ, data)) / 5) for group, data in groups.items()}
34: 
35: # 排多
36: sorted_groups = dict(sorted(diffs.items(), key=lambda item: item[1]))
37: 
38: colors = plt.cm.viridis(np.linspace(0, 1, len(groups)))
39: # bar chart
40: plt.figure(figsize=(8, 6))
41: bars = plt.barh(list(sorted_groups.keys()), list(sorted_groups.values()), align='center', alpha=0.7, color=colors)
42: plt.xlabel('RMSE')
43: 
44: # 加名次
45: for bar, rank in zip(bars, range(1, len(groups)+1)):
46:     plt.text(bar.get_width(), bar.get_y() + bar.get_height()/2, f'第{rank}名', va='center')
47: 
48: plt.savefig('images/2024-pred-result-LSTM-2.png', dpi=300)

2024-pred-result-LSTM.png

Figure 6: LSTM 各組股價預測

2024-pred-result-LSTM-2.png

Figure 7: LSTM 各組預測精確程度排名

Author: Yung-Chin Yen

Created: 2024-05-18 Sat 13:23