国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

量化交易全流程(六)(待完善補充)

這篇具有很好參考價值的文章主要介紹了量化交易全流程(六)(待完善補充)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本節(jié)目錄

多因子風險模型

自從股票市場產(chǎn)生以來,大量的學者、業(yè)界人員都在研究股票的價格波動究竟是由什么決定的。一個明顯的事實是,股票的價格波動一定是由多種因素決定的,比如大盤因素、市值因素和行業(yè)因素。對于大盤因素,股票的波動是會受大盤影響的。對于市值因素,不同市值的股票,波動率也會有較大的區(qū)別。對于行業(yè)因素,不同行業(yè)的股票,波動率往往也會有較大區(qū)別。
所謂多因子策略,就是要發(fā)掘諸如此類的因素(因子),確定這些因子對股價波動確實有影響,然后以一種合理的方式組合起來,形成模型,用于支持投資操作。
股價波動對應著股票的風險,所以多因子模型中的因子,往往又被稱作風險因子,即這些因子共同解釋了股票的風險。
本節(jié)將從最簡單的風險定義開始,逐步展開介紹多因子風險模型。
風險定義
根據(jù)前面介紹的金融基本概念可知,風險可以簡單定義為收益的標準差。我們可以通過計算歷史收益率的標準差來獲得股票的風險估計。假設一個投資組合的收益率為R,那么投資組合的風險

按照這個定義,我們可以證明,假設投資組合中有N支股票,而且這些股票是完全不相關(guān)的,每支股票本身的風險都是δ,那么投資組合的風險為:

由此可見,在投資組合中引入不相關(guān)的股票,可以降低投資組合的風險。當然實際情況中,股票不太可能完全不相關(guān)。所以我們將模型推廣一下,假設所有股票的相關(guān)性都為,那么可以證明,投資組合的風險為:(證明略)

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

這種計算風險的方法是由馬科維茨提出的。在該模型下,分散投資是可以降低風險的。然而,有些風險,無論怎么分散,都沒有辦法消除,因為所有股票都傾向于隨著大盤的漲跌而漲跌。這種市場性的風險稱為系統(tǒng)性風險。在馬科維茨的模型中,這種系統(tǒng)性風險并沒有體現(xiàn)出來。

CAPM

為了體現(xiàn)系統(tǒng)性風險,夏普等學者提出了資本資產(chǎn)定價模型(Capital Asset Pricing Model),簡稱CAPM。CAPM體現(xiàn)了預期收益和市場風險之間的關(guān)系。公式如下:

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

其中,為資產(chǎn)i的系統(tǒng)性風險。

CAPM的核心思想是,投資者只有承擔了市場風險,才能獲得對應比例的超額回報。
CAPM中最核心的參數(shù)就是股票的Beta系數(shù)。Beta系數(shù)衡量了某種證券或者投資組合對于整體市場波動性的敏感程度。直觀地理解就是,假設某支股票的Beta系數(shù)是1,那么市場上漲10%,股票也會對應上漲10%。如果Beta系數(shù)是2,那么市場上漲10%,股票將會對應上漲20%,如果市場下跌10%,股票也會對應下跌20%。
計算Beta系數(shù)也是CAPM中最重要的一環(huán)。一種簡單的方式是選取一段歷史樣本,使用公式進行計算。同時,也要注意到,Beta系數(shù)不一定是穩(wěn)定的,而且不同的歷史樣本,算出來的 Beta 系數(shù)肯定是不一樣的。所以如何更準確地估計Beta系數(shù),并不是一個簡單的問題。CAPM提供了一個新的視角來看待投資組合的風險。然而,CAPM離真實市場還是有較大的距離的。后來,美國學者斯蒂芬·羅斯(Stephen A. Ross)給出了一個以無套利定價為基礎的多因素資產(chǎn)定價模型,也稱套利定價理論(Arbitrage Pricing Theory)模型。

APT

1970年,投資界發(fā)現(xiàn)有類似特征的股票傾向于有類似的收益率表現(xiàn)(比如相同行業(yè)的、市值大小相近的,等等)?;诖税l(fā)現(xiàn),斯蒂芬·羅斯提出了套利定價理論(Arbitrage Pricing Theory),簡稱APT。

APT的核心思想是,證券或者投資組合的預期收益率與一組未知的系統(tǒng)性因素相關(guān),同時也滿足一價定律,即風險—收益性質(zhì)相同的資產(chǎn),價格也必須相同。否則會出現(xiàn)套利行為。模型推導出的資產(chǎn)收益率取決于一系列影響資產(chǎn)收益的因素,而不完全依賴于市場資產(chǎn)的組合,而套利活動則保證了市場均衡的實現(xiàn)。
實際上,CAPM是APT 模型的一種特殊形式。如果假設只有市場收益率這一個因子會影響證券的收益率,那么APT模型實際上就是CAPM。所以APT模型可以算是CAPM的一種推廣,將單一的市場因子推廣到多種因子。APT 模型的計算公式具體如下:

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

為風險因子,因子載荷,敏感度,資產(chǎn)本身風險。

APT 的因子模型更符合人對證券投資的直覺,所以更貼合于市場。不過,雖然APT 模型提出了一個很好的框架,但該理論并沒有告訴我們,因子是什么,如何計算一只股票對因子的風險頭寸,所以APT還需要進行進一步的完善和研究,才能真正用于實際投資。
對于這個問題,BARRA公司進行了大量的研究,并提出了BARRA多因子模型(Multi-factor Model)。

MFM

多因子模型(Multi-Factor Model,MFM)是建立在這樣的概念基礎之上的,即一只股票的收益可以由一系列公共因子加上一個股票自身特殊的因子來解釋。通俗地說,類似的股票應該有類似的收益率。所謂的"類似",主要是通過股票的各個特征來表現(xiàn)的,包括股票價量數(shù)據(jù)、財務報表中的基本面數(shù)據(jù)等。

MFM可用于識別股票之間共同的因子,并且計算股票收益率對于這些因子的敏感度。最終的風險模型將所有股票的收益率表達為因子收益和特殊收益的加權(quán)之和。當我們得到模型之后,任何的因子變化都將能夠很快反應在模型之中。

多因子模型的優(yōu)勢

使用多因子模型有很多種優(yōu)勢,具體如下。
□可以減小問題規(guī)模。假設有3000只股票,如果使用收益率來計算協(xié)方差,那么我們將會有3000x(3000-1)/2= 4 498 500個協(xié)方差。但是如果我們將股票表示為20個因子,那么我們更多地就只需要研究這20個因子之間的關(guān)系。問題的規(guī)模就小得多了。
□多因子模型對風險進行了比較全面的分解和分析。其在進行風險暴露分析的時候比諸如CAPM的模型能分析得更為全面。
□在選擇因子的時候,由于引入了經(jīng)濟邏輯,所以多因子模型的分析不會局限于純歷史數(shù)據(jù)的挖掘。

建立多因子模型的一般流程

風險因子的種類
建立多因子模型,第一步就是要選擇合適的因子。一般來說,因子可以分成三大類:反映外部影響的因子、代表資產(chǎn)特點的截面比較因子、純內(nèi)部因子或者統(tǒng)計因子。

反映外部影響的因子

很明顯,外部經(jīng)濟力量與股票市場間應該存在明確的聯(lián)系。相關(guān)的因子便試圖抓住這種聯(lián)系。這些因子包括但不限于通貨膨脹系數(shù)、石油價格變動、匯率變化、工業(yè)生產(chǎn)量變化等。這些因子通常又被稱為宏觀因子。宏觀因子有時非常有效,但其也有如下三方面的缺陷。
第一個缺陷是,必須通過回歸分析或者類似的方法來估計資產(chǎn)收益對這些因素的反應系數(shù)。如果我們需要估計3000只股票,那么每個月都需要進行3000次時間序列回歸。這將會產(chǎn)生估計誤差。
第二個缺陷是,我們的估計通常是建立在對歷史數(shù)據(jù)的估計基礎之上的,比如說5年。這些估計雖然可能能夠比較精確地描述歷史情形,但未必能夠精確描述當前或者未來的情況。也就是說,這些反應系數(shù)是不穩(wěn)定的。
第三個缺陷是,一些宏觀經(jīng)濟數(shù)據(jù)的質(zhì)量較差,收集過程可能會存在錯誤和延遲。而且有的數(shù)據(jù)可能因為頻率較低而沒有太大的使用價值。

資產(chǎn)截面因子

資產(chǎn)截面因子用于比較股票自身的特征,與宏觀經(jīng)濟無關(guān)。截面因子通常也可以分為兩類:基本面特征和市場特征。基本面特征包括諸如派息比例、每股收益、股票市值等。市場特征則包括過去一段時期的收益率、波動率、成交量、換手率等。

統(tǒng)計因子

統(tǒng)計因子是一類因子,這些因子有可能與股票收益率相關(guān),雖然其中并不存在明顯的金融經(jīng)濟學邏輯,但是從統(tǒng)計上可以得到很好的解釋效果。

一般來說,我們要回避統(tǒng)計因子,因為統(tǒng)計估計往往會得出一些虛假相關(guān)性,而且統(tǒng)計因子往往還非常難以解釋。一般來說,我們需要挑選具有經(jīng)濟意義,可解釋,而且具有統(tǒng)計意義的因子。典型的因子包含兩類:行業(yè)因子和風險因子。行業(yè)因子用于衡量不同行業(yè)股票的不同行為,風險因子用于衡量其他的非行業(yè)尺度上不同股票的不同行為。

行業(yè)因子

股票所屬行業(yè)是一項非常重要的特征。不過有的公司涉及多種行業(yè),所以對股票進行行業(yè)分類需要一個標準。A 股票的行業(yè)的分類標準有很多種,比如申萬行業(yè)分類、證監(jiān)會行業(yè)分類等。
其中,申萬行業(yè)在業(yè)內(nèi)使用得較多。股票分類又分為一級行業(yè)分類、二級行業(yè)分類等。所謂一級行業(yè)分類就是比較粗的分類,二級行業(yè)分類相當于一級行業(yè)分類的子分類。

二級行業(yè)分類眾多,這里就不列舉了。
在進行回歸分析的時候,行業(yè)的頭寸一般設為0或1的啞變量,主要目的是檢測因子的表現(xiàn)是否有明顯的行業(yè)傾向。

風險因子分類

行業(yè)并不是產(chǎn)生股票風險的唯一來源,風險因子也是一大類的風險來源。一般來說,風險因子可以分為如下幾個大類。
□波動率(volatility):根據(jù)波動率的不同來區(qū)分股票。波動率的概念在前面的章節(jié)中曾提到過,是股份一項十分重要的特征。

□動量(momentum):根據(jù)股票當前的績效來進行區(qū)分。學術(shù)中曾有實證研究,動量效應確實是存在的,即處于漲勢的股票總是會傾向于上漲得更多,處于跌勢中的股票也傾向于跌得更多。
口規(guī)模(size):股票的規(guī)模一般會使用市值來表示。著名的Fama-French三因子模型中就有市值的因子。
□流動性(liquidity):流動性也是股票一項非常重要的指標,一般使用股票的交易量來表示。
□成長性(growth):根據(jù)過去的和預期的收益成長性來進行區(qū)分。
□價值(value):根據(jù)股票的一些基本面數(shù)據(jù)來區(qū)分股票。比如股息、現(xiàn)金流、賬面價值等。
□財務杠桿(financial leverage):根據(jù)凈資產(chǎn)負債率和利率風險來進行區(qū)分。

每一個大類通常都會包含幾個特定的度量尺度,這些特定的度量尺度稱為描述符(descriptors)。例如,波動率包括近期每日收益率波動率、期權(quán)隱含的波動率、近期價格范圍等。盡管同一類別中的各個描述符通常都是相關(guān)的,但是每一個描述符都描述了風險因子的某一個方面。我們也可以在某大類因子的不同描述符中分配頭寸權(quán)重。

投資組合風險分析

多因子風險模型可用于分析當期投資組合風險。它既能衡量整體風險,也能利用多種途徑來分散風險。風險的分散可以鑒別出資產(chǎn)組合中重要的風險來源。
風險分析對于消極管理和積極管理都很重要。消極管理通??梢岳斫鉃橹笖?shù)基金,指數(shù)基金一般與一個特定的基準組合相匹配。然而,即使有了基準組合,管理者的投資也不一定包括基準組合中的所有股票。比如,對于一個包含幾百上千只股票的基準組合,管理者不太可能持有所有的股票。當前的投資組合的風險分析就可以告訴消極管理者其投資組合相對于基準組合的風險水平。這就是跟蹤誤差。這是投資組合與基準組合之間收益差異的波動率來源,消極的管理者的目標是最小化跟蹤誤差。
當然,更多的投資者所關(guān)注的可能是積極型管理。積極型管理者的目標不是盡可能地接近基準組合,而是要盡可能地超越基準組合。同樣的,風險分析對于積極型管理關(guān)注積極型策略也十分重要。積極型管理者只承擔他們獲得超額收益所面臨的風險。
通過恰當?shù)胤纸猱斍巴顿Y組合的風險,積極型管理者可以更好地理解他們投資組合的們?yōu)槭裁匆约叭绾尾拍芨淖兯?。資產(chǎn)配置。風險分析不僅可以告訴積極型管理者他們的積極型風險是什么,還可以告訴他們?yōu)槭裁匆约叭绾尾拍芨淖兯?/p>

基準組合

在實際情況中,積極型資產(chǎn)管理者通常被要求其管理的基金績效要高于基準組合。所謂基準組合,在實際中,其實并不是真正的"市場組合"。比如滬深300或者上證指數(shù),并不是真正的"整體市場"的表現(xiàn),畢竟A股有3000只股票,而這些指數(shù)只是包括了其中一部分的股票。另外,當我們在投資債券或者商品期貨的時候,滬深300明顯也不是一個合適的基準組合。所以在實際中,我們很少真正地去對"整體市場"進行比較和分析,取而代之的是人為選擇出來的"基準組合"。
那么之前提到的β值,就不再是相對于整體市場的,而是相對于基準組合的了。

因子選擇和測試

備選因子有兩個來源。一個來源是市場信息,比如成交量、價格等,這種信息每天都有。第二個來源是公司的基本面數(shù)據(jù),比如利潤、凈資產(chǎn)、負債等。這些信息一般會體現(xiàn)在季報和年報中。也有些因子是市場信息和基本面信息的組合,比如市盈率(PE)。因子的選擇并不是一個簡單的過程,需要進行大量嚴謹?shù)牧炕芯俊?br> 最開始是因子的初步篩選。首先,好的因子,即使單獨來看,也應該具有比較明顯的意義。換句話說,好的因子應該是被廣泛接受的,易于理解的資產(chǎn)相關(guān)的特征。其次,好的因子應該能將市場中的股票較好地進行分類,能夠較明顯地說明投資組合的風險特征。
選中的因子應當是基于經(jīng)常發(fā)布的、準確的數(shù)據(jù),而且應當具有預測風險的效用。當將一個因子加到模型里面的時候,對模型的預測作用應該會有所提升,否則的話就不應該加入進來。
為了能將不同的因子結(jié)合到一個模型中,我們需要對其進行歸一化操作。所謂歸一化,就是將不同范圍的數(shù)據(jù)調(diào)整到同樣的量級,這樣做可便于比較。因為不同因子的數(shù)值范圍差別很大,如果不進行歸一化,就會極大地影響模型的有效性。歸一化的公式是:

因子歸一化之后,我們將資產(chǎn)收益和行業(yè)、因子進行回歸。每次只對一個因子進行回歸,這樣就可以對每個因子測試其統(tǒng)計顯著性。之后再基于計算的結(jié)果選擇相應的因子納入模型中。實際上這是一個迭代的過程,當將最顯著的因子納入模型之后,后面的因子需要接受更為嚴格的檢驗才能納入,只有當它們能夠增加模型的解釋能力的時候才考慮將其納入。

Fama-French三因子模型

Fama-French 三因子模型考慮的因子包括CAPM里的市場風險溢價因子,小市值股票回報率減去大市值股票回報因子(SMB),以及低PE股票回報率減去高PE 股票回報率因子(HML)。由于 Eugene Fama 當時研究的對象為美國的股市,而且時代相差太過久遠,因此當時有效的模型可能現(xiàn)在在A股中的使用已不是那么有效了,但為了遵從原本的三因子模型,我們還是盡可能原汁原味地遵照原本模型的構(gòu)建方式。我們相信,數(shù)據(jù)本身在模型的學習階段并不重要,能夠掌握模型背后的思想才是更為重要的。

數(shù)據(jù)需要從銳思數(shù)據(jù)庫下載存放到mysql數(shù)據(jù)庫中,akshare好像還找不到因子數(shù)據(jù),自行下載數(shù)據(jù)。從2021-01-04到2023-09-30大概60萬條數(shù)據(jù)。

在A股當中還原三因子模型時,我們將資產(chǎn)池暫時設定為上證380相關(guān)成分股中歷史數(shù)據(jù)較多的股票。其收益率我們以周收益率為準,并且假定每個因子對每只股票都是有效的,代碼如下:

import numpy as np
import pandas as pd
sz380 = pd.read_excel(*'sz380.xlsx')
sh=pd.read_excel('000001sh.xlsx')[2:]
sh.columns=['date','sh_index']
sh=sh.set_index(['date'])
sh=sh.pct_change()

假定無風險年化收益率為0.02,代碼如下:

sh['sh_index']=sh['sh_index']-0.02/52
sz380.rename(columns={'Unnamed:0':'date'},inplace=True)
sz380=sz380.set_index(['date'])

將整個數(shù)據(jù)集拆分為三個DataFrame,分別對應于不同的指標,也可以用Multilndex 的形式進行數(shù)據(jù)整理,代碼如下:

sz380close=sz380.iloc[:,:380].iloc[2:,:]
sz380mc=sz380.iloc[:.380:760].iloc[2:,:]
sz380pe= sz380.iloc[:.760:].iloc[2:,:]
sz380mc.columns = sz380close.columns
sz380pe.columns=sz380close.columns

轉(zhuǎn)化數(shù)據(jù)格式,將字符串轉(zhuǎn)化為浮點數(shù)進行計算。為了準確計算,可以用Python的定點數(shù)對象進行計算,代碼如下:

def to_float (df):
    for c in df.columns:
        df[c]=df[c].map(float)
to_float (sz380close)
to_float (sz380mc)
to_float (sz380pe)

我們對每只股票的數(shù)據(jù)量進行排序,選取其中一部分歷史數(shù)據(jù)量較大的進行計算,可以設置為全局變量以便于調(diào)控(按照數(shù)據(jù)量排序的前兩百名股票的歷史數(shù)據(jù))。由于三種數(shù)據(jù)都是行情相關(guān)的,因此對于每一只股票而言,三種數(shù)據(jù)的量都是一樣的,代碼如下:

top = 200
def get_data_amount_count (df,top): 
    count =[]
    for c in df.columns:
        count.append ([c,len(df[c].dropna())])
    count = sorted(count,key= lambda x:x[1],reverse=True)
    valid_ids=[]  # 獲得數(shù)據(jù)量足夠的股票代碼
    for i in range(0,top):
        valid_ids.append (count[i][0])
    return valid_ids,count[top][1]
valid_ids,amount_of_data = get_data_amount_count (sz380close, top)

sz380close=sz380close[valid_ids].iloc[len(sz380) -amount_of_data:,:].fillna (method='ffill')
sz380return=sz380close.pct_change().dropna()
sz380mc=sz380mc[valid_ids].iloc[len(sz380)-amount_of_data:,:].fillna (method='ffill').dropna()
sz380pe=sz380pe[valid_ids].iloc[len(sz380) -amount_of_data:,:].fillna (method='ffill').dropna()

下面就來正式構(gòu)建因子。我們先構(gòu)建SMB 因子。SMB因子是由做多市值排名相對較小,而做空市值排名相對較大的股票獲得的因子。針對數(shù)據(jù)內(nèi)的每一個交易日,我們根據(jù)市值來進行選股,代碼如下:

sz380mc_dict=sz380mc.to_dict (orient ='index')
factor_track=[]
for date, data in sz380mc_dict.items():
# 分別取市值排名前10%和后10%
    data=list(data.items())
    data=sorted(data,key=lambda x:x[1])
    small_cap=data[:int (0.1*len(data))]
    large_cap=data[int(0.9*len(data)):]
# 將每一個交易日的SMB因子構(gòu)建出來
# 將投資軌跡建立起來
factor_track.append([date, [x[0] for x in small_cap],[x[0] for x in large_cap]])
# 再依據(jù)投資軌跡建立相應的因子收益軌跡
factor=[]
for track in factor_track:
# 做多小市值,做空大市值
# 各個組合假定為等權(quán)重
    try:
        trading_day_small_cap_return = np.mean(sz380return.loc[pd.Timestamp(track[0]),track[1]])
        trading_day_large_cap_return = np.mean (sz380return.loc[pd.Timestamp(track[0]),track[2]])
        factor.append([track[0], trading_day_small_cap_return-trading_day_large_cap_return])
    except KeyError:
        continue
smb = pd.DataFrame(factor,columns=['date','smb'])

這樣我們就建立了一個因子,如法炮制,還可以建立HML因子,即做空高PE股票,做多低PE股票,代碼如下:

for date, data in sz380pe_dict.items():
    # 我們分別取PE排名前10%和后10%
    data=list(data.items())
    data = sorted(data,key = lambda x:x[1])
    low_pe=data[:int(0.1*len(data))]
    high_pe=data[int(0.9*len(data)):]
    # 投資軌跡建立起來
    factor_track.append([date, [x[0] for x in low_pe],[x[0] for x in high_pe]])
# 再依據(jù)投資軌跡建立相應的因子收益軌跡
factor =[]
for track in factor_track:
    # 做多低PE,做空高PE
    # 假定各個組合為等權(quán)重
    try:
        trading_day_low_pe_return=np.mean(sz380return.loc[pd.Timestamp(track[0]),track[1]])
        trading_day_high_pe_return=np.mean(sz380return.loc[pd.Timestamp(track[0]),track[2]])
        factor.append([track[0], trading_day_low_pe_return-trading_day_high_pe_return])
    except KeyError:
        continue
hml=pd.DataFrame(factor,columns=['date','hml'])

至此,三因子模型需要的數(shù)據(jù)算是建立起來了,下面將所有的數(shù)據(jù)整合到一起,代碼如下:

factors=smb.merge(hml,on=['date'],how='inner',copy=False)
factors =factors.set_index(['date'])
# 將市值因子整合到一起
factors['capm']=sh
factors['const']=1
# 對每一只股票進行回歸,得出資產(chǎn)池內(nèi)的單個資產(chǎn)的暴露情況
# 假設所有的因子都是統(tǒng)計顯著的
from sklearn.linear_model import LinearRegression
factor_loading=[]
for stock_id in sz380return.columns:
    regression_data=factors.copy()
    regression_data[stock_id]=sz380return[stock_id]
    print (stock_id)
    model=LinearRegression(fit_intercept = True).fit(regression_data[['capm','smb','hml']],regression_data[stock_id])
    factor_loading.append ([stock_id]+[model.intercept_]+list (model.coef_))
# 最后整理為DataFrame
factor_loading=pd. DataFrame(factor_loading, columns=['stock_id','alpha','capm','smb','hml'])

假如我們需要構(gòu)建一個 SML 因子暴露為0.5、CAPM 因子暴露為1.2、HML 因子暴露為0.3的投資組合,實質(zhì)就是解方程組。

np.dot(Idiosyncratic_exposure.T,weight) = target_exposure

你肯定發(fā)現(xiàn),這個方程組大概率會有無窮多個解,所用的方式一般是求矩陣的廣義逆。在實操過程當中,會有很多限定條件來進一步縮小投資組合的范圍,代如下:

factor_loading_array=factor_loading[['capm','smb','hml']].values.T
weight=list(np.dot(np.linalg.pinv(factor_loading_array).np.array([1.2,0.5,0.3]).T))

至此,一個FF3因子模型基本復現(xiàn)完成。

因子發(fā)掘與論證
一般意義上來講,所有的因子模型采用的都是如下一個通用流程。
口從各種維度統(tǒng)計論證某個指標的時間序列選股的有效性。包括因子收益是否統(tǒng)計顯著為正,其背后的因果關(guān)系是怎么樣的,在未來是否還會復現(xiàn),成本收益比如何,是否已經(jīng)被市場的套利團隊填平了收益等。
口利用該指標的歷史時間序列構(gòu)建資產(chǎn)池序列,并跟蹤其收益。
口將收益序列作為一個回歸項對現(xiàn)有的資產(chǎn)池所有管轄資產(chǎn)進行回歸,得出各個資產(chǎn)因子的顯著暴露。
口根據(jù)基金經(jīng)理的投資風格、投資目標、風險收益比權(quán)衡等因素,確定投資組合的目標因子暴露。
口計算出權(quán)重,進行資金分配。

可以發(fā)現(xiàn),其實這里最重要的一個步驟就是發(fā)現(xiàn)有效因子。一個因子是否有效,通常意義上必須要滿足兩個條件。
1)在統(tǒng)計意義上是顯著的。

2)其因果關(guān)系是可以論證的。前者其實非常容易實現(xiàn),而后者則相對要難很多。發(fā)現(xiàn)因子的過程其傳統(tǒng)的做法是通過經(jīng)濟學論證或者是基金經(jīng)理長期多年在股票市場上挖掘出來的因子。而這些方法發(fā)掘因子的效率極其低下。近年來,發(fā)現(xiàn)因子的方法出現(xiàn)了一些新的模式。通過各種數(shù)據(jù)的排列組合,以及模型的不斷嘗試,挖掘出在統(tǒng)計意義上有效的因子,之后再交給資深的基金經(jīng)理進行論證和判斷,選取能夠在因果邏輯上行得通的因子推動投資組合建立。目前市面上已經(jīng)有團隊在用類似的方法進行嘗試。可以想見的是,傳統(tǒng)的技術(shù)分析帶來的收益回報將會被這些團隊全部攫取,市場將會變得更加有效。

單因子有效性分析 alphalens

alphalens是一個用于進行單因子分析的開源項目,是由國外的在線量化平臺quantopian 開發(fā)的。使用alphalens,我們可以對單因子的有效性進行全面的分析。
使用alphalens,用戶只需要做兩件事情。一是數(shù)據(jù)的預處理,要將數(shù)據(jù)處理成alphalens 需要的數(shù)據(jù)格式;二是讀懂 alphalens的計算結(jié)果和相應表圖。

數(shù)據(jù)預處理

我們先來進行數(shù)據(jù)預處理操作。數(shù)據(jù)預處理的核心函數(shù)如下:

alphalens.utils.get_clean_factor_and_forward_returns(factor, prices, groupby=None,\
        by_group=False, quantiles=5, bins=None, periods=(1, 5, 10), filter_zscore=20, groupby_labels=None)

這個函數(shù)會將輸人的數(shù)據(jù)整合成alphalens 需要的形式。用戶需要做的就是將參數(shù)的數(shù)據(jù)準備好,作為輸人。
其中,比較常用的有factor、prices(必須要是用戶定義的)、groupby、groupby_labels (用于對股票的分類進行分析),一般是用行業(yè)來進行分類,類別可以自行定義。periods定義了分析因子和未來多少天的收益率的關(guān)系。默認是1、5、10,也就是會分析因子和未來1天、5天、10天的收益率的關(guān)系。
數(shù)據(jù)來源,由于需要用到行業(yè)數(shù)據(jù),因此我們使用的是開源的數(shù)據(jù)接口tushare和akShare,兩者須同時使用。
首先,我們需要獲取股票列表。tuShare提供了接口,用于獲取滬深A 股的股票代碼和相應的行業(yè)分類,代碼如下:

import tushare as ts
pro = ts.pro_api('fdf059e3fd18ba53290c4907562f871fc598b37ac78f2536859003f3')
#查詢當前所有正常上市交易的股票列表
#您每小時最多訪問該接口1次
data = pro.query('stock_basic', exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')

結(jié)果如下:

data

?量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

相比于akshare就不全面:

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

為了簡化問題,我們只隨機選取其中100只股票進行分析,在數(shù)據(jù)整合函數(shù)中,不僅要用到行業(yè)名稱,還需要為每個行業(yè)生成相應的ID號,在這里我們自己生成行業(yè)的ID號。代碼如下:

import random
import pandas as pd
import numpy as np
random.seed(123)  # 設置隨機數(shù)種子為123

# 創(chuàng)建隨機整數(shù)序列,不要把范圍弄太大,隨機生成去取數(shù)據(jù),好多都是新股沒有歷史數(shù)據(jù)
s = [random.randint(1, 2000) for _ in range(100)]

# 使用s作為df的行索引提取數(shù)據(jù)
result = data.loc[s]

result = result[['symbol','industry']]
result = result.sort_values('symbol')
# print(result)


# 根據(jù)行業(yè)名稱生成行業(yè)對應的ID號
result['industry_name']=result['industry']
industry_name = result.industry_name.unique()
industry_id = range(0,len(industry_name))
# 在result 里添加一列行業(yè)對應的ID
sec_names = dict(zip(industry_id, industry_name))
sec_names_rev = dict(zip(industry_name, industry_id))
result['industry_id'] = result['industry_name'].map(sec_names_rev)
# 生成 code 和與行業(yè)代碼對應的字典
code_sec = dict (zip(result.symbol, result.industry_id))
print(result)

結(jié)果如圖:

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

其中code_sec如圖:是字典

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

sec_names也是字典:

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

接下來,我們獲取每只股票的行情數(shù)據(jù)。使用akShare獲取數(shù)據(jù)的時候,股票如果停牌,那么相應日期的數(shù)據(jù)就不會存在。為了對齊交易日期,下面我們使用滬深300指數(shù)的交易日期作為所有股票的索引基準,代碼如下:
#由于有的股票在某些交易日不交易,導致要提取的數(shù)據(jù)提取不到
#所以這里使用滬深300的數(shù)據(jù)作為交易日的標準

輔助函數(shù):

def gp_type_szsh(gp):
        if code.find('60',0,3)==0:
            gp_type='sh'
        elif code.find('688',0,4)==0:
            gp_type='sh'
        elif code.find('689',0,4)==0:
            gp_type='sh'
        elif code.find('900',0,4)==0:
            gp_type='sh'
        elif code.find('00',0,3)==0:
            gp_type='sz'
        elif code.find('300',0,4)==0:
            gp_type='sz'
        elif code.find('301',0,4)==0:
            gp_type='sz'
        elif code.find('200',0,4)==0:
            gp_type='sz'
        elif code.find('8',0,1)==0:
            gp_type='bj'
        elif code.find('430',0,4)==0:
            gp_type='bj'
        return gp_type+gp
import akshare as ak
code='000001'
start_date='2020-01-01'
end_date='2023-09-29'

df = ak.index_zh_a_hist(symbol=code, period="daily", start_date=start_date, end_date=end_date)
# print(index_zh_a_hist_df)
df = df[['日期','開盤','最高','最低','收盤']]
df = df.rename(columns={'日期': 'date','開盤': 'open','最高': 'high','最低': 'low','收盤': 'close'})
df=df.set_index('date')
df[code]=df.open
df=df[[code]]
# print(df)

# 取所有股票的數(shù)據(jù),并與滬深300數(shù)據(jù)的日期進行對齊
for code in result.symbol:
    stock_code = gp_type_szsh(code)
    stock_df = ak.stock_zh_a_daily(symbol=stock_code, start_date=start_date, end_date=end_date)
    stock_df=stock_df.set_index('date')
    df[code]=stock_df.open
# 將index 轉(zhuǎn)換為datetime 格式(從TuShare 導出的數(shù)據(jù)date是字符串格式)
df.index=pd.to_datetime(df.index)

#提出指數(shù)數(shù)據(jù)
del df['000001']
df

結(jié)果如圖:df行為日期,列為股票代碼

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

這里為了進行說明,我們使用未來5天的收益率作為因子進行分析。未來5天的收益率用于預測未來5天的收益率,當然是百分之百的準確,而且未來5天的收益率會與第1天、第10天的收益率有很強的相關(guān)性。所以在表現(xiàn)上,這會是一個很強的因子(當然現(xiàn)實中,我們不可能知道未來5天的收益率,這里只是舉例說明,并沒有實際的意義),代碼如下:
#為了更有效地演示,這里我們使用未來5天的收益率作為預測因子
# 這個因子由于加入了未來函數(shù),所以會有很強的預測效果

lookahead_bias_days=5
predictive_factor = df.pct_change(lookahead_bias_days)
predictive_factor = predictive_factor.shift(-lookahead_bias_days)
predictive_factor = predictive_factor.stack()
predictive_factor.index = predictive_factor.index.set_names(['datet','asset'])
predictive_factor.head()

predictive_factor是雙索引的Series類型。兩個索引分別是日期和對應的資產(chǎn)代碼,對應的數(shù)值是 factor值,結(jié)果為:

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

數(shù)據(jù)準備好了后,調(diào)用整合函數(shù)進行處理:

import alphalens
# 將數(shù)據(jù)整合為alphalens所需要的格式
pricing = df
factor_data = alphalens.utils.get_clean_factor_and_forward_returns (predictive_factor, pricing, quantiles = 5, bins = None,groupby = code_sec, groupby_labels = sec_names)
factor_data.head()

結(jié)果如圖:

額,這里數(shù)據(jù)有問題,找了幾天沒找到問題所在,說是矩陣行列長度不符合,這里進行不下去后面就無法進行分析。

量化交易全流程(六)(待完善補充),人工智能,大數(shù)據(jù)

這是數(shù)據(jù)整合后的格式,是DataFrame類型,日期和資產(chǎn)代碼作為雙重索引。列1、5、10分別代表未來1、5、10天的收益率,factor是因子值,group是分類,factor_quantile是將因子從小到大劃分區(qū)間進行的分類,這里由于參數(shù)quantiles=5,所以是分為5類。1代表因子是處于最小的那一部分因子中,5代表因子處理最大的那一類,其余的類似。
完成了數(shù)據(jù)整合之后,數(shù)據(jù)準備工作就完成了。剩下的代碼很簡單,直接調(diào)用相應的函數(shù)就可以進行分析了。

收益率分析

最基礎的分析就是查看不同大?。ú煌治粩?shù))的因子和未來收益率的相關(guān)性,代碼如下:

mean_return_by_q, std_err_by_q = alphalens.performance.mean_return_by_quantile(factor_data, by_group=False)
mean_return_by_q.head()

結(jié)果如圖:--

這里計算出了每個分位數(shù)的因子所對應的收益率(平均值),代碼如下:

alphalens.plotting.plot_quantile_returns_bar(mean_return_by_q)

換成圖會更直觀,每個分位的因子所對應的收益率如圖所示:--

可以看到的是,隨著因子的增大,未來的收益率也會增加,說明因子和收益率具有很強的相關(guān)性,可能是一個不錯的因子。
alphalens 的強大之處在于可以多方位審視一個因子的有效性。除了上面提到的最基礎的因子分位數(shù)和收益率的關(guān)系之外,還提供了其他的方法來進行檢測。
比如,繪制每個調(diào)倉期最高因子和最低因子收益率的差值,代碼如下:

mean_return_by_q_daily, std_err= alphalens.performance.mean_return_by_quantile(factor_data, by_date=True)
quant_return_spread, std_err_spread = alphalens.performance.compute_mean_returns_spread (mean_return_by_q_daily, upper_quant=5,lower_quant=1,std_err=std_err)
alphalens.plotting.plot_mean_quantile_returns_spread_time_series (quant_return_spread, std_err_spread)

下圖是繪制出來的其中一幅圖:--

上圖是針對未來1天的收益率,綠色的線(上下波動的密集波線)代表最高的因子收益率和最低因子收益率的差值。如果一個因子是有效的,那么我們應當期望這個差值會一直穩(wěn)定地大于0(當然,對于反向因子,這個差值應該一直穩(wěn)定地小于0)。總之,這個差值應該是比較穩(wěn)定的,而不是時而大于0,時而小于0。通過上圖我們可以看到,大部分時間綠色的線都在0以上,說明因子在時間維度上是比較穩(wěn)定的。橙色的線(中間比較平緩的曲線)是綠色線的移動平均線,移動平均線是為了便于觀察因子有效性的趨勢。
下面求取不同分位數(shù)因子的累計凈值,繪制結(jié)果如圖所示:--

alphalens.plotting.plot_cumulative_returns_by_quantile(mean_return_by_q_daily)

上圖繪制了不同分位數(shù)因子的累計凈值。一個好的因子,在累計收益率上,應該出現(xiàn)較大的分化。在上圖中,不同分位數(shù)因子的累計凈值確實出現(xiàn)了很大的分化。
實際應用調(diào)用一個函數(shù),就能給出以上所有的收益率分析的結(jié)果報表,代碼如下:

alphalens.tears.create_returns_tear_sheet (factor_data)

信息系數(shù)分析


信息系數(shù)(Information Coefficient Analysis)是衡量因子有效性的另外一個角度。信息系數(shù)與相關(guān)系數(shù)比較相似,都是用于衡量兩個變量的線性關(guān)系。信息系數(shù)在0到1之間,0表示因子沒有任何預測作用,1表示因子有完全的預測作用。信息系數(shù)越大,表明因子的預測效果越好。
可以用以下函數(shù)計算信息比率:

ic=alphalens.performance.factor_information_coefficient (factor_data)
ic.head()


計算結(jié)果如圖所示:--


上圖中、1、5、10分別代表了因子對于未來1、5、10天收益率的信息系數(shù)??梢钥吹?,5天的收益率信息系數(shù)是1,因為我們本來就是用5的未來收益率作為因子,所以能夠完美預測。同時,對于1天,10天的效果也很明顯。
也可以繪制信息系數(shù)的圖,代碼如下:

alphalens.plotting.plot_ic_ts(ic)


繪制的圖形分別如下三幅圖所示:--? --? --

通過上面的三幅圖,我們可以看到信息系數(shù)隨時間變化的表現(xiàn)。對于長期的。一個好的因子,信息系數(shù)應該比較高,而且波動應該比較小。這就說明這個因子是有效且也可以觀察信息系數(shù)的分布,代碼如下:

alphalens.plotting.plot_ic_hist(ic)


繪制的信息系數(shù)分布圖如圖所示:--(三個周期三幅圖)


從上圖中我們可以看到,10天的信息系數(shù)比1天的高而且穩(wěn)定。


只看均值有時候也會帶來誤解。比如,如果有一個極端大的值,那么它很可能就會拉高整體的平均值。這個時候就需要用Q-Q圖(quantile-quantile plot)來排除這個可能性。Q-Q圖主要是比較信息系數(shù)的分布和正態(tài)分布的區(qū)別。繪制Q-Q圖的代碼如下:

alphalens.plotting.plot_ic_qq(ic)


繪制結(jié)果如圖所示:--(三個周期三幅圖)

可以看到,1和10的Q-Q圖和紅線比較接近,說明分布是類似于正太分布的,說明信息系數(shù)平均值好,并不是由于幾個極端的值造成的。
我們也可以按月份來觀察信息系數(shù),代碼如下:

mean_monthly_ic=alphalens.performance.mean_information_coefficient(factor_data,by_time='M')
mean_monthly_ic.head()


輸出結(jié)果如圖所示:--


繪制每個月的信息系數(shù)表現(xiàn)圖,代碼如下:

alphalens.plotting.plot_monthly_ic_heatmap(mean_monthly_ic)


信息系數(shù)表現(xiàn)圖如圖所示:--

從上圖中,我們可以看到每個月的信息系數(shù)的表現(xiàn)。

當然alphalens也提供了所有信息系數(shù)分析的報表函數(shù),代碼如下:

alphalens.tears.create information_tear_sheet(factor_data)


除了收益率和信息系數(shù)分析,alphalens還提供了換手率和按行業(yè)分類的分析。這里不再過多介紹,請自行查閱官方文檔。我后續(xù)要把這里的問題查資料解決。

財務因子為什么不好用

股票量化模型,最流行的就是多因子模型。多因子模型是從Fama-French三因子模型衍生而來的,基本框架從未變過。
因子有很多種,比如動量因子、估值因子、盈利因子、行業(yè)因子,等等。最大的好處是,可以用統(tǒng)一的框架解釋所有的事情。缺點也很明顯,實際研究發(fā)現(xiàn),真有效的可能就那么幾個,比如動量、市值、賬面市值比之類的因子。
大部分財務因子,要么就是效果不好(統(tǒng)計顯著性不明顯),要么就是因為共線性被刪掉了。研究多了會發(fā)現(xiàn),忽略財務指標,深挖技術(shù)指標,實際產(chǎn)出可能會更高。
比如World Quant的101 Alpha因子,全是技術(shù)因子。再比如,Two Sigma兩年前在Kaggle上舉辦過一項挑戰(zhàn),放出了積累了十幾年的上百個因子,主要有44個技術(shù)指標因子和63個基本面因子。結(jié)果一通操作下來,發(fā)現(xiàn)最顯著的還是技術(shù)因子。
局面就很詭異了。量化界研究下來,技術(shù)因子比基本面因子有效。傳統(tǒng)投資界又看不起技術(shù)分析。無論是寫研報還是做投資,大家都只關(guān)心財務數(shù)據(jù)。
按理說,財務數(shù)據(jù)的信息量應該遠大于技術(shù)指標,為什么就是不好呢?后來想明白了,原因很簡單:量化主要依據(jù)統(tǒng)計信息,無論什么指標,都要先進行回歸和檢驗。
然而,財務指標領(lǐng)域的知識極多,樣本又少,還呈現(xiàn)各種非線性,完全是統(tǒng)計模型的克星。文章來源地址http://www.zghlxwxcb.cn/news/detail-728899.html

到了這里,關(guān)于量化交易全流程(六)(待完善補充)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包