alpha值计算 qcolor_量化交易与机器学习(四):如何研究alpha因子
算法交易策略由指示何時購買或出售資產以產生相對于基準(例如指數)的較高回報的信號驅動。 資產回報率中未通過暴露于該基準而無法解釋的部分稱為alpha,因此旨在產生這種不相關收益的信號也稱為alpha因子。
本章主要介紹alpha因子
一、從數據到信號
Alpha因子是原始數據(raw data)的轉換,旨在預測資產價格的變動。它們旨在捕獲驅動資產回報的風險。每當策略評估因子以獲得信號時,因子可以組合一個或多個輸入,但為每種資產輸出只有單個值。交易決策可能依賴于跨資產的相對因子值或單個資產的形式。
在第一章中我們了解到,alpha因子的工作流程分為兩個階段:研究流程和執行流程。本章重點講研究階段。 下一章將介紹執行階段。 其余部分將重點介紹如何利用機器學習從數據中學習新因子并有效地匯總來自多個alpha因子的信號。
alpha因子是預測市場數據,基本數據和另類數據的轉變的信號。 一些因子描述了整個經濟領域的基本變量,例如增長,通貨膨脹,波動性,生產率和人口風險。其他因子代表投資風格,例如價值或增長,以及可以交易并因此由市場定價的動量投資。 還有一些因子可以根據經濟學或金融市場的制度設置或投資者的行為來解釋價格走勢,包括這種已知的行為偏差。
因子背后的經濟學理論可能是理性的(rational),因此,因子在長期具有高回報,以彌補在困難時期的低回報。 這也可能是行為的(behavioral),因子風險溢價是由未套利的代理人的行為可能存在偏見或不完全理性所致。
人們一直在尋找和發現新的因子,以更好地捕捉已知的因子或反映新的回報驅動因子。 管理著近2000億美元的Research Affiliates公司的聯合創始人Jason Hsu確定了截止到2015年已用經驗證據在知名期刊上發表的約250個因子。他估計這一數字每年可能會增加40。
為了避免錯誤的發現并確保一個因子產生一致的結果,它應該基于各種已建立的因子類別(例如動量,價值,波動性或質量及其原理)具有有意義的經濟直覺,我們將在下一部分中概述。 這使得該因素反映出市場將要補償的風險更為合理。
alpha因子是通過使用簡單的算術,例如變量隨時間的絕對或相對變化,數據序列之間的比率或在時間窗內的匯總(如簡單或指數移動平均值)對原始市場數據,基本數據或替代數據進行轉換而產生的。 它們還包括從價格和數量模式的技術分析中得出的指標,例如需求與供應的相對強度指數(RSI)以及從證券基礎分析中熟悉的眾多指標。 Kakushadze于2016列出了101個alpha因子的公式,在撰寫本文時,其中80%已用于WorldQuant對沖基金的生產中。
從歷史上看,交易策略將簡單的排名試探法,價值閾值或分位數法應用于對整個投資領域中的多種證券計算的一個或幾個alpha因子。例子包括價值投資方法,該方法在沃倫·巴菲特最喜歡的一本書《證券分析》(Security Analysis)中流行,該書由Graham和Dodd(1934)撰寫,它依賴于諸如市銷率之類的指標。
Eugene Fama(曾獲得2013年諾貝爾經濟學獎)和Kenneth French領導了有關預測高于市場收益的alpha因子的現代研究,他們提供了有關規模和價值因子的證據(1993年)。 這項工作得出了FF三因子和FF五因子模型。洪崇理(Andrew Ang)是貝萊德(BlackRock)公司的因子策略頭目,其管理近7億美金,他于2014年撰寫了一篇關于現代因子投資的精彩絕倫的綜述。
我們將在之后的文章中看到,在沒有確定的公式的情況下,機器學習在學習直接從更多樣化,更大得多的輸入數據集中直接提取信號方面是非常有效的。 但是,正如我們還將看到的那樣,Alpha因子對于機器學習模型仍然是有用的輸入,它比手動設置規則以更優化的方式組合了它們的信息內容。
結果,當今的算法交易策略會利用大量信號,其中許多信號可能單獨使用功效較弱,但通過機器學習算法與其他模型驅動或傳統因子結合使用時,其可以產生可靠的預測。
二、著名因子合輯
本文只挑選部分因子,目的是用來給大家做介紹,之后會專門出一片文章,其包含海量因子以及有對應的因子解釋
1. 動量與情緒因子
1993年,Jegadeesh和Titman通過定量證據展示了動量因子在美國股票市場的有效性,從此,動量投資一直是最完善的因子策略之一。“趨勢是您的朋友,或讓您的贏家奔跑”(the trend is your friend or let your winners run)。 動量因子旨在使表現良好的資產多頭,而在一定時期內使表現不佳的資產空頭。 擁有2000億美元對沖基金AQR的創始人克利福德·阿內斯(Clifford Asness)最近提供了證據,證明了八種不同資產類別和市場的動量效應。
使用此因子的策略的前提是資產價格呈現趨勢,并以正的序列相關性反映出來。這種價格動量反駁了有效市場的假設,即市場僅憑過去的價格回報無法預測未來的表現。盡管有理論相反的觀點,價格動量策略已在資產類別中產生了正收益,并且是許多交易策略的重要組成部分。
下圖顯示了根據對各種alpha因子的影響而形成的投資組合的歷史表現(使用Fama-French網站的數據)。 因子 winner-minus-loser(WML)代表在前2到12個月的收益率中,包含美國股市前三名和后三名的股票投資組合之間的業績差異:
直到2008年危機,動量因子都大大超過了其他突出的風險因子。 其他因子包括High-Minus-Low(HML)價值因子,Robust-Minus-Weak(RMW)盈利能力因子和Conservative-Minus-Aggressive(CMA)投資因子。 股權溢價是市場回報率(例如,標準普爾500指數)與無風險利率之差。
為什么動量和情緒會推動超額收益?
動量效應的原因有以下幾個:投資者的行為、持續的供需失衡、風險資產與經濟之間的正反饋回路或市場微觀結構。
行為理論(behavioral rationale)反映了當投資者以不同的速度處理新信息時,反應不足和反應過度的偏見。 在最初對新聞反應不足之后,投資者通常會推斷過去的行為并創造價格動能。 90年代末市場泡沫期間的技術股反彈是一個極端的例子。 恐懼和貪婪的心理也促使投資者增加對獲勝資產的敞口,并繼續出售虧損資產。
動量也可以具有基本面驅動因素(fundamental drivers),例如風險資產與經濟之間的正反饋回路。 經濟增長提振了股票,由此產生的財富效應通過增加支出將其反饋到經濟中,再次推動了增長。價格和經濟之間的正反饋通常將股票和信貸的勢頭延伸到更長的期限,而債券,FOEX和商品則要長得多,而負反饋會導致逆轉,因此需要更短的投資期限。動力的另一個原因可能是由于市場摩擦而導致的持續供需失衡。一個例子是商品生產在適應不斷變化的需求方面的延遲。多年來,石油產量可能滯后于經濟蓬勃發展帶來的更高需求,持續的供應短缺可能觸發并支撐價格上漲的勢頭。
在短期內,當投資者實施模仿其偏見的策略時,市場微觀結構效應也可產生價格動能。 例如,減少損失并獲利的交易智慧使投資者使用諸如止損,恒定比例投資組合保險(CPPI),動態三角套期保值之類的交易策略,或基于保護性看跌期權的基于期權的策略。 這些策略之所以能產生動力,是因為它們暗示了資產表現不佳時賣出和資產表現極好時買入的事先承諾。
同樣,風險平價策略傾向于購買經常表現為正的低波動率資產,并出售通常表現為負的高波動率資產。 使用這些策略的投資組合自動重新平衡,往往會增強價格動能。
如何衡量動量和情緒
動量因子通常是通過識別趨勢和模式從價格時間序列的變化得出的。通過比較資產的橫截面或分析資產的時間序列(在傳統資產類別之內或之間以及在不同時間范圍內),可以基于絕對或相對回報來構建它們。
以下是一些例子(以下全用英文顯示因子名稱)
其他情緒指標包括以下指標: 可以從諸如Quandl或Bloomberg等數據提供者那里獲得諸如分析師估計之類的輸入:
也有許多數據提供商旨在提供從社交媒體(如Twitter)構建情緒指標。我們在之后講自然語言處理中時會構建自己的指標。
2. 價值因子
價格相對于基本價值而言較低的股票往往會提供超過資本加權基準的回報。價值因子反映了這種相關性,旨在為相對便宜的被低估資產發送購買信號,為被高估的資產出售信號。因此,任何價值策略的核心都是一個模型,用于估計資產的公允或基本價值。公允價值可以定義為絕對價格水平,相對于其他資產的價差或資產應交易的范圍。
相對價值策略
價值策略依賴于資產的公允價值的均值回歸。 他們認為,價格只是由于過度反應或羊群效應等行為影響或暫時性市場影響或長期供需摩擦等流動性影響而暫時偏離公允價值。 價值因子通常表現出與動量因子相反的性質,因為它們依賴均值回歸。 對于股票而言,與價值股相反的是增長股票,由于增長預期,它們的估值很高。
價值因子支持廣泛的系統策略,包括基本面和市場估值以及交叉資產相對價值。 它們通常被統稱為統計套利(StatArb)策略,以與市場無關的多頭/空頭投資組合實施,而不會面臨其他傳統或替代風險因素。
基本面價值策略
基本面價值策略從取決于目標資產類別的經濟和基本指標中得出公允資產價值。 在固定收益類產品,貨幣和商品中,指標包括資本賬戶余額,經濟活動,通貨膨脹或資金流量的水平和變化。 對于股票和公司債,價值因素可以追溯到Graham和Dodd先前提到的Security Analysis。 股權價值方法將股票價格與基本指標(例如賬面價值,頂線銷售,底線收益或各種現金流量指標)進行比較。
市值策略
市值策略使用統計或機器學習模型來識別由于流動性供應效率低下而導致的定價錯誤。統計和指數套利是突出的例子,可以捕捉到短期內市場對臨時市場影響的逆轉。在更長的時間范圍內,市場價值交易還利用股票和商品的季節性影響。
交叉資產相對價值策略
跨資產相對價值策略側重于跨資產類別的定價錯誤。例如,可轉換債券套利涉及可轉換為債券的債券與單個公司的基礎股票之間的相對價值的交易。相對價值策略還包括信貸和股票波動之間的交易,使用信貸信號交易股票或商品與相關股票之間的交易。
價值因子為何有助于預測收益
價值效應的存在有理性上和行為上的解釋,價值效應定義為價值股票投資組合相對于成長股票投資組合的超額收益,其中前者的市場價值低而后者的市場價值高。相對于基本面,我們將從大量研究中列舉一些突出的例子。
從理性、有效的市場角度來看,價值溢價彌補了較高的實際或感知風險。 研究人員提供的證據表明,與精益和較靈活的成長型公司相比,價值公司對不利的經濟環境的適應能力較弱,或者價值股票風險與較高的財務杠桿和更不確定的未來收益有關。 與價值型和大型股票投資組合相比,成長型和小型股票投資組合對宏觀沖擊的敏感性也更高。
從行為的角度來看,價值溢價可以用損失規避和心理會計偏見來解釋。由于先前收益提供的緩沖,投資者可能不太擔心近期表現強勁的資產損失。 這種損失規避的偏見使投資者認為股票的風險比以前低,并以較低的利率折現未來現金流量。相反,近期表現不佳可能會導致投資者提高資產的折現率。
這些不同的回報期望可以產生價值溢價:相對于基本面而言,具有高價格倍數的成長型股票在過去表現良好,但由于投資者對低風險的偏見,投資者未來的平均回報將較低。 適用于價值股。
量化價值因子
從基本面數據中可以計算出大量估值的因子。 這些因子可以組合為機器學習評估模型的輸入,以預測資產價格。 以下示例適用于股票,我們將在之后的文章中了解如何使用其中一些因子:
3. 波動性和規模因子
規模效應是較早的風險因子之一,并且與低市值的股票過剩表現有關。 最近,低波動率因子已顯示出捕獲低于平均波動率,β或特質風險的股票的超額收益的能力,同時市值較大的股票往往具有較低的波動性,因此傳統的規模因子通常與較新的波動性因子相結合。
低波動率異常是一個實證中的難題,它與金融的基本原理不符。 資本資產定價模型(CAPM)和其他資產定價模型斷言,較高的風險應獲得較高的回報,但是在眾多市場和較長時期內,情況恰恰相反。 風險較小的資產優于風險較高的同類資產。
下圖繪制了1990-2019年標準普爾500指數收益率相對于VIX指數的滾動平均值(VIX指數衡量了標準普爾100指數平價期權的隱含波動率)。它說明了股票收益率和這種波動率的度量如何反向變化,在此期間負相關系數為-0.54。 除了這種綜合效應外,還有證據表明,對VIX變動更敏感的股票表現更差。
為何波動性和規模因子有助于預測收益
低波動率異常與有效市場的假設和CAPM假設相矛盾。目前已經提出了幾種行為解釋來解釋其存在。
彩票效應,即個人進行類似于彩票的投注,但預期損失較小,但潛在獲勝機會很大,即使該獲勝機會可能性很小。 如果投資者認為低價,波動性股票的風險收益狀況就像一張彩票,那么這可能是一個有吸引力的選擇。 結果,由于偏好偏頗,投資者可能會為高波動性股票支付過多的費用,而為低波動性股票支付不足的費用。
代表性偏見,投資者將一些廣為人知的波動性股票的成功推斷為所有波動性股票,而忽略了此類股票的投機性質。
投資者對未來的預測能力可能也過于自信,對于波動性較大,結果不確定性更大的股票,他們的觀點差異更大。 由于做多(即擁有資產)表達積極觀點要比做空(消極觀點)消極觀點要容易,因此樂觀主義者的數量可能超過悲觀主義者,并繼續推高波動性股票的價格,從而導致回報降低。
此外,在牛市和熊市期間,投資者的行為也有所不同。 在牛市期間,beta系數的分散性要低得多,因此,低波動性股票的表現不會太差,即使有的話也不行,而在危機期間,投資者尋求或保持低波動性股票,貝塔的分散性會增加。 因此,長期來看,波動性較低的資產和投資組合的表現更好。
如何衡量波動率和規模
用于識別低波動性股票的指標涵蓋范圍很廣,一邊實現了波動率(標準差),另一邊則進行了預測(隱含)波動率和相關性。 有些將低波動性作為低beta值進行操作。 支持波動率異常的證據對于不同指標似乎很可靠。
4. 質量因子
質量因子旨在獲取高利潤,高效運營,安全,穩定且管理良好(簡而言之,高質量)的公司的超額收益。 市場似乎還會獎勵相對確定的收益,并對收益波動較大的股票進行懲罰。
長期以來,依賴基本面分析的選股者一直提倡向高質量業務傾斜的投資組合,但這在量化投資中是相對較新的現象。 面臨的主要挑戰是,鑒于質量的主觀性,如何使用定量指標客觀地定義質量因子。
基于獨立質量因子的策略往往以反周期的方式執行,因為投資者支付一些溢價以最大程度地降低下行風險并提高估值。 因此,在多因子策略中,質量因子通常會與其他風險因子結合在一起。
多空質量因子往往具有負的beta,因為多頭是具有低波動性的優質股票,而空頭則是更具波動性的低質股票。因此,質量因子通常與低波動性和動量因子正相關,而與價值和廣闊的市場敞口等因子負相關。
為什么質量因子很重要
質量因素可能預示著表現極佳,因為,諸如持續盈利、現金流量穩定增長、謹慎杠桿、資本市場融資需求低或金融風險低等優越的基礎支撐了對股票的需求,并長期支撐著這類公司的價格。 從公司融資的角度來看,優質公司通常會謹慎管理其資本,并降低過度利用或資本過多的風險。
行為上的解釋表明,投資者對質量信息的反應不充分,類似于動量因子的原理,即投資者追逐贏家和輸家。
關于優質溢價的另一個論點是羊群效應,類似于成長型股票。 基金經理可能會發現,即使股價變高,購買一家具有強大基本面的公司,也比波動性更大(風險)的股票更容易有說服力。
如何衡量質量
質量因子依賴于從資產負債表和損益表計算得出的指標,這些指標從更高的利潤率或現金流量利潤率、運營效率、財務實力和競爭力中更廣泛地反映出盈利能力,因為它暗示了隨著時間的推移維持盈利能力的能力。
因此,質量是使用毛利潤率、投資資本回報率、低收益波動率或多者結合來衡量的各種盈利能力,收益質量和杠桿指標,并在下表中列出了一些選項。
盈余管理主要通過操縱應計項目進行。因此,應計金額的大小通常被用作收入質量的代表:相對于資產而言,更高的總應計金額使低收入質量的可能性更大。但是,這并不是明確的,因為應計項目可以反映收益操縱以及對未來業務增長的會計估計:
我們已經對alpha因子進行了高級分類,這些分類已顯示出不同程度的異常收益。現在,我們將開始根據市場,基本面數據和替代數據開發自己的財務特征。
三、如何搭建因子
基于對關鍵因子的類別、原理和流行指標的計算方式,一項關鍵任務是確定可以更好地捕捉先前設定的收益驅動因素所體現的風險的新因素,或者尋找新的因素。 無論哪種情況,將創新因子的性能與已知因子的性能進行比較以識別增量信號增益都是很重要的。
有助于將數據轉換為因子的關鍵工具包括用于數值計算的Python庫,NumPy和pandas,以及用于技術分析的專用庫TA-Lib的Python包裝器。 替代方法包括Zura Kakushadze在2016年的論文中開發的表達式alphas 101公式化Alphas,并由alphatools庫實現。 此外,Quantopian平臺提供了大量內置因子,可加快研究過程。
要將一個或多個因子應用于投資領域,我們可以使用Zipline回測庫(其中也包含一些內置因素),并使用Alphalens庫來評估其績效。
1. 用pandas和numpy構建因子
NumPy和pandas是自定義因子計算的關鍵工具。 本節演示如何使用它們快速計算產生各種alpha因子的轉換。
Travis Oliphant于2005年通過整合自1990年代中期以來開發的較老的Numeric和Numarray庫創建了用于科學計算的NumPy庫。 它以稱為ndarray的高性能n維數組數據結構進行組織,可實現與MATLAB相當的功能。
Wes McKinney在AQR Capital Management工作時創造了pandas。 它提供了基于NumPy的ndarray的DataFrame數據結構,但允許通過基于標簽的索引進行更加用戶友好的數據操作。它包括各種特別適合金融數據的計算工具,包括具有自動日期對齊功能的豐富時間序列操作,我們將在這里進行探討。
以下各節說明了將原始股票價格數據轉換為選定因子的一些步驟。
Loading, slicing, reshaping
在之前加載了美國股票的Quandl Wiki股票價格數據后,我們通過將pd.IndexSlice應用于pd.MultiIndex來選擇2000-2018個時間片段,這里面包含時間戳和股票代碼信息。 然后,我們使用.stack()方法選擇并取消調整后的收盤價列,以將DataFrame轉換為寬格式,在各列中加上代碼,在各行中添加時間戳:
idx = pd.IndexSlice with pd.HDFStore('../../data/assets.h5') as store:prices = (store['quandl/wiki/prices'].loc[idx['2000':'2018', :], 'adj_close'].unstack('ticker')) prices.info() ''' DatetimeIndex: 4706 entries, 2000-01-03 to 2018-03-27 Columns: 3199 entries, A to ZUMZ '''Resampling
為了減少訓練時間并嘗試使用更長的時間范圍的策略,我們使用可用的調整后收盤價將每日業務數據轉換為月末頻率:
monthly_prices = prices.resample('M').last()如何計算多歷史周期的收益率
為了捕獲動量模式之類的時間序列動態,我們使用pct_change(n_periods)方法計算歷史多周期收益,其中n_periods表示滯后的次數。然后,我們使用.stack()將寬結果轉換回長格式。隨后,我們使用.pipe()將.clip()方法應用于獲得的DataFrame,并用winsorize縮尾,返回[1%,99%]排位的數據; 也就是說,我們將異常值限制在這些百分比上。
最后,我們使用幾何平均值對收益進行歸一化。使用.swaplevel()更改MultiIndex級別的順序后,我們獲得了六個不同時期(從1到12個月不等)的復合月收益:
outlier_cutoff = 0.01 data = pd.DataFrame() lags = [1, 2, 3, 6, 9, 12] for lag in lags:data[f'return_{lag}m'] = (monthly_prices.pct_change(lag).stack().pipe(lambda x:x.clip(lower=x.quantile(outlier_cutoff),upper=x.quantile(1-outlier_cutoff))).add(1).pow(1/lag).sub(1)) data = data.swaplevel().dropna() data.info() ''' MultiIndex: 521806 entries, (A, 2001-01-31 00:00:00) to (ZUMZ, 2018-03- 31 00:00:00) Data columns (total 6 columns): return_1m 521806 non-null float64 return_2m 521806 non-null float64 return_3m 521806 non-null float64 return_6m 521806 non-null float64 return_9m 521806 non-null float64 return_12m 521806 non-null float6 '''計算因子的beta
我們將在之后介紹利用Fama-French數據,以估計資產在常見風險因子中的敞口。 Fama-French的五個因子,即系統風險,市場規模,市值,盈利能力和投資,已在實證中證明了可解釋資產收益率。 它們通常用于評估投資組合對知名風險和回報驅動因素的敞口,其中無法解釋的部分則歸因于管理者的特質。 因此,自然而然地將過去的因素敞口作為財務特征納入旨在預測未來收益的模型中。
我們可以使用pandas-datareader訪問歷史因子收益,并使用pyfinance庫中的PandasRollingOLS滾動線性回歸功能估算歷史風險,如下所示:
factors = ['Mkt-RF', 'SMB', 'HML', 'RMW', 'CMA'] factor_data = web.DataReader('F-F_Research_Data_5_Factors_2x3','famafrench', start='2000')[0].drop('RF', axis=1) factor_data.index = factor_data.index.to_timestamp() factor_data = factor_data.resample('M').last().div(100) factor_data.index.name = 'date' factor_data = factor_data.join(data['return_1m']).sort_index() T = 24 betas = (factor_data.groupby(level='ticker', group_keys=False).apply(lambda x: PandasRollingOLS(window=min(T, x.shape[0]-1), y=x. return_1m, x=x.drop('return_1m', axis=1)).beta))之后我們會更詳細的進行進一步的因子分析工作。
添加動量因子
我們可以使用1個月和3個月的結果來計算簡單的動量因子。下面的代碼示例演示如何計算較長時期的收益與最近的每月收益之間的差異,以及如何計算3個月和12個月收益之間的差異:
for lag in [2,3,6,9,12]:data[f'momentum_{lag}'] = data[f'return_{lag}m'].sub(data.return_1m) data[f'momentum_3_12'] = data[f'return_12m'].sub(data.return_3m)增加時間列來捕捉季節效應
基本因子還包括季節性,例如一月效應,據觀察,該異常會導致本月股票上漲(這可能是出于稅收原因)。我們可以通過代表特定時間段(例如年份和/或月份)的指標變量來模擬這些季節性影響。 可以這樣生成:
dates = data.index.get_level_values('date') data['year'] = dates.year data['month'] = dates.month創造滯后收益特征
如果要使用滯后收益,即使用以前期間的收益作為輸入變量或特征來訓練一個學習收益模型以預測未來收益的模型,則可以使用.shift()方法將歷史收益向上移動到當前收益期。以下示例將1到6個月前的收益率上移相應的滯后,以便將其與當月的觀察值關聯:
for t in range(1, 7):data[f'return_1m_t-{t}'] = data.groupby(level='ticker').return_1m.shift(t)創造超前收益特征
同樣,您可以使用帶有負周期的.shift()來創建當前期間的遠期收益,即將來將要發生的收益(假設您的數據按升序排序):
for t in [1,2,3,6,12]:data[f'target_{t}m'] = (data.groupby(level='ticker')[f'return_{t}m'].shift(-t))2. 如何使用TA-Lib創建alpha因子
TA-Lib是用C ++編寫的帶有Python接口的開放源代碼庫,它被交易軟件開發人員廣泛使用。它包含用于技術分析的200多個流行因子的標準化實現;這些指標僅使用市場數據,即市場價格和市場數量信息。
TA-Lib與pandas和NumPy兼容,因此使用非常簡單。 以下示例演示了如何計算兩個流行因子。
布林帶(Bollinger Bands)由一個簡單的移動平均線(SMA)組成,它周圍環繞著兩個在SMA上下的滾動標準偏差的帶。當價格分別跌落到上下兩端的兩個波段之外時,它存在潛在超買/超賣情況。 實際上,發明人John Bollinger推薦了一種由22條規則生成交易信號的交易系統。
我們可以用如下所示的代碼計算布林帶,并且為了進行比較,可以計算本節前面介紹的有關流行alpha因子的相對強度指數(RSI)。
我們加載單個股票的調整后的收盤價(下面的例子為AAPL):
with pd.HDFStore(DATA_STORE) as store:data = (store['quandl/wiki/prices'].loc[idx['2007':'2010', 'AAPL'],['adj_open', 'adj_high', 'adj_low', 'adj_close','adj_volume']].unstack('ticker').swaplevel(axis=1).loc[:, 'AAPL'].rename(columns=lambda x: x.replace('adj_', '')))然后,我們通過相關的TA-Lib函數傳遞一維pd.Series:
from talib import RSI, BBANDS up, mid, low = BBANDS(data.close, timeperiod=21, nbdevup=2, nbdevdn=2, matype=0) rsi = RSI(adj_close, timeperiod=14)然后,我們將結果收集到一個DataFrame中,并用AAPL股票價格和30/70線的RSI繪制布林帶,這表明了多空的機會:
data = pd.DataFrame({'AAPL': data.close, 'BB Up': up, 'BB Mid': mid, 'BB down': low, 'RSI': rsi}) fig, axes= plt.subplots(nrows=2, figsize=(15, 8)) data.drop('RSI', axis=1).plot(ax=axes[0], lw=1, title='Bollinger Bands') data['RSI'].plot(ax=axes[1], lw=1, title='Relative Strength Index') axes[1].axhline(70, lw=1, ls='--', c='k') axes[1].axhline(30, lw=1, ls='--', c='k')如下圖所示,結果參差不齊,這兩個指標都表明在危機后復蘇初期,當價格繼續上漲時,出現了超買狀態:
3. 用卡爾曼濾波給alpha因子降噪
數據中的噪聲概念涉及信號處理領域,其目的是從例如通過電磁波形式通過空氣發送的信號中檢索正確的信息。 當波在太空中移動時,環境干擾會以噪聲的形式添加到原始的純信號中,因此信號都是有噪音的,需要分開。
卡爾曼濾波器于1960年問世,在許多需要處理噪聲數據的應用中非常流行,因為它可以對基礎信號進行更準確的估算。
除在時間序列分析中使用該技術外,該技術還廣泛用于跟蹤計算機視覺中的對象,支持飛機和宇宙飛船的定位和導航以及基于嘈雜的傳感器數據控制機器人運動。
噪聲在數據科學,金融和其他領域中的用法類似,原始數據必須包含有用的信息,例如,就交易信號而言,它需要從許多無關的信息中提取并分離出來。 顯然,因為我們不知道真實信號是否一定存在,這種分離是頗具挑戰性的。
我們將首先回顧一下卡爾曼濾波器的工作原理以及為實現其目標所做的假設。 然后,我們將演示如何使用pykalman庫將其應用于金融數據。
卡爾曼濾波的工作原理
卡爾曼濾波器是諸如時間序列之類的順序數據的動態線性模型,它可適應新信息的到達。相比于使用固定大小的窗口(如移動平均值)或給定的權重集(如指數移動平均值),卡爾曼濾波將新數據結合到其基于概率模型的時間序列當前值的估計中。
具體而言,卡爾曼濾波器是觀測序列
和對應的隱藏狀態 序列的概率模型(在這里我們將演示pykalman庫使用的表示法)。可以用下圖表示:從技術上講,卡爾曼濾波器采用貝葉斯方法,根據狀態變量x隨時間的變化推導狀態變量x的后驗分布。我們還可以將其視為在連續狀態空間中跟蹤單個對象的無監督算法(在該狀態空間中,我們將對象視為證券的價值或收益或alpha因子)。
為了從可能實時獲得的一系列觀測中恢復隱藏狀態,該算法在兩個步驟之間進行迭代:
該算法的基本思想如下:關于動態系統的某些假設以及相應測量的歷史,將使我們能夠以使先前測量的概率最大化的方式來估計系統的狀態。
為了恢復隱藏狀態,卡爾曼濾波器進行以下假設:
結果,卡爾曼濾波器類似于隱馬爾可夫模型,不同之處在于潛變量的狀態空間是連續的,并且隱變量和觀測變量均具有正態分布,表示為
,均值 和標準差用數學術語來說,模型的關鍵組成部分是:
卡爾曼濾波器的優點之一是,它可以隨著分布特性的變化靈活地適應非平穩數據。
主要缺點是金融數據經常違反線性和高斯噪聲的假設。 為了解決這些缺點,卡爾曼濾波器已擴展為具有非線性動力學的系統。 粒子濾波器是使用基于采樣的蒙特卡洛方法來估計非正態分布的替代方法。
用pykalman庫實現卡爾曼濾波
卡爾曼濾波器對于滾動估計隨時間變化的數據值或模型參數特別有用。這是因為它會根據新的觀察結果在每個時間步調整其估計值,并且傾向于權衡最近的觀察結果。
除了傳統的移動平均值,卡爾曼濾波器不需要我們指定用于估計的窗口的長度。 相反,我們從對隱藏狀態的均值和協方差的估計開始,然后讓卡爾曼濾波器根據定期觀察來校正我們的估計。
以下代碼示例顯示了如何應用卡爾曼過濾器來平滑2008-09年期間的S&P500股票價格序列:
with pd.HDFStore(DATA_STORE) as store:sp500 = store['sp500/stooq'].loc['2008': '2009', 'close']我們使用單位協方差矩陣和零均值來初始卡爾曼濾波(請參閱pykalman文檔以獲取有關選擇合適初始值的建議):
from pykalman import KalmanFilter kf = KalmanFilter(transition_matrices = [1],observation_matrices = [1],initial_state_mean = 0,initial_state_covariance = 1,observation_covariance=1,transition_covariance=.01)然后,我們運行filter方法來觸發正向算法,該算法迭代地估計隱藏狀態,即時間序列的平均值:
state_means, _ = kf.filter(sp500)最后,我們添加移動平均值方法進行比較并繪制結果:
sp500_smoothed = sp500.to_frame('close') sp500_smoothed['Kalman Filter'] = state_means for months in [1, 2, 3]:sp500_smoothed[f'MA ({months}m)'] = (sp500.rolling(window=months * 21).mean()) ax = sp500_smoothed.plot(title='Kalman Filter vs Moving Average', figsize=(14, 6), lw=1, rot=0)下面的結果圖表明,卡爾曼濾波器的性能類似于1個月的移動平均值,但對時間序列行為的變化更敏感:
4. 如何使用小波預處理噪聲信號
小波與傅立葉分析有關,傅立葉分析將不同頻率的正弦和余弦波組合在一起,以近似噪聲信號。 雖然傅里葉分析對于將信號從時域轉換到頻域特別有用,但小波對于過濾出可能在不同范圍出現的特定模式很有用,而這些特定模式又可能對應于一個頻率范圍。
小波是將離散或連續時間信號分解為不同比例分量的函數或類似波形的模式。小波變換又表示使用小波作為有限長度波形的縮放副本和轉換副本的函數。對于具有不連續和尖峰的函數,并且近似于非周期性或非平穩信號,此變換相對于傅立葉變換具有優勢。
要對信號進行降噪,可以使用小波收縮和閾值化方法。 首先,您選擇特定的小波模式來分解數據集。 小波變換產生與數據集中的細節相對應的系數。
閾值化的想法只是簡單地忽略所有低于特定截止值的系數,前提是它們代表了代表真實信號所不必要的次要細節。 然后,將這些剩余系數用于小波逆變換,以重建(去噪)數據集。
現在,我們將使用pywavelets庫將小波應用于嘈雜的股票數據。 以下代碼示例說明了如何使用正反小波變換(具有Daubechies 6小波和不同閾值)對S&P 500返回值進行降噪。
首先,我們在2008-09期間產生標準普爾500指數的每日收益:
signal = (pd.read_hdf(DATA_STORE, 'sp500/stooq').loc['2008': '2009'].close.pct_change().dropna())然后,我們從眾多內置的小波函數中選擇一個Daubechies小波:
import pywt pywt.families(short=False) ''' ['Haar', 'Daubechies', 'Symlets', 'Coiflets', 'Biorthogonal', 'Reverse biorthogonal', 'Discrete Meyer (FIR Approximation)', 'Gaussian', 'Mexican hat wavelet', 'Morlet wavelet', 'Complex Gaussian wavelets', 'Shannon wavelets', 'Frequency B-Spline wavelets', 'Complex Morlet wavelets'] '''Daubechies 6小波由縮放函數ψ和小波函數φ本身定義(有關詳細信息,請參閱PyWavelet文檔):
給定一個小波函數,我們首先使用.wavedec函數分解返回信號,這會產生小波變換的系數。接下來,我們濾除高于給定閾值的所有系數,然后使用逆變換.waverec僅使用那些系數來重構信號:
wavelet = "db6" for i, scale in enumerate([.1, .5]):coefficients = pywt.wavedec(signal, wavelet, mode='per')coefficients[1:] = [pywt.threshold(i, value=scale*signal.max(), mode='soft') for i in coefficients[1:]]reconstructed_signal = pywt.waverec(coefficients, wavelet, mode='per')signal.plot(color="b", alpha=0.5, label='original signal', lw=2, title=f'Threshold Scale: {scale:.1f}', ax=axes[i])pd.Series(reconstructed_signal, index=signal.index).plot(c='k', label='DWT smoothing}', linewidth=1, ax=axes[i])下面的結果圖清楚地表明了較高的閾值如何產生明顯更平滑的序列:
四、用Zipline包進行回測
開源庫Zipline是一個事件驅動的回測系統。它生成市場事件以模擬算法交易策略的反應并跟蹤其表現。一個特別重要的功能是,它為算法提供了歷史時間點數據,從而避免了前瞻性偏差(look-ahead bias)。
該庫已由Quantopian推廣,并在運作中使用該庫來促進算法開發和實時交易。
在本節中,我們將簡要說明其基本功能。 之后的文章會包含更詳細的介紹,以使我們為更復雜的用例做準備。
1. 如何回測單因子策略
您可以將Zipline脫機與數據包結合使用,以研究和評估alpha因子。 在Quantopian平臺上使用它時,您將可以訪問更廣泛的基礎數據和替代數據集。 我們還將在本章中演示Quantopian研究環境,并在下一章中演示回測IDE。
市場數據中的一個單因子
我們首先將說明離線環境中的Zipline alpha因子研究工作流程。 特別是,我們將開發和測試一個簡單的均值回歸因子,該因子可衡量最近的表現偏離歷史平均值的程度。
短期逆轉是一種常見的策略,它利用了弱預測模式,即股價可能會在不到1分鐘到1個月的時間內恢復到滾動均值。
為此,該系數將計算最后一個月回報相對于上一年的滾動月回報的z-score。 在這一點上,我們不會下任何命令來簡單地說明CustomFactor的實現并在模擬過程中記錄結果。
Zipline包含許多用于許多常見操作的內置因子(有關詳細信息,請參見GitHub上鏈接的Quantopian文檔)。 盡管這通常方便且足夠,但在其他情況下,我們希望以不同的方式轉換可用數據。 為此,Zipline提供了CustomFactor類,該類為我們指定各種計算提供了很大的靈活性。 它通過NumPy使用可用于證券橫截面和自定義回溯期的各種功能來執行此操作。
為此,在進行了一些基本設置之后,MeanReversion繼承了CustomFactor的子類并定義了compute()方法。 它會在一個默認的為期一年的窗口內創建月度收益的默認輸入,以便在給定的一天中,Quandl數據集中的每種證券的monthly_return變量將具有252行和一列。
compute_factors()方法創建一個MeanReversion因子實例,并創建長、短和排名流水線列。 前兩個包含可用于下訂單的布爾值,而后兩個則反映用于評估總體因素表現的總體排名。 此外,它使用內置的AverageDollarVolume因子將計算限制為更多的流動庫存:
from zipline.api import attach_pipeline, pipeline_output, record from zipline.pipeline import Pipeline, CustomFactor from zipline.pipeline.factors import Returns, AverageDollarVolume from zipline import run_algorithm MONTH, YEAR = 21, 252 N_LONGS = N_SHORTS = 25 VOL_SCREEN = 1000 class MeanReversion(CustomFactor):"""Compute ratio of latest monthly return to 12m average,normalized by std dev of monthly returns"""inputs = [Returns(window_length=MONTH)]window_length = YEARdef compute(self, today, assets, out, monthly_returns):df = pd.DataFrame(monthly_returns)out[:] = df.iloc[-1].sub(df.mean()).div(df.std())def compute_factors():"""Create factor pipeline incl. mean reversion,filtered by 30d Dollar Volume; capture factor ranks"""mean_reversion = MeanReversion()dollar_volume = AverageDollarVolume(window_length=30)return Pipeline(columns={'longs' : mean_reversion.bottom(N_LONGS),'shorts' : mean_reversion.top(N_SHORTS),'ranking':mean_reversion.rank(ascending=False)},screen=dollar_volume.top(VOL_SCREEN))這些代碼將使我們能夠下達多頭和空頭訂單。
initialize() 方法注冊了compute_factors() 管道(pipeline),而before_ trading_start()方法可確保管道每天運行。 record() 函數將管道的排名列以及當前資產價格添加到 run_algorithm()函數返回的性能DataFrame中:
def initialize(context):"""Setup: register pipeline, schedule rebalancing,and set trading params"""attach_pipeline(compute_factors(), 'factor_pipeline') def before_trading_start(context, data):"""Run factor pipeline"""context.factor_data = pipeline_output('factor_pipeline')record(factor_data=context.factor_data.ranking)assets = context.factor_data.indexrecord(prices=data.current(assets, 'price'))最后,以UTC術語定義start和end Timestamp對象,設置一個大寫基礎,并通過引用關鍵執行方法來執行run_algorithm()。 性能DataFrame包含嵌套數據,例如,price列由每個單元格的pd.Series組成。 因此,以pickle格式存儲時,后續數據訪問更加容易:
start, end = pd.Timestamp('2015-01-01', tz='UTC'), pd.Timestamp('2018-01-01', tz='UTC') capital_base = 1e7 performance = run_algorithm(start=start, end=end, initialize=initialize, before_trading_start=before_trading_start, capital_base=capital_base) performance.to_pickle('single_factor.pickle')在下一節中,我們將使用存儲在性能DataFrame中的因子和定價數據來評估不同持有期間的因子性能,但是首先,我們將研究如何通過組合來自多個交易品種的多個alpha因子來創建更復雜的信號。
2. 綜合各種數據來源的因子
Quantopian研究環境是為快速測試預測性alpha因子而量身定制的。 該過程非常相似,因為它基于Zipline構建,但是提供了對數據源的更豐富的訪問。 下面的代碼示例說明了如何不僅像以前一樣根據市場數據計算alpha因子,而且還根據基本數據和替代數據計算alpha因子。
Quantopian免費提供了數百個Morningstar基本變量,還包括Stocktwits信號作為替代數據源的示例。 還有一些自定義環境,例如QTradableStocksUS,它應用了幾個過濾器,將回測環境限制為在現實市場條件下可能可交易的股票:
from quantopian.research import run_pipeline from quantopian.pipeline import Pipeline from quantopian.pipeline.data.builtin import USEquityPricing from quantopian.pipeline.data.morningstar import income_statement, operation_ratios, balance_sheet from quantopian.pipeline.data.psychsignal import stocktwits from quantopian.pipeline.factors import CustomFactor, SimpleMovingAverage, Returns from quantopian.pipeline.filters import QTradableStocksUS我們將使用自定義的AggregateFundamentals類來使用最后報告的基本數據點。 這樣做的目的是要解決基本面按季度報告的事實,而Quantopian目前尚無法提供一種簡便的方法來匯總歷史數據,例如,滾動獲取最近四個季度的總和:
class AggregateFundamentals(CustomFactor):def compute(self, today, assets, out, inputs):out[:] = inputs[0]我們將再次使用前面代碼中的自定義MeanReversion因子。 我們還將使用rank()方法的mask參數為給定的環境空間定義計算其他幾個因子:
def compute_factors():universe = QTradableStocksUS()profitability = (AggregateFundamentals(inputs=[income_statement.gross_profit], window_length=YEAR) /balance_sheet.total_assets.latest).rank(mask=universe)roic = operation_ratios.roic.latest.rank(mask=universe)ebitda_yield = (AggregateFundamentals(inputs=[income_statement.ebitda],window_length=YEAR) /USEquityPricing.close.latest).rank(mask=universe)mean_reversion = MeanReversion().rank(mask=universe)price_momentum = Returns(window_length=QTR).rank(mask=universe)sentiment = SimpleMovingAverage(inputs=[stocktwits.bull_minus_bear],window_length=5).rank(mask=universe)factor = profitability + roic + ebitda_yield + mean_reversion +price_momentum + sentimentreturn Pipeline(columns={'Profitability' : profitability,'ROIC' : roic,'EBITDA Yield' : ebitda_yield,"Mean Reversion (1M)": mean_reversion,'Sentiment' : sentiment,"Price Momentum (3M)": price_momentum,'Alpha Factor' : factor})該算法僅對六個獨立因子如何對每種資產進行排名以組合其信息進行平均。 這是一種非常naive的方法,沒有考慮每個因素在預測未來收益時可能提供的相對重要性和增量信息。以下各章的機器學習算法將使我們能夠使用相同的回測框架來做到這一點。
策略執行還依賴于run_algorithm(),但是Quantopian平臺上的返回DataFrame僅包含管道創建的因子值。 這樣是很方便的,因為該數據格式可用作Alphalens的輸入,Alphalens是用于評估alpha因子的預測性能的庫。
五、使用Alphalens包將信號與噪聲分離
Quantopian已開源Python Alphalens庫,用于對預測庫存因子進行性能分析。 它與Zipline回測庫以及投資組合績效和風險分析庫pyfolio很好地集成在一起,我們將在下一章中進行探討。
Alphalens在以下方面有助于分析alpha因子的預測能力:
1. 創建遠期收益和因子分位數
要使用Alphalens,我們需要提供兩個輸入:
我們可以使用get_clean_factor_and_forward_returns函數將從Zipline輸出數據生成Alphalens輸入數據,即因子信號和前文所述的前向收益。 該函數返回信號五分位數,并在給定的保持時間內返回正向:
HOLDING_PERIODS = (5, 10, 21, 42) QUANTILES = 5 alphalens_data = get_clean_factor_and_forward_returns(factor=factor_data, prices=prices, periods=HOLDING_PERIODS, quantiles=QUANTILES) ''' Dropped 14.5% entries from factor data: 14.5% in forward returns computation and 0.0% in binning phase (set max_loss=0 to see potentially suppressed Exceptions). max_loss is 35.0%, not exceeded: OK! '''alphalens_data DataFrame包含在指定持有期的給定日期在給定資產上給定資產的投資回報,以及因子值,即該日期在該資產的MeanReversion排名和相應的分位數:
前向收益和信號分位數是評估信號預測能力的基礎。通常,因子對于不同的分位數應該提供明顯不同的回報,例如因子值的最低五分位數的負回報和頂部分位數的正回報。
2. 通過因子分位數預測因子性能
第一步,我們希望通過因子分位數來可視化平均周期收益。 我們可以使用性能模塊中的內置函數mean_return_by_quantile和繪圖模塊中的plot_quantile_returns_bar:
from alphalens.performance import mean_return_by_quantile from alphalens.plotting import plot_quantile_returns_bar mean_return_by_q, std_err = mean_return_by_quantile(alphalens_data) plot_quantile_returns_bar(mean_return_by_q);如下圖所示,除最長的持有時間之外,最低的五分位數產生的負面結果比最高的五分位數多:
10天(10D)持有期在整個交易期間內平均為第一和第四分位數提供了更好的結果差異。
我們還希望看到由每個信號五分位數驅動的投資隨時間變化的性能。為此,我們每天計算5天持有期間的每日回報,而不是平均回報。Alphalens調整周期收益以解決每日信號和更長的持有周期之間的不匹配(有關詳細信息,請參閱Alphalens文檔):
from alphalens.plotting import plot_cumulative_returns_by_quantile mean_return_by_q_daily, std_err = mean_return_by_quantile(alphalens_data, by_date=True) plot_cumulative_returns_by_quantile(mean_return_by_q_daily['5D'], period='5D');下圖的折線圖顯示,在這三年的大部分時間內,前兩個五分位數的表現明顯優于后兩個五分位數。 但是,如前圖所示,由于在2017年期間的相對表現,第四等五等分的信號產生的性能略好于最高五等分的信號:
一個對交易策略有用的因子就是前面的那種模式,其中累積收益沿著明顯不同的路徑發展,因為這允許具有較低資本要求的多空策略,并因此降低了對整個市場的敞口。
但是,我們還需要考慮周期收益的分散性,而不僅僅是平均值。 為此,我們可以依靠內置的plot_quantile_returns_violin:
from alphalens.plotting import plot_quantile_returns_violin plot_quantile_returns_violin(mean_return_by_q_daily);分布圖如下圖所示,突出表明日收益率的范圍相當寬。 盡管有不同的方法,但是分布的分離非常有限,因此在任何給定的日子里,五分位數之間的性能差異可能會非常有限:
當我們專注于單個alpha因子的評估時,我們通過忽略與交易執行相關的實際問題來簡化事情,下篇文章我們會講回測,這些問題將被考慮到。 其中一些包括:
3. 信息系數
本書的大部分內容是關于使用機器學習模型設計alpha因子的。機器學習是關于優化某些預測目標的,在這一部分中,我們將介紹用于測量alpha因子性能的關鍵指標。我們將alpha定義為超過基準的平均回報。
這引出了信息比率(IR)的定義,該比率通過將alpha除以跟蹤風險來衡量單位風險的平均超額收益。 當基準為無風險利率時,IR對應于眾所周知的Sharpe比率,我們將重點介紹在收益率不呈正態分布的典型情況下出現的關鍵統計測量問題。 我們還將解釋主動管理的基本法則,該法則將IR分解為預測技能和有效利用這些預測技能的策略能力的組合。
alpha因子的目標是對未來收益的準確方向預測。因此,自然的績效指標是alpha因子的預測與目標資產的遠期回報之間的相關性。
相關性最好使用非參數Spearman秩相關系數,該系數衡量使用單調函數描述兩個變量之間的關系的能力,而一般人們常用的Pearson相關系數衡量的只是線性關系的強弱。
我們可以使用依賴scipy的Alphalens獲得信息系數(IC)。 stats.spearmanr在后臺(有關如何直接使用scipy獲取p值的示例,請參見有關文檔)。factor_information_coefficient函數計算周期相關性,plot_ic_ts創建一個具有1個月移動平均值的時序圖:
from alphalens.performance import factor_information_coefficient from alphalens.plotting import plot_ic_ts ic = factor_information_coefficient(alphalens_data) plot_ic_ts(ic[['5D']])下圖中的時間序列圖顯示了具有明顯正移動平均IC的擴展周期。如果有足夠的機會運用這種預測技能,則當IC值為0.05甚至0.1的情況下,策略的表現將很突出:
年度平均IC曲線圖突顯了該因子的績效歷來是不均衡的:
ic = factor_information_coefficient(alphalens_data) ic_by_year = ic.resample('A').mean() ic_by_year.index = ic_by_year.index.year ic_by_year.plot.bar(figsize=(14, 6))結果如下圖
風險調整后的IC由平均IC除以IC的標準偏差得出,IC也通過scipy進行了零假設IC = 0的雙向t檢驗(用stats.ttest_1samp方法) :
4. 因子換手率
因子換手率(Factor turnover)衡量與給定分位數更改關聯的資產的頻率,即需要多少筆交易來調整投資組合以適應信號序列。 更具體地說,它衡量的是當前因子分位數中的資產份額,而上一時期不在該分位數中的次數。 下表由此命令生成:
create_turnover_tear_sheet(alphalens_data)加入基于五分位數的投資組合的資產所占的比例相當高,這表明交易成本對從預測績效中獲得收益構成了挑戰:
關于因子換手率的另一種觀點是,由于各種持有時長(也是上表的一部分)中的因子導致的資產等級的相關性:
通常,為了使交易成本可控,最好具有更高的穩定性(低換手率)。
六、alpha因子的資源
研究過程需要根據其信號的預測能力設計和選擇alpha因子。 算法交易策略通常將基于為每個資產發送信號的多個alpha因子。 可以使用機器學習模型來匯總這些因素,以優化各種信號如何轉化為有關單個位置的時間和規模的決策。
除quantopian用于算法交易和數據收集的其他開源Python庫包括以下幾個:
總結
以上是生活随笔為你收集整理的alpha值计算 qcolor_量化交易与机器学习(四):如何研究alpha因子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: B站韩顺平版Linux学习笔记(很全啊!
- 下一篇: wpf: DataGridTextCol