凱利準則是一個用來計算下注規模的公式。只要輸入勝率、獲利幅度與虧損幅度,它就會傳回能讓財富長期成長率最大化的資金比例。約翰·凱利於1956年在貝爾實驗室以資訊理論的成果發表了這個公式,後來賭徒與交易員紛紛採用。本文將從基本原理推導公式,接著以十年真實的每日股票報酬來衡量公式的建議,結果發現這個建議根本無法執行。
凱利準則的真正內容
考慮一個重複進行的賭局,每次下注有機率 p 贏得下注金額的 g 倍,並有機率 q 輸掉下注金額的 l 倍,其中 q 等於一減去 p。能讓資金成長率最佳化的每次下注比例為:
f* = p / l - q / g
在經典的輸贏金額相等的情況下,獲利與虧損的倍數 g 和 l 都等於 1,公式便簡化為 f* = p - q。這個差值本身就是優勢。一個有 60% 勝率且輸贏金額相等的賭局,擁有 20 個百分點的優勢,而凱利準則會建議投入 20% 的資金。
這個推導過程僅需對財富的期望對數值進行一次微積分運算。最大化每次下注的平均對數財富,等同於最大化長期序列下的複合增長率,而能達成此目標的比例就是上述公式。由此可得出兩個特性。凱利準則絕不會建議在可能全輸的賭局中投入全部資金,因為零的對數值是負無窮大。此外,任何不同於 f 的固定比例,只要重複夠多次,其複合增長速度都會比 f 慢。
一個可以手動驗證的擲硬幣例子
本節的數字是假設性的,目的是讓計算過程一目瞭然。假設一枚硬幣出現正面的機率為 60%,且輸贏金額相等,起始資金為 1,000 美元。
- 每次擲幣投入 20% 的資金。贏了,資金從 1,000 美元變成 1,200 美元;輸了,則變成 800 美元。無論順序如何,經歷一次贏和一次輸後,資金會剩下 960 美元。
- 每次擲幣投入 40% 的資金。同樣先贏後輸的順序,資金會從 1,000 美元變成 1,400 美元,再變成 840 美元。
- 每次擲幣投入全部資金。只要出現一次反面,無論之前的優勢有多大,整個過程都將永久終止。
在投入 20% 資金的情況下,那 4% 的來回成本,是資金波動時進行複利所需付出的代價。而一個勝率 60/40 的硬幣,在長期的序列中足以多次彌補這個成本。在投入 40% 資金的情況下,來回成本高達 16%,此時硬幣的優勢已無法彌補:當下注比例是凱利比例的兩倍時,增長率大約降至零。超過這個臨界點,一個擁有真實、經驗證優勢的賭局,其資金將完全無法增長。這是凱利公式所能傳達的最有用的一個事實。
公式對每日股票下注的要求
現在將同一個公式應用於市場。將某支股票的一個交易日視為一次重複的賭局:勝率是當日收盤上漲的天數比例,獲利幅度是平均上漲日的漲幅,而虧損幅度是平均下跌日的跌幅。資料涵蓋 2016 年至 2025 年,共十個完整日曆年,選取六檔常見股票:
每個數據背後的精確 SQL 語法
WITH daily AS (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS dt,
argMax(toFloat64(close), window_start) AS c
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('SPY', 'KO', 'JNJ', 'MSFT', 'NVDA', 'TSLA')
AND window_start >= '2016-01-01 00:00:00'
AND window_start < '2026-01-01 00:00:00'
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY ticker, dt
),
steps AS (
SELECT ticker, dt, c,
lagInFrame(c) OVER (PARTITION BY ticker ORDER BY dt
ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev
FROM daily
),
rets AS (
SELECT ticker, c / prev - 1 AS ret
FROM steps
WHERE prev > 0 AND c != prev
)
SELECT ticker,
round(100 * countIf(ret > 0) / count(), 1) AS win_rate_pct,
round(100 * avgIf(ret, ret > 0), 2) AS avg_gain_pct,
round(100 * abs(avgIf(ret, ret < 0)), 2) AS avg_loss_pct,
round(countIf(ret > 0) / count() / abs(avgIf(ret, ret < 0))
- countIf(ret < 0) / count() / avgIf(ret, ret > 0), 1) AS full_kelly_x
FROM rets
GROUP BY ticker
HAVING countIf(ret > 0) > 0 AND countIf(ret < 0) > 0
ORDER BY full_kelly_x DESC只看前三欄,優勢看起來非常微小。勝率接近擲硬幣,而對於表中的每一檔股票,平均上漲日與平均下跌日的幅度都相當接近。SPY 在 55.3% 的交易日中收高,平均上漲日漲幅為 0.71%,平均下跌日跌幅則為 0.76%。
問題出在最後一欄。那些微小且近乎平衡的輸入值,位於公式的分母中,而小的分母會產生大的答案。公式為 SPY 傳回的比例是 10.1 倍的資金,而 6 檔股票中最低的比例也達到 2 倍。將完整凱利比例應用於每日股票下注,並非帳戶資金的一個百分比。它要求的槓桿倍數,沒有任何券商會提供,也沒有任何帳戶能承受。
取捨的樣貌
以上就是理論部分。下一張圖表則是實驗結果。取同一段十年期間內,追蹤 S&P 500 指數的 ETF 之實際每日報酬,將每天的報酬乘以一個固定的下注規模,然後進行複利計算。下注規模 1.0 倍代表無槓桿的指數本身。下注規模 3.0 倍則代表每天、每投入一美元資本,就承諾投入三美元,並且每日重新平衡。每一行都是一條完整的十年路徑,並顯示其最終財富以及過程中最深的峰值到谷底的跌幅。
每個數據背後的精確 SQL 語法
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS dt,
argMax(toFloat64(close), window_start) AS c
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2016-01-01 00:00:00'
AND window_start < '2026-01-01 00:00:00'
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY dt
),
steps AS (
SELECT dt, c,
lagInFrame(c) OVER (ORDER BY dt ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev
FROM daily
),
rets AS (
SELECT dt, c / prev - 1 AS ret
FROM steps
WHERE prev > 0
),
sizes AS (
SELECT arrayJoin([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0]) AS bet
),
paths AS (
SELECT bet, dt,
exp(sum(log(greatest(1 + bet * ret, 0.0001)))
OVER (PARTITION BY bet ORDER BY dt
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) AS equity
FROM rets CROSS JOIN sizes
),
peaks AS (
SELECT bet, dt, equity,
max(equity) OVER (PARTITION BY bet ORDER BY dt
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS peak
FROM paths
)
SELECT concat(toString(bet), 'x') AS bet_size,
round(argMax(equity, dt), 2) AS ending_multiple,
round(100 * max(1 - equity / peak), 1) AS max_drawdown_pct
FROM peaks
GROUP BY bet
ORDER BY bet當下注規模為 0.5x 倍時,路徑最終的財富是起始資金的 1.92 倍,過程中最深的跌幅為 18.2%。當下注規模為 5x 倍時,在同樣的每日報酬與同樣的十年期間下,路徑最終的財富是起始資金的 14.35 倍,過程中最深的跌幅則為 94.5%。
這兩個欄位的變化趨勢不同,而這正是部分凱利比例的核心教訓。最終財富會隨著下注規模增加而上升一段時間,然後趨於平緩,最後當波動複利帶來的拖累超過額外曝險帶來的好處時,便開始下降。而最大跌幅這一欄則沒有這樣的轉折點。在 8 行中,它每一步都在攀升,而且攀升的速度遠比財富那一欄曾經達到的速度更快。最適下注規模所能帶來的一半增長,可以在最適規模一半的下注量下實現,而所承受的痛苦卻只有一小部分。這種不對稱性,正是主張下注應低於 f* 的論點,也是存在「半凱利」這個慣例的原因。
問題在於估計,而非公式本身
對於一個賠率已知的賭局,這個公式是精確的。在賭場裡,賠率是印好的。在市場中,賠率是根據歷史資料估計出來的,而這個估計值會搖擺不定。以下是針對單一指數 ETF,分別在十年中的每個日曆年獨立執行與第一張圖表相同的計算結果。
每個數據背後的精確 SQL 語法
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS dt,
argMax(toFloat64(close), window_start) AS c
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2016-01-01 00:00:00'
AND window_start < '2026-01-01 00:00:00'
AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60
+ toMinute(toTimeZone(window_start, 'America/New_York'))) BETWEEN 570 AND 959
GROUP BY dt
),
steps AS (
SELECT dt, c,
lagInFrame(c) OVER (ORDER BY dt ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS prev
FROM daily
),
rets AS (
SELECT dt, c / prev - 1 AS ret
FROM steps
WHERE prev > 0 AND c != prev
)
SELECT toString(toYear(dt)) AS year,
round(100 * countIf(ret > 0) / count(), 1) AS win_rate_pct,
round(100 * avgIf(ret, ret > 0), 2) AS avg_gain_pct,
round(100 * abs(avgIf(ret, ret < 0)), 2) AS avg_loss_pct,
round(countIf(ret > 0) / count() / abs(avgIf(ret, ret < 0))
- countIf(ret < 0) / count() / avgIf(ret, ret > 0), 1) AS full_kelly_x
FROM rets
GROUP BY year
HAVING countIf(ret > 0) > 0 AND countIf(ret < 0) > 0
ORDER BY year每一行都是對同一個未知數量的估計,而每個估計值僅基於大約 250 個觀察值。2016 年傳回的結果是 13.7,該年的勝率為 53.8%。2025 年傳回的結果是 12.3,該年的勝率為 57.8%。這張圖表顯示,當 10 個讀數各自來自單一年份時,它們之間的差距可以有多大。
這種離散程度,遠比任何對公式本身的改良都來得重要。如果你將自己的優勢高估了兩倍,公式就會傳回大約兩倍的下注規模,這會讓你處於或超過增長率轉為負值的臨界點。如果你低估了優勢,你只是放棄了一些本可以複利增長的潛在增長,而沒有破產的風險。這兩種錯誤並非對稱的,而這種不對稱性中代價較低的一方,就是保守的那一方。實際使用凱利準則的從業者,往往只投入一半或四分之一的資金,並將該公式視為一個上限,而非一個目標。
模型在何處不再能描述市場
凱利準則假設一個你可以重複進行、且具備固定已知賠率的賭局,並且每次重複的結果是相互獨立的。市場打破了所有這些假設。賠率是估計出來的,並且會隨著時間改變。每日報酬會聚集:平靜的時期之後往往跟著平靜的時期,而劇烈波動的日子則成群出現,這使得跌幅超出獨立性假設所能預測的範圍。部位並非在每個交易日結束時結算,價格跳空會越過原本應該平倉的價格,而追繳保證金的通知則是按照券商而非模型的時間表到來。
儘管如此,凱利公式作為一個邊界值,仍然有其價值。它用一條公式就表明,存在一個下注規模,超過它之後,更多的信心反而會產生更少的財富,並且它從交易者至少可以嘗試測量的數量中,定位出這個邊界。這也是為什麼同樣的邏輯指向了分散投資:幾個部分獨立的賭局,可以比單一賭局更有效地分攤相同的總風險預算,而這正是集中風險背後的算術原理。對於那些按計劃定期投入資金,而非根據離散賭局來決定部位規模的投資者而言,部位規模的問題本身就由這個計劃來回答,這也是平均成本法的論點所在。
常見問題
什麼是凱利準則公式?
對於一個有機率 p 贏得下注金額 g 倍,並有機率 q 輸掉下注金額 l 倍的賭局,能讓資金成長率最佳化的下注比例為 f = p / l - q / g。在輸贏金額相等的情況下,它簡化為 f = p - q,也就是優勢本身。
為什麼交易員使用半凱利而非完整凱利?
因為在最適比例附近,增長率幾乎持平,而風險卻持續攀升。因此,將下注規模減半,只會犧牲少量的長期增長,卻能大幅降低最大跌幅。估計誤差更加強了這個論點:因高估優勢而加倍的下注規模,會落在增長率趨近於零的臨界點附近。
凱利準則適用於股票嗎?
它在算術上是適用的,但其關於固定已知賠率和獨立結果的假設,在市場中並不成立。如上文第一張圖表所示,將其天真地應用於每日股票報酬,會要求遠超過任何帳戶能承受的槓桿。
如果下注超過凱利比例會怎樣?
長期增長率會下降。當下注規模大約是凱利比例的兩倍時,增長率會降至接近零。超過這個點,一個擁有真實優勢的賭局,其資金會隨著時間縮水,同時跌幅會持續加深。
凱利準則等同於每次交易冒 1% 或 2% 的風險嗎?
不。固定百分比規則完全忽略了賠率,對每個交易機會都套用相同的數字。凱利準則則會根據衡量出的優勢來調整下注規模,這使得它在優勢已知時更具反應性,而在優勢是猜測時則更為脆弱。
以上每個數字都來自一個可儲存的查詢,您可以打開、編輯並重新執行。在 Strasmore 終端機上,替換股票代碼、時間區間或下注規模網格,親自衡量其中的取捨。