A级片三级毛片中文字幕|97人人干人人爱|aaaaa毛片亚洲av资源网|超碰97在线播放|日本一a级毛片欧美一区黄|日韩专区潮吹亚洲AV无码片|人人香蕉视频免费|中文字幕欧美激情极品|日本高清一级免费不卡|国模大胆在线国产啪视频

AQF
首頁 備考指南 精品課程 名師團隊 職業(yè)前景
您現(xiàn)在的位置:首頁備考必備AQF資料 AQF資料丨量化選股之因子檢驗和多因子模型的構(gòu)建

AQF資料丨量化選股之因子檢驗和多因子模型的構(gòu)建

發(fā)表時間: 2019-01-07 11:04:35 編輯:tansy

AQF資料丨今天要講的是多因子模型。多因子選股模型是廣泛應用的一種方法。采用一系列的因子作為選股標準,滿足則買入,不滿足則賣出。不同的市場時期總有一些因子在發(fā)揮作用,該模型相對來說比較穩(wěn)定。

  量化選股-多因子模型

  總體分為基本面選股、市場行為選股?;久孢x股包括:多因子模型,風格輪動模型,行業(yè)輪動模型。市場行為選股包括:資金流選股,動量反轉(zhuǎn)模型,一致預期模型,趨勢追蹤模型和籌碼選股。

  今天要講的是多因子模型。

  AQF資料丨多因子選股模型是廣泛應用的一種方法。采用一系列的因子作為選股標準,滿足則買入,不滿足則賣出。不同的市場時期總有一些因子在發(fā)揮作用,該模型相對來說比較穩(wěn)定。

  模型的優(yōu)點是可以綜合很多信息后給出一個選股結(jié)果。選取的因子不同以及如何綜合各個因子得到最終判斷的方法不同會產(chǎn)生不同的模型。一般來說,綜合因子的方法有打分法和回歸法兩種,打分法較為常見。

  模型構(gòu)建實例

  選取09-15年做樣本期,進行因子檢驗。

  benchmark = 000001.XSHG

  一.備選因子選取

  根據(jù)市場經(jīng)驗和經(jīng)濟邏輯選取。選擇更多和更有效的因子能增強模型信息捕獲能力。 如一些基本面指標(PB、PE、EPS、增長率),技術(shù)面指標(動量、換手率、波動),或其他指標(預期收益增長、分析師一致預期變化、宏觀經(jīng)濟變量)。

  結(jié)合JQ能提供的數(shù)據(jù),具體選取以下三個方面的因子:

  (1)估值:賬面市值比(B/M)、盈利收益率(EPS)、動態(tài)市盈(PEG)

  (2)成長性:ROE、ROA、主營毛利率(GP/R)、凈利率(P/R)

  (3)資本結(jié)構(gòu):資產(chǎn)負債(L/A)、固定資產(chǎn)比例(FAP)、流通市值(CMV)

  下面就上述10個因子的有效性進行驗證。

  二.因子有效性檢驗

  采用排序的方法檢驗備選因子的有效性。

  對任一個因子,從第一個月月初計算市場每只股票該因子的大小,從小到大對樣本股票池排序,平均分為n個組合,一直持有到月末。每月初用同樣的方法調(diào)整股票池。運用一定樣本時期的數(shù)據(jù)來建立模型。

  0.導入所需庫

  In [1]:

  import pandas as pd

  from pandas import Series, DataFrame

  import numpy as np

  import statsmodels.api as sm

  import scipy.stats as scs

  import matplotlib.pyplot as plt

  1.每月初取所有因子數(shù)值(以2015-01-01為例)

  (1)估值:賬面市值比(B/M)、盈利收益率(EPS)、動態(tài)市盈(PEG)

  (2)成長性:ROE、ROA、主營毛利率(GP/R)、凈利率(P/R)

  (3)資本結(jié)構(gòu):資產(chǎn)負債(L/A)、固定資產(chǎn)比例(FAP)、流通市值(CMV)

  In [2]:

  factors = ['B/M','EPS','PEG','ROE','ROA','GP/R','P/R','L/A','FAP','CMV']

  #月初取出因子數(shù)值

  def get_factors(fdate,factors):

  stock_set = get_index_stocks('000001.XSHG',fdate)

  q = query(

  valuation.code,

  balance.total_owner_equities/valuation.market_cap/100000000,

  income.basic_eps,

  valuation.pe_ratio,

  income.net_profit/balance.total_owner_equities,

  income.net_profit/balance.total_assets,

  income.total_profit/income.operating_revenue,

  income.net_profit/income.operating_revenue,

  balance.total_liability/balance.total_assets,

  balance.fixed_assets/balance.total_assets,

  valuation.circulating_market_cap

  ).filter(

  valuation.code.in_(stock_set),

  valuation.circulating_market_cap

  )

  fdf = get_fundamentals(q, date=fdate)

  fdf.index = fdf['code']

  fdf.columns = ['code'] + factors

  return fdf.iloc[:,-10:]

  fdf = get_factors('2015-01-01',factors)

  fdf.head()

  Out[2]:

  多因子模型的構(gòu)建

  2.對每個因子按大小排序(以'B/M'為例)

  In [3]:

  score = fdf['B/M'].order()

  score.head()

  Out[3]:

  code600301.XSHG -0.045989600444.XSHG -0.029723600228.XSHG -0.026231600217.XSHG -0.026090600876.XSHG -0.010862Name: B/M, dtype: float64

  股票池中股票數(shù)目

  In [4]:

  len(score)

  Out[4]:

  966

  3.按分值將股票池五等分構(gòu)造組合port1-5

  In [5]:

  startdate = '2015-01-01'

  enddate = '2015-02-01'

  nextdate = '2015-03-01'

  df = {}

  CMV = fdf['CMV']

  port1 = list(score.index)[: len(score)/5]

  port2 = list(score.index)[ len(score)/5: 2*len(score)/5]

  port3 = list(score.index)[ 2*len(score)/5: -2*len(score)/5]

  port4 = list(score.index)[ -2*len(score)/5: -len(score)/5]

  port5 = list(score.index)[ -len(score)/5: ]

  Out[5]:

  15066.599999999999

  4.函數(shù)-計算組合月收益(按流通市值加權(quán))

  In [6]:

  def caculate_port_monthly_return(port,startdate,enddate,nextdate,CMV):

  close1 = get_price(port, startdate, enddate, 'daily', ['close'])

  close2 = get_price(port, enddate, nextdate, 'daily',['close'])

  weighted_m_return = ((close2['close'].ix[0,:]/close1['close'].ix[0,:]-1)*CMV).sum()/(CMV.ix[port].sum())

  return weighted_m_return

  caculate_port_monthly_return(port1,'2015-01-01','2015-02-01','2015-03-01',fdf['CMV'])

  Out[6]:

  0.042660461430416276

  5.函數(shù)-計算benchmark月收益

  In [7]:

  def caculate_benchmark_monthly_return(startdate,enddate,nextdate):

  close1 = get_price(['000001.XSHG'],startdate,enddate,'daily',['close'])['close']

  close2 = get_price(['000001.XSHG'],enddate, nextdate, 'daily',['close'])['close']

  benchmark_return = (close2.ix[0,:]/close1.ix[0,:]-1).sum()

  return benchmark_return

  caculate_benchmark_monthly_return('2015-01-01','2015-02-01','2015-03-01')

  Out[7]:

  -0.06632375461831419

  6.觀察5個組合在2015-01-01日構(gòu)建起一個月內(nèi)的收益情況

  In [8]:

  benchmark_return =caculate_benchmark_monthly_return(startdate,enddate,nextdate)

  df['port1'] = caculate_port_monthly_return(port1,startdate,enddate,nextdate,CMV)

  df['port2'] = caculate_port_monthly_return(port2,startdate,enddate,nextdate,CMV)

  df['port3'] = caculate_port_monthly_return(port3,startdate,enddate,nextdate,CMV)

  df['port4'] = caculate_port_monthly_return(port4,startdate,enddate,nextdate,CMV)

  df['port5'] = caculate_port_monthly_return(port5,startdate,enddate,nextdate,CMV)

  print Series(df)

  print 'benchmark_return %s'%benchmark_returnOut[8]:

  port1 0.042660port2 -0.047200port3 0.012783port4 -0.063027port5 -0.117817dtype: float64benchmark_return -0.0663237546183

  7.構(gòu)建因子組合并計算每月?lián)Q倉時不同組合的月收益率

  數(shù)據(jù)范圍:2009-2015共7年

  得到結(jié)果monthly_return為panel數(shù)據(jù),儲存所有因子,在7×12個月內(nèi)5個組合及benchmark的月收益率

  In [9]:

  factors = ['B/M','EPS','PEG','ROE','ROA','GP/R','P/R','L/A','FAP','CMV']

  #因為研究模塊取fundmental數(shù)據(jù)默認date為研究日期的前一天。所以要自備時間序列。按月取

  year = ['2009','2010','2011','2012','2013','2014','2015']

  month = ['01','02','03','04','05','06','07','08','09','10','11','12']

  result = {}

  for i in range(7*12):

  startdate = year[i/12] + '-' + month[i%12] + '-01'

  try:

  enddate = year[(i+1)/12] + '-' + month[(i+1)%12] + '-01'

  except IndexError:

  enddate = '2016-01-01'

  try:

  nextdate = year[(i+2)/12] + '-' + month[(i+2)%12] + '-01'

  except IndexError:

  if enddate == '2016-01-01':

  nextdate = '2016-02-01'

  else:

  nextdate = '2016-01-01'

  print 'time %s'%startdate

  fdf = get_factors(startdate,factors)

  CMV = fdf['CMV']

  #5個組合,10個因子

  df = DataFrame(np.zeros(6*10).reshape(6,10),index = ['port1','port2','port3','port4','port5','benchmark'],columns = factors)

  for fac in factors:

  score = fdf[fac].order()

  port1 = list(score.index)[: len(score)/5]

  port2 = list(score.index)[ len(score)/5+1: 2*len(score)/5]

  port3 = list(score.index)[ 2*len(score)/5+1: -2*len(score)/5]

  port4 = list(score.index)[ -2*len(score)/5+1: -len(score)/5]

  port5 = list(score.index)[ -len(score)/5+1: ]

  df.ix['port1',fac] = caculate_port_monthly_return(port1,startdate,enddate,nextdate,CMV)

  df.ix['port2',fac] = caculate_port_monthly_return(port2,startdate,enddate,nextdate,CMV)

  df.ix['port3',fac] = caculate_port_monthly_return(port3,startdate,enddate,nextdate,CMV)

  df.ix['port4',fac] = caculate_port_monthly_return(port4,startdate,enddate,nextdate,CMV)

  df.ix['port5',fac] = caculate_port_monthly_return(port5,startdate,enddate,nextdate,CMV)

  df.ix['benchmark',fac] = caculate_benchmark_monthly_return(startdate,enddate,nextdate)

  print 'factor %s'%fac

  result[i+1]=df

  monthly_return = pd.Panel(result)

  8.取某個因子的5個組合收益情況('L/A'為例)

  In [10]:

  monthly_return[:,:,'L/A']

  Out [10]:

  多因子模型的構(gòu)建

  In [11]:

  (monthly_return[:,:,'L/A'].T+1).cumprod().tail()

  Out [11]:

  多因子模型構(gòu)建

  9.因子檢驗量化指標

  模型建立后,計算n個組合的年化復合收益、超額收益、不同市場情況下高收益組合跑贏benchmark和低收益組合跑輸benchmark的概率。

  檢驗有效性的量化標準:

  (1)序列1-n的組合,年化復合收益應滿足一定排序關(guān)系,即組合因子大小與收益具有較大相關(guān)關(guān)系。假定序列i的組合年化收益為Xi,則Xi與i的相關(guān)性絕對值A(chǔ)bs(Corr(Xi,i))>MinCorr。此處MinCorr為給定的最小相關(guān)閥值。

  (2)序列1和n表示的兩個極端組合超額收益分別為AR1、ARn。MinARtop、MinARbottom表示最小超額收益閥值。

  if AR1 > ARn #因子越小,收益越大

  則應滿足AR1 > MinARtop >0 and ARn < MinARbottom < 0

  if AR1 < ARn #因子越小,收益越大

  則應滿足ARn > MinARtop >0 and AR1 < MinARbottom < 0

  以上條件保證因子最大和最小的兩個組合,一個明顯跑贏市場,一個明顯跑輸市場。

  (3) 在任何市場行情下,1和n兩個極端組合,都以較高概率跑贏or跑輸市場。

  以上三個條件,可以選出過去一段時間有較好選股能力的因子。

  In [12]:

  total_return = {}

  annual_return = {}

  excess_return = {}

  win_prob = {}

  loss_prob = {}

  effect_test = {}

  MinCorr = 0.3

  Minbottom = -0.05

  Mintop = 0.05

  for fac in factors:

  effect_test[fac] = {}

  monthly = monthly_return[:,:,fac]

  total_return[fac] = (monthly+1).T.cumprod().iloc[-1,:]-1

  annual_return[fac] = (total_return[fac]+1)**(1./6)-1

  excess_return[fac] = annual_return[fac]- annual_return[fac][-1]

  #判斷因子有效性

  #1.年化收益與組合序列的相關(guān)性 大于 閥值

  effect_test[fac][1] = annual_return[fac][0:5].corr(Series([1,2,3,4,5],index = annual_return[fac][0:5].index))

  #2.高收益組合跑贏概率

  #因子小,收益小,port1是輸家組合,port5是贏家組合

  if total_return[fac][0] < total_return[fac][-2]:

  loss_excess = monthly.iloc[0,:]-monthly.iloc[-1,:]

  loss_prob[fac] = loss_excess[loss_excess<0].count()/float(len(loss_excess))

  win_excess = monthly.iloc[-2,:]-monthly.iloc[-1,:]

  win_prob[fac] = win_excess[win_excess>0].count()/float(len(win_excess))

  effect_test[fac][3] = [win_prob[fac],loss_prob[fac]]

  #超額收益

  effect_test[fac][2] = [excess_return[fac][-2]*100,excess_return[fac][0]*100]

  #因子小,收益大,port1是贏家組合,port5是輸家組合

  else:

  loss_excess = monthly.iloc[-2,:]-monthly.iloc[-1,:]

  loss_prob[fac] = loss_excess[loss_excess<0].count()/float(len(loss_excess))

  win_excess = monthly.iloc[0,:]-monthly.iloc[-1,:]

  win_prob[fac] = win_excess[win_excess>0].count()/float(len(win_excess))

  effect_test[fac][3] = [win_prob[fac],loss_prob[fac]]

  #超額收益

  effect_test[fac][2] = [excess_return[fac][0]*100,excess_return[fac][-2]*100]

  #effect_test[1]記錄因子相關(guān)性,>0.5或<-0.5合格

  #effect_test[2]記錄【贏家組合超額收益,輸家組合超額收益】

  #effect_test[3]記錄贏家組合跑贏概率和輸家組合跑輸概率?!?0.5,>0.4】合格(因?qū)嶋H情況,跑輸概率暫時不考慮)

  DataFrame(effect_test)

  Out[12]:

  多因子模型構(gòu)建

  多因子模型構(gòu)建

  檢驗結(jié)果,同時滿足上述三個條件的5個有效因子(粗體):

  (1)估值:賬面市值比(B/M)、盈利收益率(EPS)、動態(tài)市盈(PEG)

  (2)成長性:ROE、ROA、主營毛利率(GP/R)、凈利率(P/R)

  (3)資本結(jié)構(gòu):資產(chǎn)負債(L/A)、固定資產(chǎn)比例(FAP)、流通市值(CMV)

  其中:CMV,F(xiàn)AP,PEG三個因子越小收益越大;B/M,P/R越大收益越大

  (1)有效因子的總收益和年化收益

  小市值妖孽!!按CMV因子排序時,CMV小的組合總收益14.6倍,年化58%!總收益第二名是FAP的port2,達到2.71倍。(這也是造成FAP組合收益相關(guān)性稍低的原因)

  In [13]:

  effective_factors = ['B/M','PEG','P/R','FAP','CMV']

  DataFrame(total_return).ix[:,effective_factors]

  Out[13]:

  aqf1719

  In [14]:

  DataFrame(annual_return).ix[:,effective_factors]

  Out[14]:

  多因子模型構(gòu)建

  (2)有效因子組合和benchmark收益率展示

  In [15]:

  def draw_return_picture(df):

  plt.figure(figsize =(10,4))

  plt.plot((df.T+1).cumprod().ix[:,0], label = 'port1')

  plt.plot((df.T+1).cumprod().ix[:,1], label = 'port2')

  plt.plot((df.T+1).cumprod().ix[:,2], label = 'port3')

  plt.plot((df.T+1).cumprod().ix[:,3], label = 'port4')

  plt.plot((df.T+1).cumprod().ix[:,4], label = 'port5')

  plt.plot((df.T+1).cumprod().ix[:,5], label = 'benchmark')

  plt.xlabel('return of factor %s'%fac)

  plt.legend(loc=0)

  for fac in effective_factors:

  draw_return_picture(monthly_return[:,:,fac])

  Out [15]:

  多因子模型構(gòu)建

  多因子模型構(gòu)建

  多因子模型構(gòu)建

  多因子模型構(gòu)建

  多因子模型構(gòu)建

  3.冗余因子的剔除

  (僅給出思路,此處因子較少不做這一步)

  有些因子,因為內(nèi)在的邏輯比較相近等原因,選出來的組合在個股構(gòu)成和收益等方面相關(guān)性較高。所以要對這些因子做冗余剔除,保留同類因子中收益較好、區(qū)分度較高的因子。具體步驟:

  (1)對不同因子的n個組合打分。收益越大分值越大。分值達到好將分值賦給每月該組合內(nèi)的所有個股。

  if AR1 > ARn #因子越小,收益越大

  則組合i的分值為(n-i+1)

  if AR1 < ARn #因子越小,收益越小

  則組合i的分值為i

  (2)按月計算個股不同因子得分的相關(guān)性矩陣。得到第t月個股的因子得分相關(guān)性矩陣Score_Corrt,u,v。u,v為因子序號。

  (3)計算樣本期內(nèi)相關(guān)性矩陣的平均值。即樣本期共m個月,加總矩陣后取1/m。

  (4)設(shè)定得分相關(guān)性閥值MinScoreCorr。只保留與其他因子相關(guān)性較小的因子。

  4.模型建立和選股

  根據(jù)選好的有效因子,每月初對市場個股計算因子得分,按一定權(quán)重求得所有因子的平均分。如遇因子當月無取值時,按剩下的因子分值求加權(quán)平均。通過對個股的加權(quán)平均得分進行排序,選擇排名靠前的股票交易。

  以下代碼段等權(quán)重對因子分值求和,選出分值較高的股票進行交易。

  (1)模型構(gòu)建

  In [16]:

  def score_stock(fdate):

  #CMV,F(xiàn)AP,PEG三個因子越小收益越大,分值越大,應降序排;B/M,P/R越大收益越大應順序排

  effective_factors = {'B/M':True,'PEG':False,'P/R':True,'FAP':False,'CMV':False}

  fdf = get_factors(fdate)

  score = {}

  for fac,value in effective_factors.items():

  score[fac] = fdf[fac].rank(ascending = value,method = 'first')

  print DataFrame(score).T.sum().order(ascending = False).head(5)

  score_stock = list(DataFrame(score).T.sum().order(ascending = False).index)

  return score_stock,fdf['CMV']

  def get_factors(fdate):

  factors = ['B/M','PEG','P/R','FAP','CMV']

  stock_set = get_index_stocks('000001.XSHG',fdate)

  q = query(

  valuation.code,

  balance.total_owner_equities/valuation.market_cap/100000000,

  valuation.pe_ratio,

  income.net_profit/income.operating_revenue,

  balance.fixed_assets/balance.total_assets,

  valuation.circulating_market_cap

  ).filter(

  valuation.code.in_(stock_set)

  )

  fdf = get_fundamentals(q,date = fdate)

  fdf.index = fdf['code']

  fdf.columns = ['code'] + factors

  return fdf.iloc[:,-5:]

  [score_result,CMV] = score_stock('2016-01-01')

  Out [16]:

  code600382.XSHG 4274600638.XSHG 4224600291.XSHG 4092600791.XSHG 4078600284.XSHG 4031dtype: float64

  In [17]:

  year = ['2009','2010','2011','2012','2013','2014','2015']

  month = ['01','02','03','04','05','06','07','08','09','10','11','12']

  factors = ['B/M','PEG','P/R','FAP','CMV']

  result = {}

  for i in range(7*12):

  startdate = year[i/12] + '-' + month[i%12] + '-01'

  try:

  enddate = year[(i+1)/12] + '-' + month[(i+1)%12] + '-01'

  except IndexError:

  enddate = '2016-01-01'

  try:

  nextdate = year[(i+2)/12] + '-' + month[(i+2)%12] + '-01'

  except IndexError:

  if enddate == '2016-01-01':

  nextdate = '2016-02-01'

  else:

  nextdate = '2016-01-01'

  print 'time %s'%startdate

  #綜合5個因子打分后,劃分幾個組合

  df = DataFrame(np.zeros(7),index = ['Top20','port1','port2','port3','port4','port5','benchmark'])

  [score,CMV] = score_stock(startdate)

  port0 = score[:20]

  port1 = score[: len(score)/5]

  port2 = score[ len(score)/5+1: 2*len(score)/5]

  port3 = score[ 2*len(score)/5+1: -2*len(score)/5]

  port4 = score[ -2*len(score)/5+1: -len(score)/5]

  port5 = score[ -len(score)/5+1: ]

  print len(score)

  df.ix['Top20'] = caculate_port_monthly_return(port1,startdate,enddate,nextdate,CMV)

  df.ix['port1'] = caculate_port_monthly_return(port1,startdate,enddate,nextdate,CMV)

  df.ix['port2'] = caculate_port_monthly_return(port2,startdate,enddate,nextdate,CMV)

  df.ix['port3'] = caculate_port_monthly_return(port3,startdate,enddate,nextdate,CMV)

  df.ix['port4'] = caculate_port_monthly_return(port4,startdate,enddate,nextdate,CMV)

  df.ix['port5'] = caculate_port_monthly_return(port5,startdate,enddate,nextdate,CMV)

  df.ix['benchmark'] = caculate_benchmark_monthly_return(startdate,enddate,nextdate)

  result[i+1]=df

  backtest_results = pd.DataFrame(result)

  (哈哈,此處結(jié)果下一次再公布~)

  5.不足和改進

  隨著模型使用人數(shù)的增加,有的因子會逐漸失效,也可能出現(xiàn)一些新的因素需要加入到因子庫中。同時,各因子的權(quán)重設(shè)計有進一步改進空間。模型本身需要做持續(xù)的再評價,并不斷改進來適應市場的變化。

  >>>點擊咨詢量化金融分析師AQF實訓項目

AQF金融寬客交流群

  完善下表,48小時內(nèi)查收全套AQF備考資料

AQF資料索取框

  金程推薦: AQF考試 AQF報名 量化金融分析師

金融寬客交流群: 801860357

  聲明▎更多內(nèi)容請關(guān)注微信號量化金融分析師。

  >>>返回首頁

吐槽

對不起!讓你吐槽了

/500

上傳圖片

    可上傳3張圖片

    2001-2025 上海金程教育科技有限公司 All Rights Reserved. 信息系統(tǒng)安全等級:三級
    中央網(wǎng)信辦舉報中心 上海市互聯(lián)網(wǎng)舉報中心 不良信息舉報郵箱:law@gfedu.net
    滬ICP備14042082號 滬B2-20240743 通過ISO9001:2015 國際質(zhì)量管理體系認證 滬公網(wǎng)安備31010902103762號 出版物經(jīng)營許可證 電子營業(yè)執(zhí)照

    掃描二維碼登錄金程網(wǎng)校

    請使用新版 金程網(wǎng)校APP 掃碼完成登錄

    登錄即同意金程網(wǎng)校協(xié)議及《隱私政策》