2025 Q3 投資回顧

今年真的相當神奇! 經歷了上半年的創新高和倒退嚕,Q3 竟然又回神了! 不是因為買了什麼妖股、飆股,而是幾乎甚麼都沒有做,只有獲利再投入。這就是長期投資神奇之處。

大家都知道巴菲特的 95% 的財富都是 60 歲以後才獲得的。他在 60 歲之前賺了 54 億美金,目前的身價則是約 1,535 億美金 [1]。對今天的老巴來說,當初那 54 億已經不算什麼了,但是沒有當時的基礎,就沒有現在的高樓。根據公開資料,他在 10~60 歲每個年紀賺到的錢大致如下圖。

由於他在 50~59 歲這十年,比起 49 歲之前賺得多太多了,所以 50~54 歲和 55~59 歲,我把它分成兩格來畫。

我最近才嘴過老巴不行了,但他仍然是我學習的對象。我很榮幸地發現,我們的成長曲線差不多。

我在十幾歲的時候一毛都沒有賺到,只會花錢。在 20~29 歲好不容易賺到一點錢,但結個婚、買個房就所剩不多了。所以在我的圓餅圖上就是一根細細的線。

30 多歲我進入瑞昱,那時還有股票分紅,所以賺錢很快,得到了第一桶金。40 歲出頭時,我經歷了分紅費用化、金融海嘯和轉職,以至於這 10 年的複利累積不太明顯。這個時期總計有六成的獲利來自投資,四成的獲利來自薪資的結餘-也就是稅後薪資減去家用的部份。

50~54 歲這五年,賺的比整個 40 歲更多一些。雖然這 5 年已經開始投資美股大盤,但還處於摸索期,除了 buy and hold 之外,沒有其他的想法,成效也一般般。整體獲利的 46% 有來自薪資的結餘,只有 54% 來自投資,比 40 歲還低。主要原因是工作穩定,小孩自己賺錢,儲蓄率變高所致。

55~59 歲這五年,投資組合慢慢移動到以 QQQ 為重心,複利成長的效果就比較明顯了。此時的獲利只有 23% 來自工作結餘,77% 來自投資。兩者的比例從 1:1 長到了 3:1。

在這五年當中,超商茶葉蛋默默地從 10 元漲到 12、13 元,通膨和 AI 夢大幅推升了資產的價格。最大關鍵點還是 covid-19。我從死撐股市的中國市場安然退出,低接打折的美股。特別是一度跌到 -40 元的油價,讓我即使後知後覺,都想得到應該低接能源股。因此投報率相當好。

BTW,很多人應該會聯想:那老巴 在 55~60 歲是投資了什麼才大展鴻圖的呢?根據 AI 的資料,老巴 58 歲時大買可口可樂。花了 10 億美金買下 7% KO 的股權。後面眾所皆知。

時間來到 2025 年。前兩季被川普老大玩壞了。所幸 Q3 反彈,讓我這次可以輕鬆 PO 文 。目前年度獲利翻轉為 11.12 %。由於累積了一甲子功力(誤),這 10 趴也就不少了。

雖然未來怎麼樣沒有人知道,我對美股的長期發展持續樂觀看待。現在每個月定期定額買 6 次 QQQ ,以及 3 次 PFF。

買 QQQ 理由充分,無需多言。買 PFF 的原因則是為了現金流。雖然這會比 all in 少賺一些,但穩定的現金流可以讓我退休後不用賣股票換生活費。只有單筆重大支出才需要賣股。

畢竟只要有買賣就有心魔,沒有買賣沒有傷害。我要是某個月股票多賣了 1 股,那整個月吃到薯條都不會想加大。要是賣在當月最高點,可能會慶祝八次,把賺的都敗光。另外,若是為了賣個好價錢,退休了反而要看線型找賣點,這種生活我可不想要。

本季資產配置狀況,除了定期定額、股息再投入之外都不變。其中 QQQ 的比重已經過半了。又因為台幣升值,複委託的可口可樂相對折價,想賣還沒賣。其他的組合都是高成長或是高股息,沒有高不成低不就的,目前都還滿意。我們就 Q4 再研究了。

[REF]

  1. 股市大拋售億萬富豪難逃 巴菲特今年財富仍堅定成長

我讀 «人生的五種財富»

本書的作者是薩希布魯姆 (Shahil Bloom),原文書名是 “The 5 Types of Wealth"。雖然書名有點老套,內容也不是太亮眼。但有幾個地方很值得留意。首先是這個觀念:如果你的雙親已經 60 歲,你每年回家團聚一次,則在你的餘生可能只能再見到他們 15 次。假如他們活到 85 歲的話。

同理,你的好同學們,每隔兩三年聚會一次,那麼今生見面的次數可能也數得出來。我們以為明天之後還有明天,但是這些數字很快就會到了屈指可數的那一天。二十歲的年輕人還有 20 億秒的生命,從 50 歲到 80 歲就只剩 10 億秒。問題是,我們選對了終點嗎?P. 7 提到終點謬誤這個觀念。如果把時間用在不夠對的地方,那以後很可能會後悔!

一般人的人生目標都是賺大錢,根據作者的訪談,有一定的錢之後,金錢就跟快幸福感就會脫鉤。而且不論錢多錢少,每個人的賺錢目標都是現況的兩三倍。這意味著以賺錢為目標,通常最後都不會滿足!於是作者引導出五種財富的觀念,時間、社會、心理、身體、金錢。

不意外地,大標題展開之後,作者就會針對每個題目寫一些篇幅,旁徵博引,最後全書完!真正有啟發性的,我覺得還是一開始講到的那個觀念 – 來日無多,不只是你自己,還有你關心的人。

與家人相處的時光

與孩子相處的時光

與朋友相聚的時光

與伴侶相聚的時光

與同事相處的時光

獨處的時光

其他人能在你的身邊多久是種緣分,但是你肯定要跟自己相處一輩子。所以要對自己好一點。為自己設定有意義的目標,不要為了別人的眼光而盲從!

本書講到一個觀念,剛剛我在開車回家的路上,聽到一個 Youter 介紹另外一本書 « 金錢心理學» 的時候也講到。我覺得這是天意,所以我特別 highlight 一下。摩根豪瑟在 « 致富心態» 中所言:當你看到某人開著一輛好車時,你很少會想:"哇!開那輛車的人好酷。" 相反地,你會想:"哇!如果我有那輛車,人們會覺得我好酷。" (p. 60).

如果運動員表現出矯健的身手,我們自覺投胎八輩子也趕不上,自然就會覺得運動員酷!當這個東西是買來的,特別是你也有機會買得起,那就比較可能出現 “有為者亦若是" 的想法,把焦點從羨慕別人變成想要擁有,對方看似有光環,但不多。因為前者是贏來的榮耀 / 地位、後者是買來的榮耀 / 地位。(pp. 59~61) 作者當然是強調大家要追求贏來的地位。"不要購買地位,專心在贏地位,因為獎品更充實。(p.71)

既然要介紹五大主題,其中不少內容與其他書籍相似。特別是在投資方面,通常不會帶來太多新意。畢竟,如果作者同時精通健身、人際關係、時間管理、心理諮詢和投資理財,那他應該去當直播主,這樣更有機會同時獲得五方面的財富。除了和觀眾進行問答,還可以偶爾進行吃播、運動直播,分析股市,甚至提供諮詢……這樣的情景是不是太夢幻了呢,哈哈!

言歸正傳,上面那幾張圖,大家看了之後若有所感觸的話,其實作者的貢獻已經非常大了!

RAG with FAISS

RAG (Retrieval-Augmented Generation) 大家應該都知道了。至於 FAISS 是 Facebook AI Research(FAIR)開發的技術,主要用途是對海量高維度的資料作出相似度的比較。由於我是第一次看到 RAG 和 FAISS (Facebook AI Similarity Search) 一起用,所以做個筆記。

基本上 RAG 的知識庫可能是一本書、一本使用手冊、一堆 Facebook 的用戶資料等等。它們先分為不同的小段落,然後 tokenize,每個段落再 encode 為一個向量。同理,對使用者提問也做同樣的事,但此處理解為只產生一個向量。

由於知識庫的向量筆數很多, FAISS 為他們製作 Index。提問的向量用 FAISS 的函數中找出最接近的幾筆最相關的向量,再根據 index 反查出 text 原文。然後把 text 和使用者提問合在一起去問 LLM。

對 LLM 來說,它可以有自己的 tokenizer。總之,RAG 已經功成身退了。

假如不用 FAISS,純靠 Pytorch 的話,那麼要自己用 dot product 去比較相似性。因為每個 word 就可能對應到一個高維的 token,所以每個 pragraph 的向量就是所有組成 pragraph 的 word 的向量的平均值。

最後補充 DPR (Dense Passage Retriever)。顯然,它對於 question 和 context (passage) 用了兩套函數 – 所謂 dual encoder [1]。我們可以想像,對於 question 的編碼應該要力求精準,但是對於參考文件這部分,如果是一本百科全書、或是整個資料庫,那編碼時主要是求快!所以兩邊的編碼方式不太一樣、甚至 tokenizer 不太一樣 (但是相容) 應該也是合理的。

[REF]

  1. https://blog.csdn.net/qq_45668004/article/details/138256448

QQQ 股東會小筆記

QQQ 股東將於 2025 年 10 月 24 日召開特別會議。這次的股東投票,主要是表決是否將 unit investment trust (UIT) 轉為 open-end management investment company.

目前所謂的 QQQ,全名是 Invesco QQQ TrustSM, Series 1. 顯然它是 Invesco 底下的一支信託。如果投票通過,它就變成一個開放式管理投資基金(Open-End Fund),擁有自己的董事會。

它一共要投這三個提案,全部同意才能讓這個轉型成立。

  • Proposal 1: To approve amendments to the Trust’s Trust Indenture and Agreement and Standard Terms and Conditions of Trust
    (the “Governing Instruments”) that are intended to change the Trust’s classification under the Investment Company
    Act of 1940, as amended, from a unit investment trust to an open-end management investment company.
  • Proposal 2: To approve the election of nine (9) trustees to serve on the Board of Trustees of the Trust following the amendment of
    the Governing Instruments (Proposal 1) replacing the existing trustee (a bank) with a slate of individual trustees.
  • Proposal 3: To approve an investment advisory agreement between the Trust and Invesco Capital Management LLC.

然後這對我們有啥好處呢?據說可以降低費用。轉變後,信託的費用比率將從每年最高20個基點(0.20%)降低至18個基點(0.18%),預計為信託及其股東節省超過 7000 萬美元。

以 2025/8/8 那天來說,QQQ 總共有 634,150,000 股。所以每股每年可以節省 0.11 美元。也就是每擁有 9.06 股, 每年就可以多賺一塊美金;擁有 1,000 股的股東就可以多買一支耳機或是一雙運動鞋。 好像也不多就是了。

至於股東有什麼風險呢?目前能想到的風險就是,區區一支複製大盤的基金,竟然需要 9 位董事。董事不用分錢嗎?底下不用請自己會技師、分析師、工程師嗎?此外還批准 QQQ 要找 Invesco 當投資顧問,這是免費的嗎?如果他們瓜分了省下的 7000 萬,股東可能甚至沒感覺,但 Invesco 的 CEO Brian Hartigan (未來 QQQ 的董事長?) 應該就爽翻了。 However,如果他們只花 6999 萬 9999 元做這件事,身為小股東也只好認了!不要 A 太多啊!!!

Adjusted R-Squared 小整理

Adjusted R2 是 R2 的進階版, 它考慮了模型中變數 (預測因子) 的數量, 懲罰那些濫竽充數的變數, 在多變量回歸 (multiple regression ) 中達到去蕪存菁的效果.

聽起來相當美好.  但我們怎麼知道何時需要它? 要是我們的 model 已經是最好了, 再調整它是否浪費時間? 我們可以先看 R2 的破綻在哪裡?

R2 = 1 – SSR/SST

若 SSR/SST < 1, 表示這是個真分數. 當我新增一個因子, 表現得和平均 (猜的期望值) 一樣好, 真分數 (分子分母加同樣數字) 愈加愈大, R 會愈來愈小. 所以加到沒用的因子, R 會變差 (Adjusted R 變差). 反過來, 如果我們是要減少變數, 也可以預測減掉一個變數是否有感?

Adjusted R² = 1 – [(1 – R²) * (n – 1) / (n – k – 1)]

  • 如果加入的變數有貢獻 (提高解釋力), Adjusted R² 會上升.
  • 如果加入的變數無貢獻 (p-value 高, 不顯著), Adjusted R² 會下降或持平.

基本上, k 如果增加一個變數, 但它對 R2 又無額外貢獻, 分母的 (n – k – 1) 變小, … 以小學程度的數學可知 Adjusted R² 變小.

順便偷渡一下 n. n -> ∞, (n – 1) / (n – k – 1) -> 1, Adjusted R² 越接近 R² (增加變數的懲罰很小). n 越小, 分母越小, 懲罰項越大, 讓 Adjusted R² 更容易小於 R², 這能更敏感地偵測冗餘變數 (overfitting). 但因為它效力強到難以分辨 feature 好壞, 所以一般不調整 n, 只調整 k.

舉例而言, 現在要估計房價模型. 變數有坪數、屋齡、噪音 (亂數) 三個, k = 3. 統計樣本 n = 100 個. 為了說明方便, 我們先在 Python 固定亂數種子. 做出一堆可以收斂的假資料.

import statsmodels.api as sm
import pandas as pd
import numpy as np

# 步驟 1: 固定亂數種子與資料(同之前)
np.random.seed(0)
n = 100
X = pd.DataFrame({
    '坪數': np.random.uniform(20, 200, n),
    '屋齡': np.random.uniform(1, 50, n),
    '噪音': np.random.normal(0, 1, n)
})
y = 5000 * X['坪數'] - 2000 * X['屋齡'] + np.random.normal(0, 10000, n)  # real y

安裝 library ( pip install statsmodels) 後, 很多東西都不用算. 包括 OLS (Ordinary Least Squares) model 都會建好. 因為太方便了, 所以定義一個會印出過程的 function.

# 函數:計算 R²/adj_r2、係數和 p-value
def compute_and_compare(model_vars, model_name):
    X_sub = sm.add_constant(X[model_vars])  # 加常數項
    model = sm.OLS(y, X_sub).fit()          # 擬合 OLS 模型
    
    # 計算 R² 和 adj_r2
    r2 = model.rsquared
    adj_r2 = model.rsquared_adj
    print(f"\n{model_name} (變數: {model_vars}):")
    print(f"  R² = {r2:.4f}")
    print(f"  Adjusted R² = {adj_r2:.4f}")
    
    # 得到估計係數
    params = model.params
    print("  估計係數(params):")
    for var in params.index:
        print(f"    {var}: {params[var]:.2f}")
    
    # 得到每個變數的 p-value
    pvalues = model.pvalues
    print("  每個變數的 p-value(顯著性檢定):")
    for var in pvalues.index:
        print(f"    {var}: {pvalues[var]:.4f} (顯著: {pvalues[var] < 0.05})")
    
    print()  # 空行分隔

讓 3 個變數的 model A 跑一下, 然後讓除掉噪音 (random noise, 不是房子旁邊有噪音), 用只有 2 個變數的 model B 跑一下.

# 步驟 2: 計算模型 A (有噪音)
compute_and_compare(['坪數', '屋齡', '噪音'], "模型 A (有噪音)")

# 步驟 3: 計算模型 B (無噪音)
compute_and_compare(['坪數', '屋齡'], "模型 B (無噪音)")

執行上面程式, 會印出:

模型 A (有噪音) (變數: ['坪數', '屋齡', '噪音']):
  R² = 0.9745
  Adjusted R² = 0.9736
  估計係數(params):
    const: -949.47
    坪數: 4995.64
    屋齡: -2003.71
    噪音: 42.60
  每個變數的 p-value(顯著性檢定):
    const: 0.9644 (顯著: False)
    坪數: 0.0000 (顯著: True)
    屋齡: 0.0000 (顯著: True)
    噪音: 0.9655 (顯著: False)


模型 B (無噪音) (變數: ['坪數', '屋齡']):
  R² = 0.9744
  Adjusted R² = 0.9737
  估計係數(params):
    const: -947.35
    坪數: 4995.64
    屋齡: -2003.72
  每個變數的 p-value(顯著性檢定):
    const: 0.9623 (顯著: False)
    坪數: 0.0000 (顯著: True)
    屋齡: 0.0000 (顯著: True)

我們先關心 Model A 的 R² = 0.9745 > Adjusted R² = 0.9736, 或曰 Adjusted R² < , 這個訊號是提示我們的 model 可能有冗餘的變數存在! 調一調會更好! 至於誰是老鼠屎? 這時還看不出來.

但我們也印出了 p-value, 噪音的 p-value = 0.9655 很不顯著, 所以就抓它了! 在 Model B, 我們只用兩個變數.

此時 R² = 0.9744 > Adjusted R² = 0.9737 仍然成立, 或曰 Adjusted R² < 就是成立, 那這個時候戰犯要抓誰呢?

const 這個 p-value 值雖然大了點, 但是通常不會是標的. 而且坪數和屋齡的 p-value 都為 0 了, 表示極為顯著! 基本上就沒得挑了. 這也告訴我們指標並非絕對的, 要綜合起來使用.

Model B 的 R² 雖然輸給 Model A (0.9744 < 0.9745), 但我們本來就是抓 overfitting (模型在訓練資料上表現好, 但在未見過的資料上表現差), 所以不會太在意這裡掉了一點. 反而是看 Adjusted R² 從 0.9736 升到 0.9737, 還拔掉一個 p-value 很大的變數, 故改用 model B 是值得肯定的方向.