Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

均等配分が最適化を上回るとき

サンプルが短いと、最適化したポジション・サイジングより均等配分が優れます。Pythonシミュレーションで逆転と収束を示します。

サンプルが短く、期待リターンを十分に推定できない場合は、最適化したポジション・サイジングよりも均等配分の方が優れます。しかも、短いサンプルは例外ではなく、通常の状況です。オプティマイザーは、誰も正確に測定できない入力値に、正しい計算を適用しているにすぎません。1/Nポートフォリオ、つまり均等配分は、そもそも何も推定しません。そのため、推定値の精度が低い場合でも機能します。

等ウェートは本当に最適化を上回るのか

特定の条件下では、上回ります。用語を一つずつ見ていきます。等ウェート(1/N)は、資金をN個のポジションに均等配分し、いかなる予測も必要としません。平均分散最適化は、推定分散一単位当たりの期待リターンが最も高くなるウェートを求めます。Kelly基準は、長期的な複利成長率を最大化するウェートを求めます。無相関資産では、その答えは各資産の期待超過リターンを分散で割った値に比例するウェートになります。詳しい計算式は、Kelly基準によるポジションサイジングのガイドで解説しています。

どちらの最適化手法にも、同じ入力値が必要です。資産ごとの期待リターンです。これは、標本から推定するのが最も難しい値です。ボラティリティは、短い観測期間からでも実用的な精度で算出できます。しかし、平均値はそうではありません。両者の差は、どの価格履歴を見ても確認できるほど大きいものです。下のパネルでは、広く保有されている六つの銘柄を対象に、2015年から2024年までの各暦年を個別に計測しています。そして、年間推定値の最高値と最低値がどれだけ離れているかを示しています。銘柄ごとに、年率換算した日次平均リターンと、年率換算したボラティリティについて、それぞれ計算しています。

クエリ10年間の年次推定値:平均はボラティリティより大きく変動
各数値の背後にある正確なSQL
WITH prices AS
(
    SELECT
        ticker,
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('AAPL', 'MSFT', 'NVDA', 'SPY', 'KO', 'JNJ')
      AND date >= '2015-01-01'
      AND date <  '2025-01-01'
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
yearly AS
(
    SELECT
        ticker,
        toYear(date)                     AS yr,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM rets
    WHERE isFinite(ret)
    GROUP BY ticker, yr
    HAVING count() >= 200
)
SELECT
    ticker,
    round(max(mean_pct) - min(mean_pct), 1) AS mean_estimate_range_pct,
    round(max(vol_pct) - min(vol_pct), 1)   AS vol_estimate_range_pct
FROM yearly
GROUP BY ticker
ORDER BY mean_estimate_range_pct DESC
Run this yourself

NVDAでは、10年間の年間平均推定値のレンジが184.7パーセントポイントに達しました。同じ銘柄のボラティリティ推定値のレンジは28.6ポイントでした。パネルで最も安定した銘柄であるKOでも、年間平均推定値は23.9ポイント変動しました。前年の平均リターンを当年の期待リターンとして最適化手法に入力する仕組みは、これほど変動する数値を与えていることになります。

期待収益率の推定には、どれだけの期間のデータが必要か

推定平均リターンの標準誤差は、資産のボラティリティを、年単位で表したサンプル期間の平方根で割った値です。観測回数ではなく、年数です。同じ十二カ月を日次ではなく時間単位でサンプリングしても、精度は向上しません。ボラティリティが20%の資産をこの式に当てはめると、過去一年分のデータから得られる標準誤差は年率20ポイントです。四年あれば10ポイントに半減します。真の平均リターンが二ポイント異なる二つの資産を順位付けする前提として、誤差を一ポイントまで下げるには、四世紀分のデータが必要です。

ボラティリティは別のケースです。精度は暦上の期間ではなく、観測回数に応じて向上するため、日次データなら数カ月分でも数ポイント以内に収まります。以下のパネルでは、あるインデックスファンドの日次リターン二十年分を、一定の長さの重複しないブロックに分割しています。そして各ブロック内で両方の推定値を計算し、ブロックごとの推定値のばらつきを示しています。

クエリサンプル期間別の平均・ボラティリティ推定値のばらつき
各数値の背後にある正確なSQL
WITH prices AS
(
    SELECT
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker = 'SPY'
      AND date >= '2005-01-01'
      AND date <  '2025-01-01'
    GROUP BY date
),
rets AS
(
    SELECT
        date,
        c / lagInFrame(c, 1) OVER (ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
numbered AS
(
    SELECT
        ret,
        row_number() OVER (ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
),
sweep AS
(
    SELECT
        arrayJoin([21, 63, 126, 252, 504]) AS n,
        i,
        ret
    FROM numbered
),
blocks AS
(
    SELECT
        n,
        intDiv(i - 1, n)                 AS blk,
        avg(ret) * 252 * 100             AS mean_pct,
        stddevPop(ret) * sqrt(252) * 100 AS vol_pct
    FROM sweep
    GROUP BY n, blk
    HAVING count() = n
)
SELECT
    concat(toString(n), ' sessions') AS sample_length,
    round(stddevPop(mean_pct), 1)    AS mean_estimate_spread_pct,
    round(stddevPop(vol_pct), 1)     AS vol_estimate_spread_pct,
    count()                          AS window_count
FROM blocks
GROUP BY n
ORDER BY n ASC
Run this yourself

ブロックの長さが21 sessionsの場合、平均リターンの推定値は53.7ポイントの範囲でばらつきます。同じブロックで測定したボラティリティ推定値のばらつきは10.9ポイントです。ブロックを504 sessionsまで延ばすと、平均リターンのばらつきは10.6ポイントまで縮小します。縮小のペースは平方根に沿います。誤差を半分にするたびに、データは四倍必要です。

自分で実行できるシード付きシミュレーション

これだけでは、推定誤差が1/Nに勝たせるほど大きいとは証明できません。次の方法なら証明できます。必要なのはPython環境だけです。データファイルも、ダウンロードも、サードパーティー製パッケージも必要ありません。選んだパラメータからリターンを生成するため、真の答えが分かっており、両方の配分を比較できます。

  1. import randomimport statisticsの2つのモジュールに加え、from math import logをインポートします。次の行でrandom.seed(20260816)を使ってシードを設定します。
  2. 5つの資産を定義します。真の年間期待リターンは5、6、7、8、9%、真の年間ボラティリティはすべて20%とし、相関はないものとします。mu_d = mu_a / 252sd_d = sd_a / (252 ** 0.5)を使って日次の値に変換します。
  3. [60, 125, 250, 500, 1000, 2500, 5000]の範囲から、サンプル期間Tを選びます。
  4. random.gauss(mu_d, sd_d)を使い、各資産についてT日分の日次リターンを生成します。このデータが、運用担当者に与えられる全履歴です。
  5. statistics.meanで各資産の平均を、statistics.stdevでボラティリティを推定します。オプティマイザーが利用できるのは、この2つの推定値だけです。
  6. 5資産にそれぞれ0.2を割り当て、等ウェート・ポートフォリオを構築します。この配分では推定値を一切使いません。
  7. 最適化ポートフォリオでは、各未調整ウェートをmu_hat / (sd_hat ** 2)に設定します。その後、すべてのウェートを未調整ウェートの絶対値の合計で割り、両ポートフォリオのグロス・エクスポージャーをそろえます。
  8. 真のパラメータから、各資産について2520日分の日次リターンのアウト・オブ・サンプル経路を新たに生成します。どちらの配分も、この経路を事前には見ていません。
  9. rをその日の5資産の加重平均リターンとし、log(1 + r)の平均によってこの経路で両方を評価します。
  10. 各Tについて、手順4から9を独立した2000回の試行で繰り返し、等ウェートが最適化ウェートを上回った試行の割合を記録します。

短いTから長いTへと結果を読みます。Tが短い範囲では、等ウェートが試行の明確な過半数で勝ちます。Tが長くなるにつれてその割合は着実に低下し、長い範囲では最適化ウェートが大半の試行で勝ちます。中間のどこかで両者が逆転します。クロスオーバー地点は、シードと真の平均リターンの差によって変わります。ただし、方向性は変わりません。データが多いほどオプティマイザーが有利になり、データが少ないほど1/Nが有利になります。再現するには、random.seed(20260816)内の整数を変更してスイープをもう一度実行します。

オプティマイザーが不適切な平均推定値を増幅する理由

推定値がウェイトに入る位置を確認してください。推定平均は分子に、推定分散は分母に入ります。平均の推定値を二倍にすると、ウェイトも二倍になります。分散の推定値を四分の一削ると、ウェイトは三分の一上昇します。運のよい標本では、二つの誤差が同じ方向に働きます。良好な値動きが続くと、測定された平均が上昇し、同じ期間の測定分散が低下することも少なくありません。オプティマイザーはその資産をグループ内で突出した銘柄と判断し、それに応じてポジションを大きくします。標本外では、再びグループ内の普通の銘柄に戻ります。均等ウェイトは、その運のよい標本を見ていません。

このシミュレーションは、この問題を穏やかに示したものです。相関のない五つの資産なら、反転すべきものがない対角共分散行列になります。実際のポートフォリオには相関があり、資産数をわずかに上回る観測数から作った標本共分散行列は、特異行列に近くなります。これを反転すると、入力値の小さな誤差が非常に大きなウェイトに増幅されます。その結果、オプティマイザーは一つの銘柄に投下資本の数倍に相当するポジションを取り、その銘柄に近い代替銘柄を同額程度ショートすることがあります。このようなウェイトがドローダウンに及ぼす影響については、ポートフォリオの集中リスクで解説しています。

入力値も一定ではありません。下のパネルは、広範な指数ファンドと大手生活必需品銘柄について、月次で抽出した過去一年間の平均日次リターンを年率換算し、その推移を示しています。

クエリオプティマイザーに入力される1年ローリング平均リターン
各数値の背後にある正確なSQL
WITH prices AS
(
    SELECT
        ticker,
        date,
        toFloat64(max(close)) AS c
    FROM global_markets.stocks_daily_aggs
    WHERE ticker IN ('SPY', 'KO')
      AND date >= '2015-10-01'
      AND date <  '2025-01-01'
    GROUP BY ticker, date
),
rets AS
(
    SELECT
        ticker,
        date,
        c / lagInFrame(c, 1) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) - 1 AS ret
    FROM prices
),
trailing AS
(
    SELECT
        ticker,
        date,
        avg(ret) OVER (PARTITION BY ticker ORDER BY date ASC ROWS BETWEEN 251 PRECEDING AND CURRENT ROW) * 252 * 100 AS trailing_mean_pct,
        row_number() OVER (PARTITION BY ticker ORDER BY date ASC) AS i
    FROM rets
    WHERE isFinite(ret)
)
SELECT
    toString(toStartOfMonth(date))                     AS month,
    round(avgIf(trailing_mean_pct, ticker = 'SPY'), 1) AS spy_trailing_mean_pct,
    round(avgIf(trailing_mean_pct, ticker = 'KO'), 1)  AS ko_trailing_mean_pct
FROM trailing
WHERE i >= 252
  AND date >= '2017-01-01'
GROUP BY month
ORDER BY month ASC
Run this yourself

この二本の線上にある各点は、オプティマイザーがその時点の期待リターンとして受け入れた可能性のある数値です。SPYの最初の月次値は17.7%、最後の値は25.8%で、その間に96個の値があります。KOは同じ期間を-0.4%で始めます。この系列を月ごとに取り込むウェイト設定は、系列に含まれるあらゆる揺れを引き継ぎます。

ハーフ・Kellyと縮小推定で解決するのか

影響は和らぎます。実務では四つの対策が使われます。いずれも、推定値への感応度を下げる代わりに、理論上の最適性の一部を手放す方法です。

  • ハーフ・Kellyは、すべてのウェートを半分にします。Kellyの成長曲線はピーク付近では平坦で、その下方では急になります。そのため、投資比率を半分にすると理論上の成長率はわずかに低下する一方、過大に見積もった優位性による損失はそれ以上に抑えられます。ボラティリティ・ターゲティングは、分母にも同じ考え方を適用します。短いサンプルから得られる一つの入力値を基にポジションサイズを決めます。
  • 縮小推定は、推定した平均リターンをすべて、推定値のクロスセクション平均に近づけます。サンプルが少ないほど、縮小の度合いは大きくなります。限界まで縮小すると、すべての資産の期待リターンは同じになります。ボラティリティも同じなら、オプティマイザーは自動的に均等配分を返します。均等配分は、完全に縮小したポートフォリオです。
  • 制約とは、空売りを禁止し、各ポジションに上限を設けることです。これにより、一つの偶然に高くなった推定値が単一銘柄のウェートを押し上げる幅を制限できます。推定値を改善する方法ではなく、損失を抑えるための措置です。
  • 期待リターンを完全に除外すると、最小分散とリスク・パリティが残ります。これらは共分散だけを使います。共分散こそ、サンプルから実際に得られる入力値です。

四つの方法のいずれも、サンプルに含まれない情報を生み出すわけではありません。変わるのは、投資家が持っていないかもしれない情報に、ポートフォリオのどれだけを依存させるかです。

最適化が有効になる局面

この逆転は、どちらの方向にも起こります。Tが真の平均値の差に対して十分大きくなると、最適化した配分が優位に立ち、その状態が続きます。平均値の差が大きいほど、逆転は早く起こります。入力値がデータから得られる場合も、最適化が適切な手法です。共分散やヘッジ比率は、期待リターンよりも精度よく推定できます。

均等加重にもコストがあります。実際に持っている情報を無視するうえ、銘柄数が少ない場合は、最適化手法と同じ程度にポートフォリオが集中します。均等加重は、ウェイトの算出に使っていないデータで、どの候補ウェイトが上回るべきかを判断するベースラインと位置付けてください。同じサンプルでウェイトを推定し、そのウェイトを評価するのは、別の形を取ったバックテストにおける先読みバイアスです。これは常に最適化手法を実際以上に良く見せます。測定した優位性を単一点の推定値ではなく、妥当な範囲として示すには、ブートストラップ信頼区間が標準的な手法です。

よくある質問

イコールウェートは本当に平均・分散最適化を上回るのですか?

短いサンプル期間では、上回ることが多いです。最適化には各資産の期待リターンの推定値が必要です。この推定値の標準誤差は、おおむね資産のボラティリティを年単位のサンプル期間の平方根で割った大きさになります。その誤差が資産間の真の差を上回っている間、最適化はノイズを順位付けしているにすぎません。イコールウェートでは、誤った推定値を使う必要がありません。

期待リターンの推定には、どれだけの観測値が必要ですか?

ほぼ誰も用意できないほど大量の観測値が必要です。ボラティリティが20%の資産では、日次データを一年使っても標準誤差は年率で約20ポイント残ります。この誤差を半分にするには、暦上の期間を四倍に延ばす必要があります。同じ一年の中で日中の観測値を追加しても、改善にはつながりません。一方、ボラティリティは数カ月分のデータでも実用的に推定できます。

ハーフ・ケリーは、単に賭け金を小さくするだけですか?

有利な条件で賭け金を小さくする手法です。ケリー基準の成長曲線は頂点付近で平坦になるため、賭け金を半分にしても理論上の成長率の低下は小さく抑えられます。その一方で、運用経路のボラティリティはおおむね半分になり、優位性を過大評価した場合のコストも縮小します。

1/Nポートフォリオとは何ですか?

N個のポジションそれぞれに資本を均等配分し、決められたスケジュールでリバランスするポートフォリオです。リターン予測も共分散の推定も必要ありません。そのため、これらを必要とするあらゆる加重手法の標準的なベンチマークになっています。

パネルの作成方法

三つのパネルはいずれも日次終値を読み込み、終値から終値までの単純リターンを計算しています。同一銘柄・同一日付の重複行は、一つの終値に集約しています。平均リターンは、日次平均リターンに252セッションを乗じて年率換算しています。ボラティリティは、日次標準偏差に252の平方根を乗じて年率換算しています。年次パネルでは、少なくとも200セッションがある場合だけ暦年を採用しています。ブロック・パネルでは重複しないブロックを使い、各期間の最後に残る不完全なブロックは除外しています。window count列は、各期間で作成されたブロック数を示します。配当は一切含めていないため、これは価格リターンです。したがって、配当を支払う銘柄では平均値の水準が過小評価されています。パネルで示しているのは推定値のばらつきであり、水準そのものではありません。


このページの各パネルには、チャートの下に正確なSQLが記載されています。シミュレーションにはシード値も付いています。自身の銘柄リストで同じ推定値の安定性チェックを実行するには、Strasmore terminalで平易な英語で依頼してください。

#quant#position sizing#portfolio construction#estimation error#kelly