北向資金能預示大盤漲跌?「附Python源碼」

01 引言

中國證監會於 2014 年和 2016 年分別批准了滬港通和深港通,建立了大陸和香港股市的互聯互通機制,市場通常把滬股通和深股通的合計流入資金稱為北向資金。換句話說,北上資金就是指從香港流入大陸股市的資金,而內地流入香港股市的資金則被稱為南下資金。市場廣 泛認為北向資金是“聰明錢”,會對市場的短期走勢有一定的指示作用,因此本文對該指標進行統計分析,並借鑑華泰金工研量化資產配置7月月報《北向資金走向預示市場短期或震盪》關於北上資金的擇時思路,構建基於北向資金的股市擇時策略,並進行歷史回測。結果表明,北向資金對於判斷滬深 300指數漲跌具有較好的預示作用


02 數據獲取

本文所使用的指數數據和北上資金數據均來自tushare.pro。如果由於積分受限,可在公眾號後臺回覆“北上資金”獲取相應csv格式數據。

<code>

import

 pandas 

as

 pd

import

 numpy 

as

 np

import

 matplotlib.pyplot 

as

 plt %matplotlib inline

from

 pylab 

import

 mpl mpl.rcParams[

'font.sans-serif'

]=[

'SimHei'

] mpl.rcParams[

'axes.unicode_minus'

]=

False

/<code>

由於tushare對北上資金數據的單次提取有限制(300條/次),需要通過獲取兩個時間週期內的交易日曆,分次提取數據。

<code>

import

 tushare 

as

 ts token=

'輸入你的token'

pro=ts.pro_api(token) /<code>
<code> 

def

 

get_cal_date

(start,

end

)

:     cal_date=pro.trade_cal(exchange=

''

, start_date=start, end_date=

end

)     cal_date=cal_date[cal_date.is_open==

1

]     dates=cal_date.cal_date.values     

return

 dates/<code>

定義北向資金數據獲取函數。

<code> 
def get_north_money(

start

,

end

):          dates=get_cal_date(

start

,

end

)          df=pro.moneyflow_hsgt(start_date=

start

, end_date=

end

)          

for

 i 

in

 

range

(

0

,

len

(dates)

-300

,

300

):         d0=pro.moneyflow_hsgt(start_date=dates[i], end_date=dates[i+

300

])         df=pd.concat([d0,df])                  df=df.drop_duplicates()         df.index=pd.to_datetime(df.trade_date)         df=df.sort_index()     

return

 df/<code>

定義指數數據獲取函數。

<code> 

def

 

get_index_data

(code,start,

end

)

:     index_df = pro.index_daily(ts_code=code, start_date=start,end_date=

end

)     index_df.index=pd.to_datetime(index_df.trade_date)     index_df=index_df.sort_index()     

return

 index_df/<code>


獲取常用的幾個指數2014-2020期間收盤價數據。

<code> 
 
indexs={

'上證綜指'

'000001.SH'

,

'深證成指'

'399001.SZ'

,

'滬深300'

'000300.SH'

,        

'創業板指'

'399006.SZ'

,

'上證50'

'000016.SH'

,

'中證500'

'000905.SH'

,        

'中小板指'

'399005.SZ'

,

'上證180'

'000010.SH'

} start=

'20141117'

end

=

'20200812'

/<code>
<code>index_data=pd.DataFrame()
for name,code in indexs.items():
    index_data[name]=get_index_data(code,

start

,

end

)[

'close'

] /<code>


03 探索性分析

理論上而言,股市的上漲離不開資金的推動,而市場的活躍又會反過來吸引更多資金加入博弈。近年來,北上資金受到市場的關注越來越大,被看作是短期市場風向標,與市場指數存在一定的正向關係。當然理論在現實中不一定成立,所以在利用北上資金構建擇時策略前,有必要先對指數和北上資金的關係進行探索性分析。

<code>#累計收益
(index_data/index_data.iloc[

0

])

.plot

(figsize=(

14

,

6

))

plt

.title

(

'A股指數累積收益率\n 2014-2020'

,size=

15

)

plt

.show

() /<code>
北向資金能預示大盤漲跌?「附Python源碼」

陸股通覆蓋大部分寬基指數成分股,即北向資金可投資的股票池覆蓋了上證 50、滬深 300、中證 500 的絕大多數指數成分股,下面對各大指數的收益率和北上資金進行相關性分析。

<code> 
all_ret=index_data/index_data.shift(1)-1
north_data=get_north_money(

start

,

end

) all_data=all_ret.join(north_data[

'north_money'

],how=

'inner'

) all_data.rename(

columns

={

'north_money'

:

'北向資金'

},inplace=

True

) all_data.dropna(inplace=

True

)/<code>
<code>

all_data

.corr

()/<code>
北向資金能預示大盤漲跌?「附Python源碼」


上圖顯示,2014年至2020年8月整個交易期間內,北上資金與各大指數收益率均存在一定的正相關,但相關係數較低,分佈在0.23-0.29之間。由於北上資金相對整個A股市場來說,體量還是比較小的,因此該指標的指示作用可能體現在短期內。下面使用120日的滾動窗口考察下北上資金與指數的相關性。


<code>

all_data

.rolling

(120)

.corr

()

.tail

(9) /<code>
北向資金能預示大盤漲跌?「附Python源碼」

數據顯示,北上資金與各大指數的滾動窗口120日相關係數均大於0.5,其中滬深300與北上資金相關係數最高(0.7),可見中短期內,北上資金的大小對指數收益率具有一定的指示作用。下面以滬深300指數為例,對二者的散點圖進行迴歸線擬合。圖形再次支持了北上資金與滬深300指數的正相關性。

<code>

import

 

seaborn

 

as

 

sns

plt

.figure

(figsize=(

10

6

))

sns

.regplot

(x=list(all_data[

"北向資金"

][

-120

:]),y=list(all_data[

"滬深300"

][

-120

:]))

plt

.title

(

'滬深300與北向資金擬合迴歸線'

,size=

15

)

plt

.xlabel

(

'北向資金'

,size=

12

)

plt

.ylabel

(

'滬深300收益率'

,size=

12

)

plt

.show

()/<code>


北向資金能預示大盤漲跌?「附Python源碼」


再來觀察一下滬深300日收益率與北上資金的波動情況,二者具有一定的同步性。

<code>#滬深

300

指數收益率與北向資金 final_data=all_data

[['滬深300','北向資金']]

.dropna() final_data.plot(secondary_y=

'北向資金'

,figsize=(

12

,

6

)) plt.title(

'滬深300日收益率 VS 北向資金'

,size=

15

) plt.show()/<code>
北向資金能預示大盤漲跌?「附Python源碼」


<code> 

def

 

cal_rol_cor

(data,period=

30

)

:

    cors=data.rolling(period).corr()     cors=cors.dropna().iloc[

1

::

2

,

0

]     cors=cors.reset_index()     cors=cors.set_index(

'trade_date'

)     

return

 cors[

'滬深300'

]/<code>


最後從縱向角度考察滬深300收益率與北上資金的相關性。數據顯示,2014年至2020年8月期間,二者相關係數均值為0.33,最大值為0.7。圖形顯示,二者的相關性近年來逐漸走高。

<code>cor=cal_rol_cor(final_data,period=120)
cor.describe()
/<code>
<code>

count

:1236

  

mean

:0.335

std

:0

.219

  

min

-0

.215

25%:0

.219

  50%:0

.379

75%:0

.525

  

max

:0

.706

/<code>
<code>

cor

.plot

(figsize=(

14

,

6

),label=

'移動120日相關係數'

)

plt

.title

(

'滬深300與北向資金移動120日相關係數'

,size=

15

)

plt

.axhline

(cor.mean(), c=

'r'

,label=

'相關係數均值=0.33'

)

plt

.legend

(loc=

2

)

plt

.show

()/<code>
北向資金能預示大盤漲跌?「附Python源碼」


04策略實例


從上面的探索性分析發現,北上資金與各大指數中短期內存在一定的正相關性,下面參考華泰金工研報的思路,基於北向資金變動數據構建布林帶擇時策略,並對擇時模型進行回測分析。


策略思路如下:

(1) 當該日北向資金流入規模 > 過去 252 個交易日的北向資金均值 + 1.5 倍標準差, 則全倉買入滬深 300;

(2) 當該日北向資金流入規模 < 過去 252 個交易日的北向資金均值 - 1.5 倍標準差, 則清倉賣出滬深 300;

(3) 以第二天開盤價買入(研報是以收盤價來計量)。


定義策略函數:

<code>

def

 

North_Strategy

(data,window,stdev_n,cost)

:

    

'''輸入參數:     data:包含北向資金和指數價格數據     window:移動窗口     stdev_n:幾倍標準差     cost:手續費     '''

         df=data.copy().dropna()     df[

'mid'

] = df[

'北向資金'

].rolling(window).mean()     stdev = df[

'北向資金'

].rolling(window).std()          df[

'upper'

] = df[

'mid'

] + stdev_n * stdev     df[

'lower'

] = df[

'mid'

] - stdev_n * stdev     df[

'ret'

]=df.close/df.close.shift(

1

)

-1

    df.dropna(inplace=

True

)               df.loc[df[

'北向資金'

]>df.upper, 

'signal'

] = 

1

         df.loc[df[

'北向資金'

]'signal'] = 

0

    df[

'position'

]=df[

'signal'

].shift(

1

)     df[

'position'

].fillna(method=

'ffill'

,inplace=

True

)     df[

'position'

].fillna(

0

,inplace=

True

)          df.loc[df.index[

0

], 

'capital_ret'

] = 

0

         df.loc[df[

'position'

] > df[

'position'

].shift(

1

), 

'capital_ret'

] = \                          (df.close/ df.open

-1

) * (

1

- cost)           df.loc[df[

'position'

] 'position'].shift(

1

), 

'capital_ret'

] = \                    (df.open / df.close.shift(

1

)

-1

) * (

1

-cost)           df.loc[df[

'position'

] == df[

'position'

].shift(

1

), 

'capital_ret'

] = \                         df[

'ret'

] * df[

'position'

]          df[

'策略淨值'

]=(df.capital_ret+

1.0

).cumprod()     df[

'指數淨值'

]=(df.ret+

1.0

).cumprod()     

return

 df/<code>


受篇幅所限,策略評價指標、可視化函數和主函數代碼省略,完整代碼見知識星球“Python金融量化”上分享(掃描下方二維碼即可加入)。

<code>

def

 

performance

(df)

:

     

pass

/<code>
<code> 

def

 

plot_performance

(df,name)

:

     

pass

/<code>
<code> 

def

 

main

(code=

'000300.SH'

,start=

'20141117'

,end=

'20200812'

,window=

252

,stdev_n=

1.5

,cost=

0.00

)

:

    

pass

/<code>


首先以滬深300指數進行回測,滾動窗口默認250日,手續費默認為0。回測結果顯示,基於北上資金的擇時策略表現較好,年化收益率17.8%,高於基準的5.3%,最大回撤17%低於基準32%,夏普比率為2.2。

<code>

main

(code=

'000300.SH'

)/<code>
<code>回測標的:滬深300指數
回測期間:20151208—20200812
策略年勝率為:80

.0

% 策略月勝率為:64

.58

% 策略周勝率為:60

.98

% 總收益率:  策略:106

.36

%,滬深300:26

.03

% 年化收益率:策略:17

.81

%, 滬深300:5

.37

% 最大回撤:  策略:17

.28

%, 滬深300:32

.46

% 策略

Alpha

: 0

.15

Beta

:0

.46

,夏普比率:2

.2

/<code>
北向資金能預示大盤漲跌?「附Python源碼」


考慮到北上資金2016年後才開始備受關注,而且前文的探索性分析也顯示相關性是2016年後逐年攀高,因此將回測起始時間改為2016年,交易手續費設置為1%(有點高)。結果顯示,這一期間(實際上是2017年至今)的擇時策略表現更佳,年化收益率達到24%。

<code>

main

(code=

'000300.SH'

,start=

'20161117'

,cost=

0.01

) /<code>
<code>回測標的:滬深300指數
回測期間:20171205—20200812
策略年勝率為:50

.0

% 策略月勝率為:65

.52

% 策略周勝率為:61

.86

% 總收益率:  策略:72

.01

%,滬深300:15

.65

% 年化收益率:策略:23

.93

%, 滬深300:5

.92

% 最大回撤:  策略:17

.29

%, 滬深300:32

.46

% 策略

Alpha

: 0

.21

Beta

:0

.45

,夏普比率:2

.1

/<code>
北向資金能預示大盤漲跌?「附Python源碼」


最後以創業板為標的進行歷史回測,結果顯示,策略效益整體優於基準,與滬深300指數相比,除了年化收益率外,其最大回撤和夏普比率相對差些。

<code>

main

(code=

'399006.SZ'

) /<code>
<code>回測標的:創業板指指數
回測期間:20151208—20200812
策略年勝率為:80

.0

% 策略月勝率為:54

.17

% 策略周勝率為:54

.88

% 總收益率:  策略:133

.88

%,滬深300:

-3

.75

% 年化收益率:策略:21

.19

%, 滬深300:

-0

.86

% 最大回撤:  策略:37

.17

%, 滬深300:57

.57

% 策略

Alpha

: 0

.22

Beta

:0

.5

,夏普比率:1

.92

/<code>
北向資金能預示大盤漲跌?「附Python源碼」


05 結語

本文對各大指數與北上資金的相關性進行了探索性分析,並借鑑華泰金工研報關於利用北上資金來構建擇時策略的思路,對滬深300和創業板指數進行了歷史回測。回測結果表明,北上資金的流動規模具有一定的實戰指示意義,短期內可用於對對大盤的走向進行研判,同時可用於對指數進行擇時,指導股指期貨交易。本文最後的歷史回測與研報原文並未完全吻合,但策略表現上大同小異,可能與回測環境的配置有關,感興趣的讀者可試試採用回測框架(如backtrader)或量化平臺進行更嚴謹的回測。本文的分析僅供學習參考,不構成任何投資建議!


參考資料:

華泰證券·《北向資金走向預示市場短期或震盪》2020.08

關於Python金融量化

專注於分享Python在金融量化領域的應用。加入知識星球,可以免費獲取量化投資視頻資料、量化金融相關PDF資料、公眾號文章Python完整源碼、量化投資前沿分析框架,與博主直接交流、結識圈內朋友等。

北向資金能預示大盤漲跌?「附Python源碼」


分享到:


相關文章: