backtrader股票技術指標自定義與量化回測

01?引言

股票市場自交易以來芙粱,人們就開始孜孜不倦地探索各種各樣的投資理論,其中技術分析是重要的理論之一滑潘。實際上衫哥,技術分析是100多年前創(chuàng)建的股票投資理論化撕,是投資者對股票量價變化長期觀察歸納總結的若干“規(guī)律”。技術分析以市場行為(價格和成交量)為研究對象,以判斷市場趨勢并跟隨趨勢的周期性變化來指導交易,認為市場行為包容一切信息、價格以趨勢方式波動窗宇、歷史會重演。目前特纤,股票分析的技術指標超過1000多種军俊,從功能角度而言,總體可以分為趨勢類捧存、擺動類和能量類指標粪躬。趨勢類指標結合均線特征,根據(jù)股價與指標之間的關系分析股價趨勢強弱昔穴,如MACD指標镰官。擺動類指標根據(jù)股票的成交量、價格和時空吗货,通過公式得出一個數(shù)值泳唠,通過該數(shù)值波動規(guī)律指導交易,如KDJ宙搬、RSI指標笨腥。能量類指標通過分析成交量變化來預測股價波動,如OBV勇垛、VOL指標等脖母。本文主要介紹backtrader回測框架中技術分析指標(indicators)的調用方法、自定義指標的編寫以及技術指標的歷史回測闲孤。


關于backtrader的入門和進階見公眾號系列推文:

(1)【手把手教你】入門量化回測最強神器backtrader(一)

(2)【手把手教你】入門量化回測最強神器backtrader(二)

(3)【手把手教你】入門量化回測最強神器backtrader(三)

(4)backtrader如何加載股票因子數(shù)據(jù)谆级?以換手率、市盈率為例進行回測【附Python代碼】

(5)如何用backtrader對股票組合進行量化回測?

(6)【手把手教你】用backtrader量化回測海龜交易策略

02?Indicators指標調用


backtrader回測框架內置了很多技術分析指標肥照,封裝在indicators中脚仔。打開backtrader安裝路徑,以Anaconda為例舆绎,打開\Lib\site-packages\backtrader\玻侥,進入indicators文件夾,可以看到里面有48個py文件亿蒸,文件名是各個技術指標或公示的簡稱,打開這些文件可以進一步了解包含的具體指標掌桩,以及調用的函數(shù)名和參數(shù)等边锁。


以MACD指標為例,使用Notepad++軟件打開macd.py文件波岛,可以看到MACD和MACDHisto兩個類茅坛,其中MACD是計算MACD指標的類,而MACDHisto則是MACD的子類则拷,增加了macd和信號線之間差異的“直方圖”贡蓖,調用的時候直接使用bt.ind.MACD(參數(shù))。下面以常用的MACD煌茬、RSI斥铺、布林帶指標為例,為大家展示其調用方法坛善。

使用tushare獲取數(shù)據(jù)晾蜘,并設置為backtrader的數(shù)據(jù)格式。

import?backtrader?as?bt
import?pandas?as?pd
import?numpy?as?np
import?tushare?as?ts?
def?get_data(code,start='2010-01-01',end='2020-08-31'):
????df=ts.get_k_data(code,autype='qfq',start=start,end=end)
????df.index=pd.to_datetime(df.date)
????df['openinterest']=0
????df=df[['open','high','low','close','volume','openinterest']]
????return?df

dataframe=get_data('600000',start='2015-01-01')
dataframe.head()


寫一個測試策略眠屎,在輸出圖形中呈現(xiàn)MACD剔交、MACD帶柱、RSI和布林帶技術指標改衩。

class?TestStrategy(bt.Strategy):

????def?__init__(self):
????????bt.ind.MACD(self.data)
????????bt.ind.MACDHisto(self.data)
????????bt.ind.RSI(self.data,period=14)
????????bt.ind.BBands(self.data)

將回測系統(tǒng)設置封裝成main函數(shù)岖常,后面還會反復用到。

def?main(data,strategy,pf=False):
????cerebro?=?bt.Cerebro()
????feed?=?bt.feeds.PandasData(dataname=data)
????cerebro.adddata(feed)?
????#加載策略
????cerebro.addstrategy(strategy)
????#?設置初始資本為10,000
????startcash?=?100000
????cerebro.broker.setcash(startcash)?
????#?設置交易手續(xù)費為?0.1%
????cerebro.broker.setcommission(commission=0.001)?
????cerebro.run()
????#獲取回測結束后的總資金
????portvalue?=?cerebro.broker.getvalue()
????pnl?=?portvalue?-?startcash
????if?pf:
????????print(f'總資金:?{round(portvalue,2)}')
????????print(f'凈收益:?{round(pnl,2)}')
????%matplotlib?inline
????cerebro.plot()


回測結果如下圖所示葫督。

data=get_data('601318','2020-03-01')
main(data,TestStrategy)

上述策略只是調用了技術指標用于畫圖竭鞍,下面以MACD指標為例,調用該指標計算MACD柱橄镜,當MACD柱大于0(金叉)時發(fā)出買入信號笼蛛,當MACD柱小于0(死叉)時發(fā)出賣出信號。

class?TradeStrategy(bt.Strategy):
????params=(('p1',12),('p2',26),('p3',9),)
????def?__init__(self):
????????self.order?=?None
????????#獲取MACD柱
????????self.macdhist?=?bt.ind.MACDHisto(self.data,
????????????????????????period_me1=self.p.p1,?
????????????????????????period_me2=self.p.p2,?
????????????????????????period_signal=self.p.p3)
????def?next(self):
????????if?not?self.position:
????????????#?得到當前的賬戶價值
????????????total_value?=?self.broker.getvalue()
????????????#1手=100股蛉鹿,滿倉買入
????????????ss=int((total_value/100)/self.datas[0].close[0])*100
????????????#當MACD柱大于0(紅柱)且無持倉時滿倉買入
????????????if?self.macdhist?>?0:
????????????????self.order=self.buy(size=ss)
????????else:
????????????#當MACD柱小于0(綠柱)且持倉時全部清倉
????????????if?self.macdhist?<?0:
????????????????self.close()


以中國平安股票為例滨砍,使用MACD指標對2010.1-2020.9年數(shù)據(jù)進行歷史回測。

data=get_data('601318','2010-03-01')
main(data,TradeStrategy,pf=True)

#期初資金:100000
#期末資金:?225440.47
#凈收益:?125440.47


03?自定義指標


backtrader的可擴展性很強,除了內置的技術分析指標外惋戏,可以通過類的擴展進行自定義指標领追。20日均線在實戰(zhàn)中具有一定的指導意義,可以根據(jù)價格偏離20日均線的某個閾值構建類似于布林帶的通道線指標响逢。


定義一個指標的類绒窑,該類繼承bt.Indicator,均線采用20日周期舔亭,上下限閾值分別為20%和15%些膨。

class?TrendBand(bt.Indicator):

????lines?=?('mid','top','bot',)
????params?=?(('maperiod',20),
??????????????('period',3),
??????????????('highRate',1.2),
??????????????('lowRate',0.85),)
????#與價格在同一張圖
????plotinfo?=?dict(subplot=False)

????def?__init__(self):
????????ema?=?bt.ind.EMA(self.data,?period=self.p.maperiod)
????????#計算上中下軌線
????????self.l.mid=bt.ind.EMA(ema,period=self.p.period)
????????self.l.top=bt.ind.EMA(self.mid*self.p.highRate,\
??????????????????????????????period=self.p.period)
????????self.l.bot=bt.ind.EMA(self.mid*self.p.lowRate,\
??????????????????????????????period=self.p.period)
????????super(TrendBand,?self).__init__()

首先看一下該指標的圖形。

class?TestStrategy2(bt.Strategy):
????def?__init__(self):
????????TrendBand(self.data)

回測結果:

data=get_data('601318','2010-01-01')
main(data,TestStrategy2)

下面基于該指標構建交易策略并回測钦铺,當價格站在中軌線上订雾,且成交量突破20日新高時買入,當價格突破上軌線時賣出矛洞。

class?MyStrategy(bt.Strategy):
????params=(('period',20),)
????def?__init__(self):
????????self.order?=?None
????????self.mid?=?TrendBand(self.data).mid?
????????self.top?=?TrendBand(self.data).top
????????self.bot?=?TrendBand(self.data).bot
????????#設置買入信號
????????self.buy_sig=bt.And(\
???????????self.data.close>self.mid,\
???????????self.data.volume==bt.ind.Highest(\
???????????self.data.volume,period=self.p.period))
????????#賣出信號
????????self.sell_sig=self.data.close>self.top
????def?next(self):
????????if?not?self.position:
????????????#?得到當前的賬戶價值
????????????total_value?=?self.broker.getvalue()
????????????#1手=100股洼哎,滿倉買入
????????????ss=int((total_value/100)/self.datas[0].close[0])*100
????????????if?self.buy_sig:
????????????????self.order=self.buy(size=ss)
????????else:
????????????if?self.sell_sig:
????????????????self.close()

仍然以中國平安為例,回測結果如下圖所示:

data=get_data('601318','2010-01-01')
main(data,MyStrategy,True)

#期初資金:100000.00
#期末資金:?398949.39
#凈收益:?298949.39




04?結語

本文主要介紹了backtrader回測框架中indicators的調用沼本、自定義指標的編寫以及歷史回測噩峦。其中自定義指標主要是示例作用,不構成任何投資建議抽兆。歷史回測中僅以中國平安個股為例识补,具有一定的局限性,感興趣的讀者可以參考組合回測那篇推文辫红,對全市場股票進行組合回測以進一步判斷自定義指標的實用性李请。最后再強調一句,學習沒有捷徑厉熟,要想全面而深入地學習backtrader回測框架导盅,最好的方法是研讀其官方文檔。公眾號后臺回復“backtrader”可獲取《backtrader入門指南》的中文文檔揍瑟。


參考資料:

?backtrader官方文檔和安裝包原生代碼

? ? https://www.backtrader.com/docu/


關于Python金融量化








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

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末熙涤,一起剝皮案震驚了整個濱河市阁苞,隨后出現(xiàn)的幾起案子困檩,更是在濱河造成了極大的恐慌,老刑警劉巖那槽,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悼沿,死亡現(xiàn)場離奇詭異,居然都是意外死亡骚灸,警方通過查閱死者的電腦和手機糟趾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來甚牲,“玉大人义郑,你說我怎么就攤上這事≌筛疲” “怎么了非驮?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長著恩。 經常有香客問我,道長蜻展,這世上最難降的妖魔是什么喉誊? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮纵顾,結果婚禮上伍茄,老公的妹妹穿的比我還像新娘。我一直安慰自己施逾,他們只是感情好敷矫,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著汉额,像睡著了一般曹仗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蠕搜,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天怎茫,我揣著相機與錄音,去河邊找鬼妓灌。 笑死轨蛤,一個胖子當著我的面吹牛,可吹牛的內容都是我干的虫埂。 我是一名探鬼主播祥山,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼掉伏!你這毒婦竟也來了缝呕?” 一聲冷哼從身側響起澳窑,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岳颇,沒想到半個月后照捡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡话侧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年栗精,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞻鹏。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡悲立,死狀恐怖,靈堂內的尸體忽然破棺而出新博,到底是詐尸還是另有隱情薪夕,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布赫悄,位于F島的核電站原献,受9級特大地震影響,放射性物質發(fā)生泄漏埂淮。R本人自食惡果不足惜姑隅,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望倔撞。 院中可真熱鬧讲仰,春花似錦、人聲如沸痪蝇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躏啰。三九已至趁矾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間给僵,已是汗流浹背愈魏。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留想际,地道東北人培漏。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像胡本,于是被迫代替她去往敵國和親牌柄。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345