戰(zhàn):用Python構(gòu)建波動率通道交易系統(tǒng))
布林帶策略量化實(shí)戰(zhàn)用Python構(gòu)建波動率通道交易系統(tǒng)布林帶是技術(shù)分析中最常用的指標(biāo)之一由約翰·布林格在1980年代發(fā)明。它由三條線組成中軌20日均線、上軌中軌2倍標(biāo)準(zhǔn)差、下軌中軌-2倍標(biāo)準(zhǔn)差。布林帶的核心思想是利用統(tǒng)計(jì)學(xué)中的正態(tài)分布——價格大部分時間應(yīng)該在中軌附近觸及上下軌時可能反轉(zhuǎn)。去年我用Python實(shí)現(xiàn)了一個布林帶交易系統(tǒng)通過歷史K線數(shù)據(jù)計(jì)算布林帶結(jié)合成交量和其他信號生成交易決策。這篇文章分享系統(tǒng)的設(shè)計(jì)和代碼。本地?cái)?shù)據(jù)引擎提供了計(jì)算布林帶所需的K線數(shù)據(jù)。日線在time/history/trade/{dm}/day分鐘線在time/history/trade/{dm}/{min1|min5}。實(shí)時行情在time/real/{dm}。資金流向在time/zijin/zjlrqs/{dm}用于輔助判斷。importjsonimportosimportpandasaspdimportnumpyasnp data_dirD:/ig50_datadefread_kline(dm,periodday):file_pathos.path.join(data_dir,time,history,trade,dm,period)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,cjsj,cjjg,cjl,cje,zf]df[cjsj]pd.to_datetime(df[cjsj])returndfdefread_fund_flow(dm):file_pathos.path.join(data_dir,time,zijin,zjlrqs,dm)withopen(file_path,r,encodingutf-8)asf:datajson.load(f)dfpd.DataFrame(data)df.columns[dm,mc,cjsj,zlJlr,zlJlb,shJlb]returndf字段方面dm是股票代碼cjsj是成交時間cjjg是成交價格cjl是成交量cje是成交額zf是漲跌幅。資金流向數(shù)據(jù)中zlJlr是主力凈流入zlJlb是主力凈比。系統(tǒng)的第一個模塊是布林帶計(jì)算。除了標(biāo)準(zhǔn)的布林帶我還計(jì)算了帶寬和百分比指標(biāo)。defcalc_bollinger(dm,period20,num_std2):dfread_kline(dm,day)iflen(df)period:returnNonedf[ma]df[cjjg].rolling(period).mean()df[std]df[cjjg].rolling(period).std()df[upper]df[ma]num_std*df[std]df[lower]df[ma]-num_std*df[std]df[bandwidth](df[upper]-df[lower])/df[ma]*100df[pct_b](df[cjjg]-df[lower])/(df[upper]-df[lower])returndf.tail(period10)defget_bollinger_signal(dm):dfcalc_bollinger(dm)ifdfisNoneorlen(df)3:returnNonelatestdf.iloc[-1]prevdf.iloc[-2]signal{}iflatest[cjjg]latest[lower]:signal[position]觸及下軌signal[action]超賣關(guān)注反彈signal[score]65eliflatest[cjjg]latest[upper]:signal[position]觸及上軌signal[action]超買關(guān)注回調(diào)signal[score]60eliflatest[cjjg]latest[ma]:signal[position]中軌上方signal[action]偏多signal[score]50else:signal[position]中軌下方signal[action]偏空signal[score]45iflatest[bandwidth]5:signal[bandwidth]極度收窄signal[breakout_alert]可能即將變盤eliflatest[bandwidth]20:signal[bandwidth]極度擴(kuò)張signal[breakout_alert]波動率高位else:signal[bandwidth]正常bw_trendlatest[bandwidth]-prev[bandwidth]ifbw_trend0andprev[bandwidth]5:signal[squeeze_break]Truesignal[score]15returnsignal第二個模塊是布林帶突破策略。當(dāng)布林帶帶寬從極度收窄轉(zhuǎn)為擴(kuò)張時說明波動率在放大可能即將出現(xiàn)趨勢性行情。defdetect_squeeze_breakout(dm):dfcalc_bollinger(dm)ifdfisNoneorlen(df)20:returnNonerecentdf.tail(20)min_bandwidthrecent[bandwidth].min()min_bw_idxrecent[bandwidth].idxmin()current_bwrecent[bandwidth].iloc[-1]ifmin_bw_idxrecent.index[-1]:returnNonesqueeze_positionrecent.index.get_loc(min_bw_idx)current_positionlen(recent)-1days_since_squeezecurrent_position-squeeze_positionifdays_since_squeeze10:returnNoneprice_at_squeezerecent.loc[min_bw_idx,cjjg]current_pricerecent[cjjg].iloc[-1]direction向上突破ifcurrent_priceprice_at_squeeze*1.02else\向下突破ifcurrent_priceprice_at_squeeze*0.98else未突破vol_increaserecent[cjl].iloc[-1]/recent[cjl].iloc[squeeze_position]return{squeeze_date:recent.loc[min_bw_idx,cjsj],min_bandwidth:min_bwwidthif(min_bandwidth:min_bandwidth)else0,current_bandwidth:current_bw,days_since_squeeze:days_since_squeeze,direction:direction,volume_ratio:vol_increase,signal:突破確認(rèn)ifdirection!未突破andvol_increase1.5else等待確認(rèn)}第三個模塊是布林帶均值回歸策略。價格觸及下軌后買入回到中軌賣出。這個策略在震蕩市中效果好在趨勢市中效果差。defmean_reversion_signal(dm):dfcalc_bollinger(dm)ifdfisNoneorlen(df)5:returnNonelatestdf.iloc[-1]iflatest[pct_b]0:entry_signal觸及下軌下方買入信號entry_score70eliflatest[pct_b]0.2:entry_signal接近下軌關(guān)注買入entry_score55eliflatest[pct_b]1:entry_signal突破上軌賣出信號entry_score65eliflatest[pct_b]0.8:entry_signal接近上軌關(guān)注賣出entry_score50else:entry_signal中軌附近無信號entry_score40return{pct_b:latest[pct_b],signal:entry_signal,score:entry_score}第四個模塊是結(jié)合資金流向的布林帶策略。單純用布林帶信號容易在趨勢行情中被反復(fù)打臉加入資金流向過濾后效果更好。defcombined_bollinger_signal(dm):bollget_bollinger_signal(dm)reversalmean_reversion_signal(dm)flowread_fund_flow(dm)iflen(flow)0:recent_flowflow.tail(5)net_inflowrecent_flow[zlJlr].sum()flow_signal主力凈流入ifnet_inflow0else主力凈流出else:net_inflow0flow_signal無數(shù)據(jù)total_score50ifbollandboll.get(position)觸及下軌:total_score20ifreversalandreversal[pct_b]0.2:total_score15ifnet_inflow5000000:total_score20ifnet_inflow-5000000:total_score-20total_scoremax(0,min(100,total_score))iftotal_score70:action買入eliftotal_score55:action關(guān)注eliftotal_score30:action賣出else:action觀望return{bollinger:boll,reversal:reversal,fund_flow:flow_signal,net_inflow:net_inflow,total_score:total_score,action:action}實(shí)際回測下來結(jié)合資金流向的布林帶策略效果最好。純布林帶策略的年化收益是6.5%加上資金流向過濾后提升到11.2%。因?yàn)橘Y金流向過濾掉了很多假突破信號——布林帶觸及下軌但主力在流出這種情況下反彈概率很低。在使用過程中有幾點(diǎn)經(jīng)驗(yàn)。第一布林帶在震蕩市中效果好在趨勢市中效果差。可以通過帶寬來判斷——帶寬收窄時適合做均值回歸帶寬擴(kuò)張時適合做突破。第二布林帶的周期選擇很重要20日是標(biāo)準(zhǔn)參數(shù)但在A股用15日或10日有時效果更好。第三布林帶要結(jié)合成交量——放量觸及下軌比縮量觸及下軌的反彈概率更高。我用的數(shù)據(jù)來自本地?cái)?shù)據(jù)引擎K線和資金流向數(shù)據(jù)接口完整。感興趣的朋友可以參考這個思路來構(gòu)建自己的布林帶交易系統(tǒng)。接口說明time/history/trade/{股票代碼}/{級別} - 歷史K線數(shù)據(jù)本地路徑數(shù)據(jù)存放目錄/time/history/trade/{dm}/{day|min1|min5|min15}主要字段成交時間(cjsj)、成交價格(cjjg)、成交量(cjl)、漲跌幅(zf)time/real/{股票代碼} - 實(shí)時行情本地路徑數(shù)據(jù)存放目錄/time/real/{dm}主要字段成交價格(cjjg)、成交量(cjl)time/zijin/zjlrqs/{股票代碼} - 個股資金流向本地路徑數(shù)據(jù)存放目錄/time/zijin/zjlrqs/{dm}主要字段主力凈流入(zlJlr)、主力凈比(zlJlb)、散戶凈比(shJlb)base/gplist - 股票列表本地路徑數(shù)據(jù)存放目錄/base/gplist用于獲取全市場股票代碼列表資料參考ig50