用多因子策略構建強大的加密資產投資組合 #大類因子分析:因子合成篇#

書接上回,關於《用多因子模型構建強大的加密資產投資組合》系列文章中,我們已經發布了三篇:《理論基礎篇》《數據預處理篇》《因子有效性檢驗篇》

前三篇分別解釋了多因子策略的理論與單因子測試的步驟。

一、因子相關性檢驗的原因:多重共線性

我們通過單因子測試部分篩選出一批有效因子,但以上因子不能直接入庫。因子本身可以根據具體的經濟含義進行大類劃分,同類型的因子間存在較強的相關性,若不經相關性篩選直接入庫,根據不同因子進行多元線性迴歸求預期收益率時,會出現多重共線性問題。計量經濟學中,多重共線性是指回歸模型中的一些或全部解釋變量存在“完全”或準確的線性關係(各變量間高度相關)。

因此,有效因子篩選出後,首先需要根據大類對因子的相關性進行T檢驗,對於相關性較高的因子,要麼捨棄顯著性較低的因子,要麼進行因子合成。

多重共線性的數學解釋如下:

$$$ Y = β₁ + β₂X₂ᵢ + β₃X₃ᵢ + ... + βₖXₖᵢ + μᵢ , i = 1,2,...,n $$$

會存在兩種情況:

1.$$C₂X₂ᵢ + C₃X₃ᵢ + … + CₖXₖᵢ = 常數向量$$,$$ Cᵢ$$不全為$$0→Xᵢ$$ 間存在完全共線

2.$$C₂X₂ᵢ + C₃X₃ᵢ + … + CₖXₖᵢ + Vᵢ = 常數向量$$,$$Cᵢ$$不全為0,$$Vᵢ$$為隨機誤差項,$$→Xᵢ$$間存在完全共線

多重共線性導致的後果:

1.完全共線性下參數估計量不存在

2.近似共線性下OLS估計量非有效

我們首先定義方差膨脹因子(variance- inflating factor, VIF)為 $$VIF=1 / (1 - rᵢⱼ)$$ ,指參數估計量的方差由於出現多重共線性而膨脹,隨著相關係數增加,VIF顯著增加。

以二元線性模型為例:$$Y = β₁ + β₂X₂ᵢ + β₃X₃ᵢ + μᵢ$$

$$$ var(β₂) = (σ²/ΣX²₂)·(1/(1-r²₂₃)) $$$

$$$ 相關係數的平方和r²₂₃=(ΣX₂ᵢX₃ᵢ)²/ ΣX²₂ᵢΣX²₃ᵢ ≤ 1 $$$

$$$ 1/(1-r²₂₃)≥ 1 $$$

  • 完全不共線(完全不相關):$$r²₂₃ = 0 → var(β₂) = σ²/ΣX²₂$$

  • 近似共線:$$0<r²₂₃<1 → var(β₂) = (σ²/ΣX²₂)·(1/(1-r²₂₃)) > σ²/ΣX²₂,越接近1,方差↑$$

  • 完全共線:$$r²₂₃ = 1 → var(β₂) = ∞,方差無限大$$

3.參數估計量經濟含義不合理

4.變量的顯著性檢驗(t檢驗)失去意義

5.模型的預測功能失效:通過多元線性模型擬合出的預測收益率極其不準確,模型失效。

二、步驟一:同類型因子的相關性檢驗

檢驗新求出的因子與已入庫因子的相關性。通常來說,有兩類數據求相關性:

1.根據所有token在回測期間的因子值求相關

2.根據所有token在回測期間的因子超額收益值求相關

$$$ 超額收益 = 多頭組收益 - 基準收益,收益 = ln(closeₜ / closeₜ ₋₁) $$$

我們所求的每個因子對token的收益率都有一定的貢獻和解釋能力。進行相關性檢驗**,是為了找到對策略收益有不同解釋和貢獻的因子,策略的最終目的是收益**。如果兩個因子對收益的刻畫是相同的,即使兩個因子值存在很大差別也無意義。因此,我們並不是想找到因子值本身差異大的因子,而是想找到因子對收益刻畫不同的因子,所以最終選擇了用因子超額收益值求相關。

我們的策略是日頻,所以按回測區間的日期計算因子超額收益之間的相關係數矩陣

編程求解與庫內相關最高的前n個因子:

 def get_n_max_corr(self, factors, n=1):
        factors_excess = self.get_excess_returns(factors)
        save_factor_excess = self.get_excess_return(self.factor_value, self.start_date, self.end_date)

        if len(factors_excess) < 1:
            return factor_excess, 1.0, None

        factors_excess[self.factor_name] = factor_excess['excess_return']
        factors_excess = pd.concat(factors_excess, axis=1)
        factors_excess.columns = factors_excess.columns.levels[0]

        # get corr matrix
        factor_corr = factors_excess.corr()
        factor_corr_df = factor_corr.abs().loc[self.factor_name]
        max_corr_score = factor_corr_df.sort_values(ascending=False).iloc[1:].head(n)
        
        return save_factor_excess, factor_corr_df, max_corr_score

三、步驟二:因子取捨、因子合成

對於相關性較高的因子集合,可以採取兩種方式處理:

(1)因子取捨

根據因子本身的ICIR值、收益率、換手率、Sharpe 比率,挑選某維度下最有效的因子進行保留,刪除其他因子。

(2)因子合成

對因子集合中的因子進行合成,截面上儘可能多的保留有效信息

$$$ F = w1 * f1 + w2f2+...+wnfn,F為最終的合成因子,f為需要進行合成的因子 $$$

假設當前有3個待處理的因子矩陣:

synthesis = pd.concat([a,b,c],axis = 1) 
synthesis
a	b	c
BTC.BN	0.184865	-0.013253	-0.001557
ETH.BN	0.185691	0.022708	0.031793
BNB.BN	0.242072	-0.180952	-0.067430
LTC.BN	0.275923	-0.125712	-0.049596
AAVE.BN	0.204443	-0.000819	-0.006550
...	...	...	...
SOC.BN	0.231638	-0.095946	-0.049495
AVAX.BN	0.204714	-0.079707	-0.041806
DAO.BN	0.194990	0.022095	-0.011764
ETC.BN	0.184236	-0.021909	-0.013325
TRX.BN	0.175118	-0.055077	-0.039513

2.1 等權加權

各因子權重相等$$( w = 1/因子個數 )$$,綜合因子=各因子值加總求平均。

Eg.動量類因子,一個月收益率、兩個月收益率、三個月收益率、六個月收益率、十二個月收益率,這六個因子的因子載荷各佔1/6的權重,合成新的動量因子載荷,然後再重新進行標準化處理。

synthesis1 = synthesis.mean(axis=1) # 按行求均值

2.2 歷史IC加權、歷史ICIR、歷史收益加權

用回測期的IC值(ICIR值、歷史收益值)對因子進行加權。過去有很多期,每一期都有一個IC值,所以用它們的均值作為因子的權重。通常使用回測期IC的均值(算數平均值)作為權重。

# 權重歸一化(後文中的因子加權方式也基本都需要進行權重歸一化)
w_IC = ic.mean() / ic.mean().sum()
w_ICIR = icir.mean() / icir.mean().sum()
w_Ret = Return.mean() / Return.mean().sum()

synthesis2 = (synthesis * w_IC).sum(axis=1)
synthesis2 = (synthesis * w_ICIR).sum(axis=1)
synthesis2 = (synthesis * w_Ret).sum(axis=1)

2.3歷史IC半衰加權、歷史ICIR半衰加權

2.1與2.2都是計算算數平均值,回測期的每一次IC、ICIR對於因子的作用被默認為相同。

但現實中,回測期的每一期對於當期的影響程度不完全相同,存在時間上的衰減。越接近當前期的時期,影響越大,越遠影響越小。在此原理,求IC權重前首先定義一個半衰權重,距離當期越近的權重值越大、越遠權重越小。

半衰權重數學推導:

\* 半衰期H:每向前推H期,權重值以指數下降的方式降低一半\* T:考慮回測的期數

# 半衰權重
def Decay(H,T):
    t = np.arange(T+1)[1:]
    wt = 2**((t-T-1)/H) #半衰權重
    decay = wt/wt.sum() #歸一化
    return decay
  
# 歷史IC半衰加權
w_bs = Decay(6,12) # 假設T=12,H=6
ic_bs = ic.mul(w_bs,axis=0)
w = ic_bs.mean()/ic.mean().sum()
synthesis3 = (synthesis * w).sum(axis=1)

# 歷史ICIR半衰加權
# 歷史ICIR半衰加權在歷史IC半衰加權的基礎上,除以IC值的標準差。
w_bs = bs(6,12)
ic_bs = ic.mul(w_bs,axis=0)
ir_bs = ic_bs.mean()/ic.std()
w = ir_bs.mean()/ir_bs.mean().sum()
synthesis3 = (synthesis * w).sum(axis=1)

2.4 最大化ICIR加權

通過求解方程,計算最優因子權重w使得ICIR最大化

協方差矩陣的估計問題:協方差矩陣用於衡量不同資產之間的關聯性。統計學中常以樣本協方差矩陣代替總體協方差矩陣,但在樣本量不足時,樣本協方差矩陣與總體協方差矩陣的差異會很大。所以有人提出了壓縮估計的方法,原理是使估計協方差矩陣與實際協方差矩陣之間的均方誤差最小

方式:

1.樣本協方差矩陣

# 最大化ICIR加權(樣本協方差)
ic_cov = np.array(ic.cov())
inv_ic_cov = np.linalg.inv(ic_cov)
ic_vector = np.mat(ic.mean())
w = inv_ic_cov * ic_vector.T
w = w / w.sum() 
synthesis4 = (synthesis * pd.DataFrame(w,index=synthesis.columns)[0]).sum(axis=1)

2.Ledoit-Wolf收縮:引入一個縮小系數,將原始的協方差矩陣與單位矩陣進行混合,以減少噪音的影響。

# 最大化ICIR加權(Ledoit-Wolf壓縮估計協方差)
from sklearn.covariance import LedoitWolf
model=LedoitWolf()
model.fit(ic)
ic_cov_lw = model.covariance_
inv_ic_cov = np.linalg.inv(ic_cov_lw)
ic_vector = np.mat(ic.mean())
w = inv_ic_cov*ic_vector.T
w = w/w.sum()
synthesis4 = (synthesis * pd.DataFrame(w,index=synthesis.columns)[0]).sum(axis=1)

3.Oracle近似收縮:對Ledoit-Wolf收縮的改進,目標是通過對協方差矩陣進行調整,從而在樣本大小較小的情況下更準確地估計真實的協方差矩陣。(編程實現與Ledoit-Wolf收縮同理)

2.5 主成分分析PCA

主成分分析(Principal Component Analysis,PCA)是一種用於降維和提取數據主要特徵的統計方法。其目標是通過線性變換,將原始數據映射到一個新的座標系,使得數據在新座標系下的方差最大化。

具體而言,PCA首先找到數據中的主成分,也就是數據中方差最大的方向。然後,它找到與第一個主成分正交(無關)且具有最大方差的第二個主成分。這個過程一直重複,直到找到數據中所有的主成分。

# 主成分分析(PCA)
from sklearn.decomposition import PCA
model1 = PCA(n_components=1)
model1.fit(f)
w=model1.components_
w=w/w.sum()
weighted_factor=(f*pd.DataFrame(w,columns=f.columns).iloc[0]).sum(axis=1)

關於LUCIDA & FALCON

Lucida (https://www.lucida.fund/ )是行業領先的量化對沖基金,在2018年4月進入Crypto市場,主要交易CTA / 統計套利 / 期權波動率套利等策略,現管理規模3000萬美元。

Falcon (https://falcon.lucida.fund /)是新一代的Web3投資基礎設施,它基於多因子模型,幫助用戶“選”、“買”、“管”、“賣”加密資產。Falcon在2022年6月由Lucida所孵化。

更多內容可訪問 https://linktr.ee/lucida_and_falcon

往期文章

Mirror
免責聲明:以上內容僅為作者觀點,不代表Followin的任何立場,不構成與Followin相關的任何投資建議。
喜歡
收藏
評論