01 引言
中國證監會於 2014 年和 2016 年分別批准了滬港通和深港通,建立了大陸和香港股市的互聯互通機制,市場通常把滬股通和深股通的合計流入資金稱為北向資金。換句話說,北上資金就是指從香港流入大陸股市的資金,而內地流入香港股市的資金則被稱為南下資金。市場廣 泛認為北向資金是“聰明錢”,會對市場的短期走勢有一定的指示作用,因此本文對該指標進行統計分析,並借鑑華泰金工研量化資產配置7月月報《北向資金走向預示市場短期或震盪》關於北上資金的擇時思路,構建基於北向資金的股市擇時策略,並進行歷史回測。結果表明,北向資金對於判斷滬深 300指數漲跌具有較好的預示作用。
02 數據獲取
本文所使用的指數數據和北上資金數據均來自tushare.pro。如果由於積分受限,可在公眾號後臺回覆“北上資金”獲取相應csv格式數據。
<code>import
pandasas
pdimport
numpyas
npimport
matplotlib.pyplotas
plt %matplotlib inlinefrom
pylabimport
mpl mpl.rcParams['font.sans-serif'
]=['SimHei'
] mpl.rcParams['axes.unicode_minus'
]=False
/<code>
由於tushare對北上資金數據的單次提取有限制(300條/次),需要通過獲取兩個時間週期內的交易日曆,分次提取數據。
<code>import
tushareas
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.valuesreturn
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
iin
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>
陸股通覆蓋大部分寬基指數成分股,即北向資金可投資的股票池覆蓋了上證 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>
上圖顯示,2014年至2020年8月整個交易期間內,北上資金與各大指數收益率均存在一定的正相關,但相關係數較低,分佈在0.23-0.29之間。由於北上資金相對整個A股市場來說,體量還是比較小的,因此該指標的指示作用可能體現在短期內。下面使用120日的滾動窗口考察下北上資金與指數的相關性。
<code>all_data
.rolling
(120).corr
().tail
(9) /<code>
數據顯示,北上資金與各大指數的滾動窗口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>
再來觀察一下滬深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>
<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>
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>
考慮到北上資金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>
最後以創業板為標的進行歷史回測,結果顯示,策略效益整體優於基準,與滬深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>
05 結語
本文對各大指數與北上資金的相關性進行了探索性分析,並借鑑華泰金工研報關於利用北上資金來構建擇時策略的思路,對滬深300和創業板指數進行了歷史回測。回測結果表明,北上資金的流動規模具有一定的實戰指示意義,短期內可用於對對大盤的走向進行研判,同時可用於對指數進行擇時,指導股指期貨交易。本文最後的歷史回測與研報原文並未完全吻合,但策略表現上大同小異,可能與回測環境的配置有關,感興趣的讀者可試試採用回測框架(如backtrader)或量化平臺進行更嚴謹的回測。本文的分析僅供學習參考,不構成任何投資建議!
參考資料:
華泰證券·《北向資金走向預示市場短期或震盪》2020.08
關於Python金融量化
專注於分享Python在金融量化領域的應用。加入知識星球,可以免費獲取量化投資視頻資料、量化金融相關PDF資料、公眾號文章Python完整源碼、量化投資前沿分析框架,與博主直接交流、結識圈內朋友等。