feedback
← 回到目錄

波動度目標化怎麼運作

固定部位大小會忽略市場環境。波動度目標化根據當前市場波動程度,自動調整每次下注的規模。

固定部位大小的問題

基本的 Type A 策略輸出 1.0(做多)或 0.0(空手)。Runner 在訊號為 1.0 時把全部配置資金都投入。這樣做有效,但有個隱性問題:不管市場是平靜還是劇烈波動,策略下的注都一樣大

在低波動期,1% 的日線波動已經算大。在高波動期,1% 的波動只是雜訊。如果策略在兩種環境都用同樣的部位大小進場,實際的金額風險就會大幅波動——高波動期的回撤會遠大於回測平均所暗示的水準。

波動度目標化解決這個問題的方式:把部位大小和已實現波動度做反向連動。市場波動比目標高時投入少一點,比目標低時投入多一點——但有上限。

公式

BlaveClaw 的波動度目標化分兩步:

第一步——測量已實現波動度

log_return = log(Close / Close.shift(1))
realized_vol = log_return.rolling(lookback).std() * sqrt(periods_per_year)

計算對數報酬率的滾動標準差,再乘以 sqrt(periods_per_year) 換算成年化。結果就是年化已實現波動度——和 Sharpe ratio 使用的波動度單位相同。

預設值:lookback=720 根 K 棒、periods_per_year=8760。這是為1h 週期策略校準的:720 根 = 30 天 × 24 小時;8760 = 24 × 365。

第二步——縮放訊號

scale = (target_vol / realized_vol).clip(upper=vol_cap)
scaled_signal = signal * scale

訊號(1.0 = 全額做多)乘以波動度比值,上限為 vol_cap,得到小數部位大小。

預設值:target_vol=0.30(年化 30%)、vol_cap=2.0(最大 2 倍槓桿)。

具體範例

已實現波動(年化)目標波動原始倍數套用上限後部位大小
10%30%3.0×2.0×(上限)配置資金的 200%
20%30%1.5×1.5×配置資金的 150%
30%30%1.0×1.0×100%——基準
60%30%0.5×0.5×配置資金的 50%
90%30%0.33×0.33×配置資金的 33%

已實現波動在 30% 時,策略以全額運行。危機期間波動飆升到 90% 時,策略自動縮減至三分之一部位。平靜期波動降至 10% 時,放大到上限 2 倍。

不同週期的參數調整

預設值(lookback=720periods_per_year=8760)是為1h 策略設定的。其他週期必須重新計算:

週期periods_per_yearlookback(30 天窗口)
5min105,120(12 × 24 × 365)8,640 根
1h(預設)8,760720 根
4h2,190180 根
8h1,09590 根
1d36530 根
日線策略用 30 根的 lookback 很短。考慮用 252 根(一年)來取得更穩定的波動估計,避免對短期飆升過度反應。

怎麼加進策略裡

VOL_TARGETING    = True
TARGET_VOL       = 0.30   # 年化目標波動 30%
VOL_CAP          = 2.0    # 最大 2 倍槓桿
VOL_LOOKBACK     = 720    # lookback 窗口長度(根 K 棒)
PERIODS_PER_YEAR = 8760   # 1h 週期用

def fetch_data(hdrs):
    from lib.data import fetch_kline
    from lib.strategy import add_realized_vol
    df = fetch_kline(SYMBOL, INTERVAL, START, END, hdrs)
    if VOL_TARGETING:
        add_realized_vol(df, VOL_LOOKBACK, PERIODS_PER_YEAR)
    return df

def compute_signals(df):
    from lib.strategy import apply_vol_scaling
    signal = pd.Series(np.nan, index=df.index)
    # ... 訊號邏輯 ...
    if VOL_TARGETING:
        return apply_vol_scaling(signal, df, TARGET_VOL, VOL_CAP)
    return signal

注意:add_realized_vol 必須在 fetch_data 裡呼叫(訊號計算之前),因為 apply_vol_scaling 會讀取 df['realized_vol'],而這個欄位是第一個函式就地寫入的。

vol_cap 為什麼預設是 2×

上限的存在是因為在持續低波動的環境下,波動度目標化可能產生極端槓桿。如果已實現波動降到 5%,沒有上限的倍數會是 6 倍。單日不利的走勢就可能造成毀滅性的回撤,即使訊號本身完全正確。

預設 2× 的上限讓策略最多只用到配置資金的兩倍。如果你完全不想有槓桿,把 vol_cap=1.0——波動度目標化就只會在高波動時縮減部位,不會在低波動時放大超過全額。

目標波動和隱含最大回撤

一個實用的經驗法則:target_vol ≈ 可接受 MDD ÷ 2。這來自趨勢追蹤策略中年化波動度和最大回撤的經驗關係。

target_vol隱含典型 MDD適合情境
10%約 −20%保守型,資金保全優先
20%約 −40%中等
30%(預設)約 −60%積極型——用滿風險預算

組合 Manager 在決定整體組合槓桿時也用同樣的邏輯:槓桿 = target_vol / 組合已實現波動。把個別策略的 TARGET_VOL 設定和 Manager 的 target_vol_pct 保持一致,可以避免多個策略組合時重複計算風險。

← 回到目錄