01引言
中國(guó)證監(jiān)會(huì)于 2014 年和 2016 年分別批準(zhǔn)了滬港通和深港通蠢挡,建立了大陸和香港股市的互聯(lián)互通機(jī)制弧岳,市場(chǎng)通常把滬股通和深股通的合計(jì)流入資金稱為北向資金。換句話說业踏,北上資金就是指從香港流入大陸股市的資金禽炬,而內(nèi)地流入香港股市的資金則被稱為南下資金。市場(chǎng)廣 泛認(rèn)為北向資金是“聰明錢”勤家,會(huì)對(duì)市場(chǎng)的短期走勢(shì)有一定的指示作用腹尖,因此本文對(duì)該指標(biāo)進(jìn)行統(tǒng)計(jì)分析,并借鑒華泰金工研量化資產(chǎn)配置7月月報(bào)《北向資金走向預(yù)示市場(chǎng)短期或震蕩》關(guān)于北上資金的擇時(shí)思路伐脖,構(gòu)建基于北向資金的股市擇時(shí)策略热幔,并進(jìn)行歷史回測(cè)。結(jié)果表明讼庇,北向資金對(duì)于判斷滬深 300指數(shù)漲跌具有較好的預(yù)示作用绎巨。
本文所使用的指數(shù)數(shù)據(jù)和北上資金數(shù)據(jù)均來自tushare.pro。如果由于積分受限蠕啄,可在公眾號(hào)后臺(tái)回復(fù)“北上資金”獲取相應(yīng)csv格式數(shù)據(jù)场勤。
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
由于tushare對(duì)北上資金數(shù)據(jù)的單次提取有限制(300條/次),需要通過獲取兩個(gè)時(shí)間周期內(nèi)的交易日歷歼跟,分次提取數(shù)據(jù)和媳。
import?tushare?as?ts
token='輸入你的token'
pro=ts.pro_api(token)
#獲取交易日歷
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
定義北向資金數(shù)據(jù)獲取函數(shù)。
#獲取北向資金數(shù)據(jù)
def?get_north_money(start,end):
????#獲取交易日歷
????dates=get_cal_date(start,end)
????#tushare限制流量哈街,每次只能獲取300條記錄
????df=pro.moneyflow_hsgt(start_date=start,?end_date=end)
????#拆分時(shí)間進(jìn)行拼接留瞳,再刪除重復(fù)項(xiàng)
????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])
????????#刪除重復(fù)項(xiàng)
????????df=df.drop_duplicates()
????????df.index=pd.to_datetime(df.trade_date)
????????df=df.sort_index()
????return?df
定義指數(shù)數(shù)據(jù)獲取函數(shù)。
#獲取指數(shù)數(shù)據(jù)
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
獲取常用的幾個(gè)指數(shù)2014-2020期間收盤價(jià)數(shù)據(jù)叹卷。
#獲取指數(shù)數(shù)據(jù)
#常用大盤指數(shù)
indexs={'上證綜指':?'000001.SH','深證成指':?'399001.SZ','滬深300':?'000300.SH',
???????'創(chuàng)業(yè)板指':?'399006.SZ','上證50':?'000016.SH','中證500':?'000905.SH',
???????'中小板指':?'399005.SZ','上證180':?'000010.SH'}
start='20141117'
end='20200812'
index_data=pd.DataFrame()
for?name,code?in?indexs.items():
????index_data[name]=get_index_data(code,start,end)['close']
#index_data.tail()
理論上而言撼港,股市的上漲離不開資金的推動(dòng),而市場(chǎng)的活躍又會(huì)反過來吸引更多資金加入博弈骤竹。近年來帝牡,北上資金受到市場(chǎng)的關(guān)注越來越大,被看作是短期市場(chǎng)風(fēng)向標(biāo)蒙揣,與市場(chǎng)指數(shù)存在一定的正向關(guān)系靶溜。當(dāng)然理論在現(xiàn)實(shí)中不一定成立,所以在利用北上資金構(gòu)建擇時(shí)策略前,有必要先對(duì)指數(shù)和北上資金的關(guān)系進(jìn)行探索性分析罩息。
#累計(jì)收益
(index_data/index_data.iloc[0]).plot(figsize=(14,6))
plt.title('A股指數(shù)累積收益率\n?2014-2020',size=15)
plt.show()
陸股通覆蓋大部分寬基指數(shù)成分股嗤详,即北向資金可投資的股票池覆蓋了上證 50、滬深 300瓷炮、中證 500 的絕大多數(shù)指數(shù)成分股葱色,下面對(duì)各大指數(shù)的收益率和北上資金進(jìn)行相關(guān)性分析。
#將價(jià)格數(shù)據(jù)轉(zhuǎn)為收益率
all_ret=index_data/index_data.shift(1)-1
north_data=get_north_money(start,end)
#north_data=pd.read_csv('north_data',index_col=0,header=0)
all_data=all_ret.join(north_data['north_money'],how='inner')
all_data.rename(columns={'north_money':'北向資金'},inplace=True)
all_data.dropna(inplace=True)
all_data.corr()
上圖顯示娘香,2014年至2020年8月整個(gè)交易期間內(nèi)苍狰,北上資金與各大指數(shù)收益率均存在一定的正相關(guān),但相關(guān)系數(shù)較低烘绽,分布在0.23-0.29之間淋昭。由于北上資金相對(duì)整個(gè)A股市場(chǎng)來說,體量還是比較小的安接,因此該指標(biāo)的指示作用可能體現(xiàn)在短期內(nèi)翔忽。下面使用120日的滾動(dòng)窗口考察下北上資金與指數(shù)的相關(guān)性。
all_data.rolling(120).corr().tail(9)
數(shù)據(jù)顯示盏檐,北上資金與各大指數(shù)的滾動(dòng)窗口120日相關(guān)系數(shù)均大于0.5歇式,其中滬深300與北上資金相關(guān)系數(shù)最高(0.7),可見中短期內(nèi)糯笙,北上資金的大小對(duì)指數(shù)收益率具有一定的指示作用贬丛。下面以滬深300指數(shù)為例,對(duì)二者的散點(diǎn)圖進(jìn)行回歸線擬合给涕。圖形再次支持了北上資金與滬深300指數(shù)的正相關(guān)性豺憔。
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()
再來觀察一下滬深300日收益率與北上資金的波動(dòng)情況,二者具有一定的同步性够庙。
#滬深300指數(shù)收益率與北向資金
final_data=all_data[['滬深300','北向資金']].dropna()
final_data.plot(secondary_y='北向資金',figsize=(12,6))
plt.title('滬深300日收益率?VS?北向資金',size=15)
plt.show()
#獲取北向資金與滬深300收益率的滾動(dòng)窗口相關(guān)系數(shù)
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']
最后從縱向角度考察滬深300收益率與北上資金的相關(guān)性恭应。數(shù)據(jù)顯示,2014年至2020年8月期間耘眨,二者相關(guān)系數(shù)均值為0.33昼榛,最大值為0.7。圖形顯示剔难,二者的相關(guān)性近年來逐漸走高胆屿。
cor=cal_rol_cor(final_data,period=120)
cor.describe()
count:1236??mean:0.335
std:0.219??min:-0.215
25%:0.219? 50%:0.379
75%:0.525??max:0.706
cor.plot(figsize=(14,6),label='移動(dòng)120日相關(guān)系數(shù)')
plt.title('滬深300與北向資金移動(dòng)120日相關(guān)系數(shù)',size=15)
plt.axhline(cor.mean(),?c='r',label='相關(guān)系數(shù)均值=0.33')
plt.legend(loc=2)
plt.show()
從上面的探索性分析發(fā)現(xiàn),北上資金與各大指數(shù)中短期內(nèi)存在一定的正相關(guān)性偶宫,下面參考華泰金工研報(bào)的思路非迹,基于北向資金變動(dòng)數(shù)據(jù)構(gòu)建布林帶擇時(shí)策略,并對(duì)擇時(shí)模型進(jìn)行回測(cè)分析纯趋。
策略思路如下:
(1) 當(dāng)該日北向資金流入規(guī)模 > 過去 252 個(gè)交易日的北向資金均值 + 1.5 倍標(biāo)準(zhǔn)差憎兽, 則全倉(cāng)買入滬深 300冷离;
(2) 當(dāng)該日北向資金流入規(guī)模 < 過去 252 個(gè)交易日的北向資金均值 - 1.5 倍標(biāo)準(zhǔn)差, 則清倉(cāng)賣出滬深 300纯命;
(3) 以第二天開盤價(jià)買入(研報(bào)是以收盤價(jià)來計(jì)量)西剥。
定義策略函數(shù):
def?North_Strategy(data,window,stdev_n,cost):
????'''輸入?yún)?shù):
????data:包含北向資金和指數(shù)價(jià)格數(shù)據(jù)
????window:移動(dòng)窗口
????stdev_n:幾倍標(biāo)準(zhǔn)差
????cost:手續(xù)費(fèi)
????'''
????#?中軌
????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)
????#設(shè)計(jì)買賣信號(hào)
????#當(dāng)日北向資金突破上軌線發(fā)出買入信號(hào)設(shè)置為1
????df.loc[df['北向資金']>df.upper,?'signal']?=?1
????#當(dāng)日北向資金跌破下軌線發(fā)出賣出信號(hào)設(shè)置為0
????df.loc[df['北向資金']<df.lower,?'signal']?=?0
????df['position']=df['signal'].shift(1)
????df['position'].fillna(method='ffill',inplace=True)
????df['position'].fillna(0,inplace=True)
????#根據(jù)交易信號(hào)和倉(cāng)位計(jì)算策略的每日收益率
????df.loc[df.index[0],?'capital_ret']?=?0
????#今天開盤新買入的position在今天的漲幅(扣除手續(xù)費(fèi))
????df.loc[df['position']?>?df['position'].shift(1),?'capital_ret']?=?\
?????????????????????????(df.close/?df.open-1)?*?(1-?cost)?
????#賣出同理
????df.loc[df['position']?<?df['position'].shift(1),?'capital_ret']?=?\
???????????????????(df.open?/?df.close.shift(1)-1)?*?(1-cost)?
????#?當(dāng)倉(cāng)位不變時(shí),當(dāng)天的capital是當(dāng)天的change?*?position
????df.loc[df['position']?==?df['position'].shift(1),?'capital_ret']?=?\
????????????????????????df['ret']?*?df['position']
????#計(jì)算標(biāo)的、策略亿汞、指數(shù)的累計(jì)收益率
????df['策略凈值']=(df.capital_ret+1.0).cumprod()
????df['指數(shù)凈值']=(df.ret+1.0).cumprod()
????return?df
受篇幅所限瞭空,策略評(píng)價(jià)指標(biāo)、可視化函數(shù)和主函數(shù)代碼省略疗我,完整代碼見知識(shí)星球“Python金融量化”上分享(掃描下方二維碼即可加入)匙铡。
def?performance(df):
?????pass
#對(duì)策略累計(jì)收益率進(jìn)行可視化
def?plot_performance(df,name):
?????pass
#將上述函數(shù)整合成一個(gè)執(zhí)行函數(shù)
def?main(code='000300.SH',start='20141117',end='20200812',window=252,stdev_n=1.5,cost=0.00):
????pass
首先以滬深300指數(shù)進(jìn)行回測(cè),滾動(dòng)窗口默認(rèn)250日碍粥,手續(xù)費(fèi)默認(rèn)為0『谝悖回測(cè)結(jié)果顯示嚼摩,基于北上資金的擇時(shí)策略表現(xiàn)較好,年化收益率17.8%矿瘦,高于基準(zhǔn)的5.3%枕面,最大回撤17%低于基準(zhǔn)32%,夏普比率為2.2缚去。
main(code='000300.SH')
回測(cè)標(biāo)的:滬深300指數(shù)
回測(cè)期間: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
考慮到北上資金2016年后才開始備受關(guān)注易结,而且前文的探索性分析也顯示相關(guān)性是2016年后逐年攀高枕荞,因此將回測(cè)起始時(shí)間改為2016年,交易手續(xù)費(fèi)設(shè)置為1%(有點(diǎn)高)搞动。結(jié)果顯示躏精,這一期間(實(shí)際上是2017年至今)的擇時(shí)策略表現(xiàn)更佳,年化收益率達(dá)到24%鹦肿。
main(code='000300.SH',start='20161117',cost=0.01)
回測(cè)標(biāo)的:滬深300指數(shù)
回測(cè)期間: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
最后以創(chuàng)業(yè)板為標(biāo)的進(jìn)行歷史回測(cè)箩溃,結(jié)果顯示瞭吃,策略效益整體優(yōu)于基準(zhǔn),與滬深300指數(shù)相比涣旨,除了年化收益率外歪架,其最大回撤和夏普比率相對(duì)差些。
main(code='399006.SZ')
回測(cè)標(biāo)的:創(chuàng)業(yè)板指指數(shù)
回測(cè)期間: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
本文對(duì)各大指數(shù)與北上資金的相關(guān)性進(jìn)行了探索性分析,并借鑒華泰金工研報(bào)關(guān)于利用北上資金來構(gòu)建擇時(shí)策略的思路,對(duì)滬深300和創(chuàng)業(yè)板指數(shù)進(jìn)行了歷史回測(cè)惠呼〉挤回測(cè)結(jié)果表明,北上資金的流動(dòng)規(guī)模具有一定的實(shí)戰(zhàn)指示意義剔蹋,短期內(nèi)可用于對(duì)對(duì)大盤的走向進(jìn)行研判旅薄,同時(shí)可用于對(duì)指數(shù)進(jìn)行擇時(shí),指導(dǎo)股指期貨交易泣崩。本文最后的歷史回測(cè)與研報(bào)原文并未完全吻合少梁,但策略表現(xiàn)上大同小異,可能與回測(cè)環(huán)境的配置有關(guān)矫付,感興趣的讀者可試試采用回測(cè)框架(如backtrader)或量化平臺(tái)進(jìn)行更嚴(yán)謹(jǐn)?shù)幕販y(cè)凯沪。本文的分析僅供學(xué)習(xí)參考,不構(gòu)成任何投資建議买优!
參考資料:
?華泰證券·《北向資金走向預(yù)示市場(chǎng)短期或震蕩》2020.08
專注于分享Python在金融量化領(lǐng)域的應(yīng)用妨马。加入知識(shí)星球,可以免費(fèi)獲取量化投資視頻資料杀赢、量化金融相關(guān)PDF資料烘跺、公眾號(hào)文章Python完整源碼、量化投資前沿分析框架脂崔,與博主直接交流滤淳、結(jié)識(shí)圈內(nèi)朋友等。