比特幣對沖基金與量化交易策略專業指南:機構級策略框架與實務分析

深入分析比特幣對沖基金的運作模式、主要量化策略類型、風險管理框架以及機構級的技術基礎設施。涵蓋趨勢追蹤、均值回歸、統計套利、宏觀驅動與鏈上量化等策略,並提供Python實作代碼範例。

比特幣對沖基金量化策略完整指南:統計套利、期現套利與波動率溢價策略的數學推導與回測方法論

前言:比特幣量化交易的市場背景

比特幣作為全球最大的加密貨幣資產,其獨特的市場結構為量化交易策略提供了豐富的機會。與傳統資產相比,比特幣市場具有 24/7 全天候交易、高波動性、相對較低的機構化程度、以及期現市場間經常出現的顯著價差等特徵。

比特幣對沖基金的量化策略通常可分為三大類:方向性策略(捕捉價格趨勢)、套利策略(捕捉市場定價效率低下)、以及波動率策略(利用波動率溢價)。本文將深入探討這三類策略的數學推導、實作細節、以及回測方法論,並提供完整的 Python 程式碼範例。

第一章:期現套利策略的數學框架

1.1 期現套利的基本原理

比特幣期現套利(Cash and Carry Arbitrage)的核心思想是:當比特幣期貨合約價格高於現貨價格加持有成本時,投資者可以買入現貨、做空期貨合約,鎖定無風險收益。

經典期現套利模型

定義以下變數:

根據持有成本模型(Cost of Carry Model):

F(t,T) = S(t) × e^((r+q) × (T-t))

當市場定價偏離理論價格時,套利機會出現:

溢價 = F(t,T) - S(t) × e^((r+q) × (T-t))

套利收益計算

若溢價 > 0(期貨價格高估):

到期收益(忽略交易費用):

π = F(t,T) - S(T) - S(t) × e^(r × (T-t)) + S(t) × q × (T-t)
  = 溢價 - 借貸成本

1.2 資金費率套利

永續合約(Perpetual Swap)的資金費率機制提供了另一種期現套利機會。

資金費率的經濟學解釋

永續合約通過定期的資金費用(Funding Rate)來使合約價格錨定現貨價格:

資金費率套利策略

當資金費率為正且較高時:

  1. 持有比特幣現貨(或期貨多頭)
  2. 做空永續合約
  3. 收取資金費用
策略收益:
===================================
π = Σ(Funding_Payment_t) + ΔS/S - Borrowing_Cost - Futures_Cost

其中:
- Σ(Funding_Payment_t) = 持有期間收到的資金費用總和
- ΔS/S = 現貨價格變動收益
- Borrowing_Cost = 比特幣借貸成本(年化)
- Futures_Cost = 期貨倉位維持成本

實例計算:
假設:
- 比特幣現貨價格:$50,000
- 永續合約溢價:0.01%/8小時(每 8 小時計費一次)
- 每日資金費用:0.01% × 3 = 0.03%
- 年化資金費用:0.03% × 365 = 10.95%
- 比特幣借貸年化利率:5%
- 期貨/永續維持成本:1%

年化套利收益:
= 10.95% - 5% - 1%
= 4.95%

若初始資本為 $1,000,000:
年收益 = $1,000,000 × 4.95% = $49,500

1.3 期現套利的風險管理

期現套利並非真正的「無風險」套利,存在以下風險:

風險一:強平風險

風險二:流動性風險

風險三:資金費率反轉風險

槓桿比例計算:
===================================
假設:
- 初始現貨價值:$100,000
- 期貨槓桿:3 倍
- 安全邊際:20%

期貨合約價值:
= $100,000 × 3 = $300,000
初始保證金:
= $300,000 / 3 = $100,000

強平門檻計算:
假設維持保證金率為 10%

若做空期貨:
強平條件 = 開倉價格 × (1 - (1 - 維持保證金率) / 槓桿)
         = $50,000 × (1 - 0.9/3)
         = $50,000 × 0.7
         = $35,000

結論:比特幣現貨價格需下跌至 $35,000 才會觸發強平

1.4 期現套利的 Python 實作

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import requests

class FuturesCashArbitrage:
    """
    期現套利策略類
    """
    def __init__(self, initial_capital=1000000, leverage=3, funding_threshold=0.0003):
        self.initial_capital = initial_capital
        self.leverage = leverage
        self.funding_threshold = funding_threshold
        self.position = 0
        self.cash = initial_capital
        
    def calculate_theoretical_futures_price(self, spot_price, time_to_expiry, 
                                            risk_free_rate=0.05, borrow_rate=0.03):
        """
        根據持有成本模型計算理論期貨價格
        """
        t = time_to_expiry / 365  # 轉換為年
        carry_cost = risk_free_rate + borrow_rate
        theoretical_price = spot_price * np.exp(carry_cost * t)
        return theoretical_price
    
    def calculate_arbitrage_opportunity(self, spot_price, futures_price, 
                                       time_to_expiry, current_funding_rate):
        """
        計算套利機會
        """
        theoretical_price = self.calculate_theoretical_futures_price(
            spot_price, time_to_expiry
        )
        
        # 溢價
        premium = futures_price - theoretical_price
        premium_pct = premium / spot_price * 100
        
        # 年化溢價率
        annualized_premium = premium_pct * (365 / time_to_expiry)
        
        # 扣除資金費率後的收益
        net_annualized_return = annualized_premium - (current_funding_rate * 365)
        
        return {
            'premium': premium,
            'premium_pct': premium_pct,
            'annualized_premium': annualized_premium,
            'net_annualized_return': net_annualized_return,
            'opportunity': net_annualized_return > self.funding_threshold * 365
        }
    
    def execute_strategy(self, spot_price, futures_price, time_to_expiry, 
                        current_funding_rate):
        """
        執行套利策略
        """
        analysis = self.calculate_arbitrage_opportunity(
            spot_price, futures_price, time_to_expiry, current_funding_rate
        )
        
        if analysis['opportunity'] and self.position == 0:
            # 開倉:買現貨,賣期貨
            position_size = self.cash * self.leverage
            btc_amount = position_size / spot_price
            
            self.position = btc_amount
            self.cash -= btc_amount * spot_price  # 買現貨
            self.cash -= btc_amount * futures_price / self.leverage  # 期貨保證金
            
            return {
                'action': 'OPEN',
                'btc_amount': btc_amount,
                'spot_cost': btc_amount * spot_price,
                'futures_entry': futures_price
            }
        elif not analysis['opportunity'] and self.position > 0:
            # 平倉
            close_value = self.position * spot_price
            pnl = close_value - (self.position * self.last_entry_price)
            
            self.cash += close_value
            self.position = 0
            
            return {
                'action': 'CLOSE',
                'btc_amount': 0,
                'pnl': pnl
            }
        
        return {'action': 'HOLD'}

第二章:統計套利策略

2.1 均值回歸策略的數學推導

統計套利的核心假設是:資產價格在短期內會偏離其均衡價格,但最終會回歸。比特幣市場的高波動性使均值回歸策略特別適用。

Ornstein-Uhlenbeck 過程模型

資產價格的均值回歸行為可用 Ornstein-Uhlenbeck (OU) 過程描述:

dS(t) = θ(μ - S(t))dt + σdW(t)

其中:
- θ = 均值回歸速度(mean reversion speed)
- μ = 長期均衡價格
- σ = 波動率
- W(t) = 布朗運動

離散化形式:

S(t+1) - S(t) = θ(μ - S(t))Δt + σ√Δt × ε(t+1)

均值回歸信號

定義 z-score 來衡量當前價格相對於均衡價格的偏離程度:

z(t) = (S(t) - μ) / σ

交易信號:
- 當 z(t) > z_entry(例:2.0):賣出(價格高估)
- 當 z(t) < -z_entry:買入(價格低估)
- 當 |z(t)| < z_exit(例:0.5):平倉

2.2 跨交易所統計套利

比特幣在多個交易所同時交易,不同交易所之間的價格差異創造了套利機會。

價差穩定性分析

假設:
- 交易所 A 的比特幣價格:S_A(t)
- 交易所 B 的比特幣價格:S_B(t)
- 歷史價差均值:μ_Δ = E[S_A - S_B]
- 歷史價差標準差:σ_Δ = √Var[S_A - S_B]

當前價差:Δ(t) = S_A(t) - S_B(t)
z-score:z(t) = (Δ(t) - μ_Δ) / σ_Δ

交易策略

當 z(t) > 2.0:

Python 實作

import pandas as pd
import numpy as np
from collections import deque

class CrossExchangeArbitrage:
    """
    跨交易所統計套利策略
    """
    def __init__(self, entry_threshold=2.0, exit_threshold=0.5, lookback=1000):
        self.entry_threshold = entry_threshold
        self.exit_threshold = exit_threshold
        self.lookback = lookback
        self.spread_history = deque(maxlen=lookback)
        self.position = 0  # 正數=做多價差,負數=做空價差
        
    def calculate_z_score(self):
        """
        計算當前價差的 z-score
        """
        if len(self.spread_history) < 30:
            return 0.0
            
        spread_array = np.array(self.spread_history)
        mean = np.mean(spread_array)
        std = np.std(spread_array)
        
        if std == 0:
            return 0.0
            
        current_spread = spread_array[-1]
        z_score = (current_spread - mean) / std
        
        return z_score
    
    def update_spread(self, exchange_a_price, exchange_b_price):
        """
        更新價差數據
        """
        spread = exchange_a_price - exchange_b_price
        self.spread_history.append(spread)
        
    def generate_signal(self, exchange_a_price, exchange_b_price):
        """
        生成交易信號
        """
        self.update_spread(exchange_a_price, exchange_b_price)
        z_score = self.calculate_z_score()
        
        if z_score > self.entry_threshold and self.position == 0:
            # 做空價差:賣出交易所A,買入交易所B
            return {
                'action': 'SHORT_SPREAD',
                'z_score': z_score,
                'exchange_a': 'SELL',
                'exchange_b': 'BUY'
            }
        elif z_score < -self.entry_threshold and self.position == 0:
            # 做多價差:買入交易所A,賣出交易所B
            return {
                'action': 'LONG_SPREAD',
                'z_score': z_score,
                'exchange_a': 'BUY',
                'exchange_b': 'SELL'
            }
        elif self.position != 0 and abs(z_score) < self.exit_threshold:
            # 平倉
            return {
                'action': 'CLOSE',
                'z_score': z_score
            }
        
        return {'action': 'HOLD', 'z_score': z_score}
    
    def calculate_pnl(self, entry_spread, exit_spread, position_type):
        """
        計算套利收益
        """
        if position_type == 'LONG_SPREAD':
            return exit_spread - entry_spread
        elif position_type == 'SHORT_SPREAD':
            return entry_spread - exit_spread
        return 0
    
    def backtest(self, price_data_a, price_data_b):
        """
        回測策略
        """
        results = []
        entry_spread = None
        position_type = None
        
        for i in range(len(price_data_a)):
            signal = self.generate_signal(price_data_a[i], price_data_b[i])
            
            if signal['action'] == 'LONG_SPREAD' and self.position == 0:
                entry_spread = price_data_a[i] - price_data_b[i]
                position_type = 'LONG_SPREAD'
                self.position = 1
                results.append({
                    'timestamp': i,
                    'action': 'ENTRY_LONG',
                    'spread': entry_spread,
                    'z_score': signal['z_score']
                })
            elif signal['action'] == 'SHORT_SPREAD' and self.position == 0:
                entry_spread = price_data_a[i] - price_data_b[i]
                position_type = 'SHORT_SPREAD'
                self.position = -1
                results.append({
                    'timestamp': i,
                    'action': 'ENTRY_SHORT',
                    'spread': entry_spread,
                    'z_score': signal['z_score']
                })
            elif signal['action'] == 'CLOSE' and self.position != 0:
                exit_spread = price_data_a[i] - price_data_b[i]
                pnl = self.calculate_pnl(entry_spread, exit_spread, position_type)
                results.append({
                    'timestamp': i,
                    'action': 'EXIT',
                    'spread': exit_spread,
                    'pnl': pnl,
                    'z_score': signal['z_score']
                })
                self.position = 0
                entry_spread = None
                position_type = None
        
        return pd.DataFrame(results)

2.3 配對交易策略

配對交易(Pairs Trading)是另一種經典的統計套利策略。

基本原理

假設存在兩個高度相關的資產 X 和 Y:

協整性檢定

使用 Engle-Granger 兩步法檢定 X 和 Y 的協整關係:

步驟 1:估計長期均衡關係
Y_t = α + βX_t + ε_t

步驟 2:檢定殘差 ε_t 的平穩性
Δε_t = ρε_{t-1} + η_t

若 ρ < 0,則拒絕虛無假設(存在單位根),
確認 X 和 Y 存在協整關係
from statsmodels.tsa.stattools import coint, adfuller
from sklearn.linear_model import LinearRegression

class PairsTrading:
    """
    配對交易策略
    """
    def __init__(self, asset_x, asset_y, lookback=60, 
                 entry_threshold=2.0, exit_threshold=0.5):
        self.asset_x = asset_x
        self.asset_y = asset_y
        self.lookback = lookback
        self.entry_threshold = entry_threshold
        self.exit_threshold = exit_threshold
        self.beta = None
        self.spread_mean = None
        self.spread_std = None
        self.position = 0
        
    def find_hedge_ratio(self, x, y):
        """
        使用OLS估計對沖比率
        """
        model = LinearRegression()
        X = x.values.reshape(-1, 1)
        y_vals = y.values
        model.fit(X, y_vals)
        return model.coef_[0], model.intercept_
    
    def calculate_spread(self, x, y):
        """
        計算價差序列
        """
        beta, alpha = self.find_hedge_ratio(x, y)
        spread = y - beta * x - alpha
        return spread, beta, alpha
    
    def check_cointegration(self, x, y):
        """
        協整性檢定
        """
        score, pvalue, _ = coint(x, y)
        return {
            'score': score,
            'pvalue': pvalue,
            'is_cointegrated': pvalue < 0.05
        }
    
    def calculate_z_score(self, spread):
        """
        計算 z-score
        """
        if len(spread) < self.lookback:
            return 0.0
            
        window = spread[-self.lookback:]
        mean = np.mean(window)
        std = np.std(window)
        
        if std == 0:
            return 0.0
            
        z = (spread.iloc[-1] - mean) / std
        return z
    
    def generate_signals(self):
        """
        生成交易信號
        """
        x = self.asset_x
        y = self.asset_y
        
        # 檢查協整性
        coint_result = self.check_cointegration(x, y)
        
        # 計算價差
        spread, beta, alpha = self.calculate_spread(x, y)
        z_score = self.calculate_z_score(spread)
        
        # 交易信號
        if abs(z_score) > self.entry_threshold:
            if z_score > 0:
                # X 被高估(相對於 Y)
                # 賣空 X,買入 Y
                return {
                    'action': 'SHORT_X_LONG_Y',
                    'z_score': z_score,
                    'beta': beta,
                    'is_cointegrated': coint_result['is_cointegrated']
                }
            else:
                # X 被低估(相對於 Y)
                # 買入 X,賣空 Y
                return {
                    'action': 'LONG_X_SHORT_Y',
                    'z_score': z_score,
                    'beta': beta,
                    'is_cointegrated': coint_result['is_cointegrated']
                }
        elif abs(z_score) < self.exit_threshold:
            return {
                'action': 'CLOSE',
                'z_score': z_score
            }
        
        return {'action': 'HOLD', 'z_score': z_score}

第三章:波動率溢價策略

3.1 波動率微笑與波動率溢價

比特幣期權市場存在顯著的波動率微笑(Volatility Smile)現象,這為波動率溢價策略提供了機會。

波動率微笑的定義

虛值期權(OTM)和實值期權(ITM)的隱含波動率(IV)通常高於平價期權(ATM),形成「微笑」形狀。

IV(K) = f(K),其中:
- K < S:虛值看跌期權,IV 較高
- K ≈ S:平價期權,IV 較低
- K > S:虛值看漲期權,IV 較高

波動率溢價的來源

  1. 尾部風險溢價:投資者願意支付溢價來對沖尾部風險
  2. 流動性溢價:深度虛值期權流動性較差,需要更高收益
  3. 供需結構:機構投資者的避險需求推動 OTM 期權價格

3.2 賣出波動率策略

最簡單的波動率溢價策略是賣出跨式套利(Short Straddle)賣出寬跨式套利(Short Strangle)

Short Straddle 策略

策略構建:
- 賣出 ATM 看漲期權(執行價格 K₁ = S)
- 賣出 ATM 看跌期權(執行價格 K₂ = S)

最大收益:
= 看漲期權權利金 + 看跌期權權利金
(當到期價格恰好等於 K 時實現)

潛在損失:
= 無限大(若比特幣價格大幅波動)
import numpy as np
from scipy.stats import norm

class BlackScholes:
    """
    Black-Scholes 期權定價模型
    """
    @staticmethod
    def call_price(S, K, T, r, sigma):
        """
        計算看漲期權價格
        """
        d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
        d2 = d1 - sigma*np.sqrt(T)
        
        call = S*norm.cdf(d1) - K*np.exp(-r*T)*norm.cdf(d2)
        return call
    
    @staticmethod
    def put_price(S, K, T, r, sigma):
        """
        計算看跌期權價格
        """
        d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
        d2 = d1 - sigma*np.sqrt(T)
        
        put = K*np.exp(-r*T)*norm.cdf(-d2) - S*norm.cdf(-d1)
        return put
    
    @staticmethod
    def implied_volatility(market_price, S, K, T, r, option_type='call'):
        """
        計算隱含波動率(牛頓-拉夫森法)
        """
        sigma = 0.5  # 初始猜測
        
        for _ in range(100):
            if option_type == 'call':
                price = BlackScholes.call_price(S, K, T, r, sigma)
            else:
                price = BlackScholes.put_price(S, K, T, r, sigma)
            
            diff = market_price - price
            
            if abs(diff) < 1e-6:
                break
                
            # Vega(對波動率的敏感性)
            d1 = (np.log(S/K) + (r + 0.5*sigma**2)*T) / (sigma*np.sqrt(T))
            vega = S*np.sqrt(T)*norm.pdf(d1)
            
            if vega == 0:
                break
                
            sigma = sigma + diff/vega
            
        return sigma


class VolatilityPremiumStrategy:
    """
    波動率溢價策略
    """
    def __init__(self, spot_price, risk_free_rate=0.05):
        self.spot_price = spot_price
        self.risk_free_rate = risk_free_rate
        self.bs = BlackScholes()
        
    def short_straddle_payoff(self, K, T, sigma_call, sigma_put, 
                              expiry_price, call_premium, put_premium):
        """
        計算 Short Straddle 到期收益
        """
        # 看漲期權收益(對賣方)
        if expiry_price > K:
            call_pnl = call_premium - (expiry_price - K)
        else:
            call_pnl = call_premium
            
        # 看跌期權收益(對賣方)
        if expiry_price < K:
            put_pnl = put_premium - (K - expiry_price)
        else:
            put_pnl = put_premium
            
        total_pnl = call_pnl + put_pnl
        
        return {
            'call_pnl': call_pnl,
            'put_pnl': put_pnl,
            'total_pnl': total_pnl,
            'max_profit': call_premium + put_premium,
            'breakeven_low': K - (call_premium + put_premium),
            'breakeven_high': K + (call_premium + put_premium)
        }
    
    def calculate_var(self, K, T, sigma, confidence_level=0.95):
        """
        計算 Value at Risk
        """
        z = norm.ppf(1 - confidence_level)
        daily_vol = sigma / np.sqrt(365)
        
        var_99 = self.spot_price * daily_vol * z * np.sqrt(1)
        
        return abs(var_99)
    
    def execute_short_straddle(self, days_to_expiry, atm_iv_spread=0.05):
        """
        執行 Short Straddle 策略
        """
        K = self.spot_price  # ATM 執行價格
        T = days_to_expiry / 365  # 轉換為年
        
        # 假設隱含波動率高於真實波動率
        implied_vol = 0.8 + atm_iv_spread
        realized_vol = 0.6  # 預期實現波動率
        
        # 計算期權價格
        call_premium = self.bs.call_price(
            self.spot_price, K, T, self.risk_free_rate, implied_vol
        )
        put_premium = self.bs.put_price(
            self.spot_price, K, T, self.risk_free_rate, implied_vol
        )
        
        total_premium = call_premium + put_premium
        
        # 計算希臘字母
        d1 = (np.log(self.spot_price/K) + (self.risk_free_rate + 0.5*implied_vol**2)*T) / (implied_vol*np.sqrt(T))
        gamma = norm.pdf(d1) / (self.spot_price * implied_vol * np.sqrt(T))
        theta_call = - (self.spot_price * norm.pdf(d1) * implied_vol) / (2*np.sqrt(T)) - \
                     self.risk_free_rate * K * np.exp(-self.risk_free_rate*T) * norm.cdf(d2) if 'd2' in dir() else 0
        
        return {
            'strike': K,
            'call_premium': call_premium,
            'put_premium': put_premium,
            'total_premium': total_premium,
            'implied_vol': implied_vol,
            'premium_as_pct': total_premium / self.spot_price * 100,
            'd1': d1,
            'gamma': gamma
        }
    
    def monte_carlo_var(self, K, T, sigma, n_simulations=10000, 
                       confidence_level=0.95):
        """
        蒙特卡羅模擬計算 VaR
        """
        np.random.seed(42)
        
        # 模擬價格路徑
        dt = 1/365
        n_steps = int(T * 365)
        
        price_paths = np.zeros((n_simulations, n_steps + 1))
        price_paths[:, 0] = self.spot_price
        
        for t in range(1, n_steps + 1):
            z = np.random.standard_normal(n_simulations)
            price_paths[:, t] = price_paths[:, t-1] * np.exp(
                (self.risk_free_rate - 0.5*sigma**2)*dt + sigma*np.sqrt(dt)*z
            )
        
        # 計算到期收益
        expiry_prices = price_paths[:, -1]
        
        # Short Straddle 收益
        call_payoff = np.maximum(expiry_prices - K, 0)
        put_payoff = np.maximum(K - expiry_prices, 0)
        
        # 假設已收取期權費
        total_pnl = -(call_payoff + put_payoff)
        
        # VaR 計算
        var = np.percentile(total_pnl, (1 - confidence_level) * 100)
        
        return {
            'var_95': var,
            'var_99': np.percentile(total_pnl, 1),
            'expected_shortfall_95': np.mean(total_pnl[total_pnl <= var]),
            'max_loss': np.min(total_pnl),
            'mean_pnl': np.mean(total_pnl)
        }

3.3 波動率套利

波動率套利(Volatility Arbitrage)策略試圖捕捉隱含波動率與預期實現波動率之間的差異。

核心思想

當隱含波動率(IV)> 預期實現波動率(RV)時,賣出期權是划算的(收取溢價)。

策略績效指標

波動率溢價 = IV - RV

若波動率溢價 > 0:持有賣出波動率倉位
若波動率溢價 < 0:持有買入波動率倉位
class VolatilityArbitrage:
    """
    波動率套利策略
    """
    def __init__(self, initial_capital=1000000):
        self.initial_capital = initial_capital
        self.current_capital = initial_capital
        
    def calculate_realized_volatility(self, returns, window=30):
        """
        計算滾動實現波動率
        """
        return returns.rolling(window=window).std() * np.sqrt(365)
    
    def calculate_iv_rv_spread(self, iv, rv):
        """
        計算 IV-RV 差額
        """
        return iv - rv
    
    def position_sizing(self, iv_rv_spread, vol_of_vol=0.3):
        """
        根據 IV-RV 差額計算倉位大小
        Kelly Criterion 調整版
        """
        edge = iv_rv_spread
        kelly_fraction = edge / (vol_of_vol ** 2)
        
        # 半 Kelly 保守估計
        adjusted_fraction = kelly_fraction * 0.5
        
        # 限制最大槓桿
        max_leverage = 2.0
        position_fraction = min(max(adjusted_fraction, 0), max_leverage)
        
        return position_fraction
    
    def backtest(self, price_data, iv_data, transaction_cost=0.001):
        """
        回測波動率套利策略
        """
        # 計算日收益率
        returns = price_data.pct_change().dropna()
        
        # 計算實現波動率
        rv = self.calculate_realized_volatility(returns)
        
        # 交易記錄
        trades = []
        position = 0
        entry_iv = None
        entry_price = None
        
        for i in range(len(returns)):
            if i < 30:  # 等待足夠的歷史數據
                continue
                
            current_rv = rv.iloc[i]
            current_iv = iv_data.iloc[i]
            current_price = price_data.iloc[i]
            
            spread = self.calculate_iv_rv_spread(current_iv, current_rv)
            
            if spread > 0.05 and position == 0:
                # 賣出波動率
                position_size = self.position_sizing(spread)
                entry_iv = current_iv
                entry_price = current_price
                position = position_size
                trades.append({
                    'date': i,
                    'action': 'SELL_VOL',
                    'iv': current_iv,
                    'rv': current_rv,
                    'spread': spread,
                    'position': position
                })
            elif position != 0:
                # 計算未實現盈虧
                realized_rv = current_rv
                
                # 如果實現波動率低於隱含波動率,獲利了結
                if realized_rv < entry_iv * 0.8:
                    pnl = position * (entry_iv - realized_rv) * self.current_capital
                    self.current_capital += pnl
                    trades.append({
                        'date': i,
                        'action': 'CLOSE',
                        'pnl': pnl,
                        'iv_exit': current_iv,
                        'rv_exit': current_rv
                    })
                    position = 0
                    entry_iv = None
        
        return {
            'trades': trades,
            'final_capital': self.current_capital,
            'total_return': (self.current_capital - self.initial_capital) / self.initial_capital,
            'num_trades': len(trades)
        }

第四章:回測方法論與風險管理

4.1 回測系統設計

完整的比特幣量化回測系統需要考慮以下要素:

數據處理

class BacktestEngine:
    """
    回測引擎
    """
    def __init__(self, initial_capital, commission=0.001, slippage=0.0005):
        self.initial_capital = initial_capital
        self.commission = commission
        self.slippage = slippage
        self.capital = initial_capital
        self.position = 0
        self.trades = []
        self.equity_curve = []
        
    def execute_trade(self, price, action, size=1.0):
        """
        執行交易(包含費用和滑點)
        """
        # 滑點調整
        if action == 'BUY':
            execution_price = price * (1 + self.slippage)
        else:
            execution_price = price * (1 - self.slippage)
        
        # 費用計算
        trade_value = execution_price * size
        fees = trade_value * self.commission
        
        return {
            'execution_price': execution_price,
            'fees': fees,
            'net_cost': trade_value + fees if action == 'BUY' else trade_value - fees
        }
    
    def calculate_metrics(self):
        """
        計算回測績效指標
        """
        if len(self.equity_curve) < 2:
            return {}
            
        equity = np.array(self.equity_curve)
        returns = np.diff(equity) / equity[:-1]
        
        # 年化收益
        n_days = len(equity)
        annual_return = (equity[-1] / equity[0]) ** (365 / n_days) - 1
        
        # 年化波動率
        annual_vol = np.std(returns) * np.sqrt(365)
        
        # 夏普比率
        risk_free_rate = 0.02
        sharpe_ratio = (annual_return - risk_free_rate) / annual_vol
        
        # 最大回撤
        running_max = np.maximum.accumulate(equity)
        drawdown = (equity - running_max) / running_max
        max_drawdown = np.min(drawdown)
        
        # 卡瑪比率
        calmar_ratio = annual_return / abs(max_drawdown) if max_drawdown != 0 else 0
        
        return {
            'total_return': (equity[-1] - equity[0]) / equity[0],
            'annual_return': annual_return,
            'annual_volatility': annual_vol,
            'sharpe_ratio': sharpe_ratio,
            'max_drawdown': max_drawdown,
            'calmar_ratio': calmar_ratio,
            'num_trades': len(self.trades),
            'win_rate': len([t for t in self.trades if t.get('pnl', 0) > 0]) / max(len(self.trades), 1)
        }

4.2 過擬合風險控制

量化策略回測面臨的主要風險之一是過擬合(Overfitting)。

Walk-Forward 分析

傳統回測:使用全部歷史數據訓練和測試
      |========== 訓練 ==========|========== 測試 ==========|
      2015                          2020                    2024

Walk-Forward:
      |=== 訓練 ===|=== 測試 ===|
      2015        2018        2021
                  |=== 訓練 ===|=== 測試 ===|
                  2018        2021        2024
def walk_forward_analysis(strategy_class, data, train_period=365, 
                         test_period=90, n_splits=10):
    """
    Walk-Forward 分析
    """
    results = []
    
    for i in range(n_splits):
        train_end = i * test_period
        test_start = train_end
        test_end = test_start + test_period
        
        train_data = data.iloc[train_end - train_period:train_end]
        test_data = data.iloc[test_start:test_end]
        
        # 訓練
        strategy = strategy_class()
        strategy.fit(train_data)
        
        # 測試
        test_result = strategy.backtest(test_data)
        
        results.append({
            'train_period': (train_end - train_period, train_end),
            'test_period': (test_start, test_end),
            'train_sharpe': test_result['train_sharpe'],
            'test_sharpe': test_result['test_sharpe'],
            'sharpe_ratio_change': test_result['test_sharpe'] - test_result['train_sharpe']
        })
    
    return pd.DataFrame(results)

4.3 情境分析與壓力測試

比特幣市場以其極端波動性著稱,壓力測試是量化策略風險管理的關鍵環節。

壓力測試情境

情境描述比特幣價格變動持續時間
Flash Crash短期急跌-30%1-2 天
熊市反轉中期下跌-70%6-12 月
交易所故障流動性枯竭-50%數小時
監管黑天鵝政策衝擊-40%1-2 週
流動性危機信用緊縮-80%3-6 月
def stress_test(strategy, historical_prices, scenarios):
    """
    壓力測試
    """
    results = {}
    
    for scenario_name, scenario_params in scenarios.items():
        # 應用情境到歷史數據
        modified_prices = apply_scenario(
            historical_prices, 
            **scenario_params
        )
        
        # 回測策略
        result = strategy.backtest(modified_prices)
        
        # 記錄結果
        results[scenario_name] = {
            'max_drawdown': result['max_drawdown'],
            'sharpe_ratio': result['sharpe_ratio'],
            'total_return': result['total_return'],
            'var_95': result.get('var_95', 0),
            'survived': result['max_drawdown'] > -0.5  # 回撤是否可控
        }
    
    return results

第五章:實務考量與合規要求

5.1 交易成本優化

比特幣量化交易的交易成本包括:

成本優化策略

class CostOptimizer:
    """
    交易成本優化器
    """
    def __init__(self, exchange_fee_maker=0.001, exchange_fee_taker=0.002,
                 network_fee_per_byte=10):
        self.fee_maker = exchange_fee_maker
        self.fee_taker = exchange_fee_taker
        self.network_fee_per_byte = network_fee_per_byte
        
    def estimate_network_fee(self, tx_size_bytes, fee_rate='fastest'):
        """
        估算網路費用
        fee_rate: 'slowest', 'half_hour', 'hour', 'fastest'
        """
        fee_rates = {
            'slowest': 5,
            'half_hour': 10,
            'hour': 15,
            'fastest': 30
        }
        
        rate = fee_rates.get(fee_rate, 10)
        return tx_size_bytes * rate * 1e-8  # 轉換為 BTC
    
    def calculate_total_cost(self, trade_value, side='buy', 
                            maker_taker='taker', tx_size=250):
        """
        計算總交易成本
        """
        # 交易所費用
        exchange_fee = trade_value * self.fee_taker if maker_taker == 'taker' else trade_value * self.fee_maker
        
        # 網路費用
        network_fee = self.estimate_network_fee(tx_size)
        
        # 滑點(估計)
        slippage = trade_value * 0.0005
        
        total_cost = exchange_fee + network_fee + slippage
        cost_pct = total_cost / trade_value * 100
        
        return {
            'exchange_fee': exchange_fee,
            'network_fee': network_fee,
            'slippage': slippage,
            'total_cost': total_cost,
            'cost_pct': cost_pct
        }
    
    def minimum_profitable_trade(self, expected_return_pct, trade_value):
        """
        計算最小盈利交易規模
        """
        total_cost = self.calculate_total_cost(trade_value)
        min_profit = total_cost['total_cost']
        min_return = min_profit / trade_value * 100
        
        return {
            'min_profitable_return_pct': min_return,
            'is_profitable': expected_return_pct > min_return
        }

5.2 風險控制框架

風險管理層級

第一層:策略層級風險控制
- 最大倉位限制(例:單策略不超過總資本 20%)
- 止損點設定(例:單筆虧損不超過 2%)
- 最大回撤門檻(例:策略回撤超過 15% 停止交易)

第二層:組合層級風險控制
- 相關性管理(避免高度相關的策略重複暴露)
- VaR 限制(例:99% VaR 不超過總資本 5%)
- 槓桿上限(例:總槓桿不超過 3 倍)

第三層:系統層級風險控制
- 熔斷機制(市場極端波動時自動停止)
- 流動性儲備(保持一定比例的現金應對贖回)
- 緊急贖回程序(應對大規模贖回的預案)
class RiskManager:
    """
    風險管理系統
    """
    def __init__(self, max_position_pct=0.2, max_loss_per_trade=0.02,
                 max_drawdown=0.15, max_leverage=3.0):
        self.max_position_pct = max_position_pct
        self.max_loss_per_trade = max_loss_per_trade
        self.max_drawdown = max_drawdown
        self.max_leverage = max_leverage
        self.current_drawdown = 0
        self.peak_capital = 0
        
    def check_position_limit(self, proposed_position, total_capital):
        """
        檢查倉位限制
        """
        proposed_pct = proposed_position / total_capital
        approved_pct = min(proposed_pct, self.max_position_pct)
        
        return {
            'approved': approved_pct > 0,
            'approved_position': total_capital * approved_pct,
            'reduced_pct': proposed_pct - approved_pct
        }
    
    def check_leverage(self, total_exposure, equity):
        """
        檢查槓桿限制
        """
        current_leverage = total_exposure / equity
        
        return {
            'current_leverage': current_leverage,
            'within_limit': current_leverage <= self.max_leverage,
            'reduction_needed': max(0, current_leverage - self.max_leverage)
        }
    
    def update_drawdown(self, current_capital):
        """
        更新回撤追蹤
        """
        if current_capital > self.peak_capital:
            self.peak_capital = current_capital
            
        self.current_drawdown = (self.peak_capital - current_capital) / self.peak_capital
        
        return {
            'current_drawdown': self.current_drawdown,
            'peak_capital': self.peak_capital,
            'circuit_breaker': self.current_drawdown >= self.max_drawdown
        }
    
    def daily_risk_report(self, portfolio, positions, open_orders):
        """
        生成每日風險報告
        """
        total_equity = portfolio['cash'] + sum(
            p['value'] for p in positions
        )
        
        # VaR 計算
        var_95 = self.calculate_var_95(portfolio['returns'])
        
        # 壓力測試
        stress_results = self.stress_test(positions)
        
        return {
            'total_equity': total_equity,
            'var_95': var_95,
            'current_drawdown': self.current_drawdown,
            'total_exposure': sum(p['value'] for p in positions),
            'leverage': sum(p['value'] for p in positions) / total_equity,
            'open_orders_count': len(open_orders),
            'stress_test': stress_results,
            'risk_status': 'GREEN' if self.current_drawdown < self.max_drawdown * 0.5 else \
                          'YELLOW' if self.current_drawdown < self.max_drawdown else 'RED'
        }

結論:比特幣量化交易的未來展望

比特幣量化交易是一個快速演進的領域,策略的有效性會隨著市場結構的變化而改變。以下是幾個值得關注的趨勢:

一、機構化程度提升

隨著比特幣現貨 ETF 的核准和機構採用率的提升,市場將變得更加有效,傳統的統計套利機會將減少。

二、衍生品市場深化

比特幣期權和結構化產品市場的發展將為波動率策略提供更多機會,同時也帶來更複雜的風險管理挑戰。

三、跨資產策略

比特幣與傳統資產(股票、黃金)、其他加密貨幣的相關性分析將成為組合配置的重要參考。

四、合規與透明化

隨著監管框架的完善,合規成本將成為量化策略設計的重要考量因素。

比特幣量化交易的本質是在風險與收益之間取得平衡。一個成功的比特幣量化策略不僅需要嚴謹的數學模型,還需要對比特幣生態系統的深刻理解、嚴格的風險管理、以及持續適應市場變化的能力。

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!