跳到主要內容

003互動

打造神經進化交易戰隊:從賭徒到股神

讓一群隨機的交易機器人在 2024 年的蘋果股價上競爭、繁殖、突變,三十代之後報酬率 +43%,買進持有只有 +34%。親手訓練一支,再看清楚這個數字為什麼不算數。

發布
更新
閱讀時間
4 分鐘

先講結論:下面這個儀器可以在幾秒內訓練出一支交易機器人。練滿三十代,它在 2024 年的蘋果股價上賺 +43% 左右,而同一年買進之後什麼都不做只有 +34%

這個數字是真的,但它不代表機器人會交易。這篇文章有一半在講它是怎麼練出來的,另一半在講為什麼你不該相信它。先自己練一支。

fig 01/neuroevolution / trading

AAPL

2024 年 1 月 2 日 – 12 月 31 日,每日收盤價

全年漲幅
+34.90%
1601802002202402602024-012024-042024-072024-10

設定參數後按「開始訓練」。每一代都會讓整個族群把這一年交易一遍。

每個機器人從 10,000 美元開始,每天只能做一件事:買一股、賣掉最早買的那一股,或什麼都不做。報酬率把年底還沒賣的持股也用最後一天的收盤價算進去。圖上青色三角形是買入點,粉紅色是賣出點;進化曲線上的虛線是買進持有。

訓練完全在你的瀏覽器裡執行,結果會存在瀏覽器裡,下次回來還在。

它是怎麼練出來的

這裡沒有梯度,也沒有反向傳播。原因很實際:「這一年賺了多少」不是一個可以微分的目標,市場上也沒有「正確的買賣點」可以拿來當標準答案。所以改用演化:

  1. 隨機產生 50 個機器人。
  2. 讓每一個在這一年的股價上交易一遍,用年底的報酬率打分數。
  3. 留下成績最好的幾個,讓牠們兩兩混合權重、加上一點隨機突變,生出下一代;另外再補幾個全新的隨機個體,免得整個族群卡在同一種做法上。
  4. 重複。

每個機器人的大腦是一個 30 → 24 → 3 的小網路。輸入是過去 30 天每天的漲跌幅(百分比),輸出三個分數,分別代表「不動」「買」「賣」,取最高的那個:

content/posts/trading-agent/components/trading.ts
export function observe(closes: number[], day: number): Float32Array {
  const out = new Float32Array(WINDOW); // WINDOW = 30
  for (let i = 0; i < WINDOW; i++) {
    const t = day - (WINDOW - 1) + i;
    if (t >= 1) out[i] = ((closes[t] - closes[t - 1]) / closes[t - 1]) * 100;
  }
  return out;
}

儀器上的三個參數對應的就是上面的步驟:世代數是重複幾次,族群大小是每一代有幾個機器人,突變率是每個權重被隨機改動的機率。按下訓練,進化曲線一代一代往上爬,最後停在買進持有那條虛線上方九個百分點左右。

看起來牠們越來越懂這個市場。

它到底學到了什麼

我用六組不同的隨機種子各訓練了三十代(族群 50、突變率 15%,全部是儀器的預設值;只練 20 代的話是 +41.5% 到 +43.8%)。 報酬率全部落在 +42.9% 到 +43.9%,而且贏家做的事幾乎一樣:大部分的買入集中在股價還低的上半年(全年最低點是 4 月 19 日的 165 美元),到年底幾乎滿倉,中間再做幾十次小幅的高賣低買,其中八到九成是賺錢的。

2024 年蘋果整年上漲了 35%。在這種行情裡,任何「趁便宜買滿、抱到年底」的策略都會贏過「一月二日就用 185 美元買滿」。

再回頭看進化曲線的起點。六組種子的第一代,也就是完全沒有演化過的 50 個亂數機器人裡最好的那一個,已經是 +39% 到 +41%,全部在虛線上面。我另外產生了 2,000 個亂數機器人:13% 贏過買進持有,最好的一個 +41%。三十代的演化只在這上面多擠出三個百分點左右。亂猜就能贏過的基準線,說明的是這一年的行情和這套規則,不是機器人。

六組種子收斂到同一個做法,乍看像是「它找到了規律」。比較合理的解釋正好相反:這一年只有一個明顯的低點,通往高分的路都經過那裡。

同一個錯誤的三種樣子

  • 過度擬合。 演化會在歷史資料裡找到任何能提高分數的模式,不管那個模式有沒有意義。上面的 +43% 就是一個活生生的例子。
  • 只見過一種行情。 這裡只有一檔股票、一個多頭年,所以機器人養成的習慣是「買滿之後就抱著」。換成一個下跌的年份,同樣的習慣會賠得很慘。
  • 沒見過的事不可能學到。 突發的新聞、政策變化、流動性消失,訓練資料裡沒發生過,機器人就沒有任何應對。

要讓這個實驗誠實一點,至少要做三件事:把資料切成訓練期和測試期,只在測試期上報成績;加入交易成本;在多檔股票、多種行情上評分。這一頁一件都沒做,所以它的數字只能拿來說明問題,不能拿來下單。

這一頁的機器人最會的,是在一段已經知道結局的歷史裡找到最好的劇本。


這篇文章最初於 2025 年 4 月發表在我的舊站。搬到這本筆記時互動元件用 TypeScript 整個重寫了;2026 年 9 月又重寫了文字,把原本放在文末的結論搬到了開頭。