1 引言
目前基于Python的量化回測框架有很多精绎,開源框架有zipline歪泳、vnpy锉屈、pyalgotrader和backtrader等,而量化平臺有Quantopian(國外)办龄、聚寬烘绽、萬礦、優(yōu)礦俐填、米筐安接、掘金等,這些量化框架或平臺各有優(yōu)劣英融。就個人而言盏檐,比較偏好用backtrader呀打,因為它功能十分完善,有完整的使用文檔糯笙,安裝相對簡單(直接pip安裝即可)贬丛。優(yōu)點是運(yùn)行速度快,支持pandas的矢量運(yùn)算给涕;支持參數(shù)自動尋優(yōu)運(yùn)算豺憔,內(nèi)置了talib股票分析技術(shù)指標(biāo)庫;支持多品種够庙、多策略恭应、多周期的回測和交易;支持pyflio耘眨、empyrica分析模塊庫昼榛、alphalens多因子分析模塊庫等;擴(kuò)展靈活剔难,可以集成TensorFlow胆屿、PyTorch和Keras等機(jī)器學(xué)習(xí)、神經(jīng)網(wǎng)絡(luò)分析模塊偶宫。而不足之處在于非迹,backtrader學(xué)習(xí)起來相對復(fù)雜,編程過程中使用了大量的元編程(類class)纯趋,如果Python編程基礎(chǔ)不扎實(尤其是類的操作)憎兽,學(xué)起來會感到吃力。本文作為backtrader的入門系列之一吵冒,對其運(yùn)行框架進(jìn)行簡要介紹纯命,并以實際案例展示量化回測的過程。
2 backtrader簡介
如果將backtrader包分解為核心組件痹栖,主要包括以下組成部分:
(1)數(shù)據(jù)加載(Data Feed):將
交易策略的數(shù)據(jù)加載到回測框架中亿汞。??
(2)交易策略(Strategy):該模塊是編程過程中最復(fù)雜的部分,需要設(shè)計交易決策结耀,得出買入/賣出信號留夜。
(3)回測框架設(shè)置(?Cerebro):需要設(shè)置(i)初始資金(ii)傭金(iii)數(shù)據(jù)饋送(iv)交易策略(v)交易頭寸大小匙铡。
(4)運(yùn)行回測:運(yùn)行Cerebro回測并打印出所有已執(zhí)行的交易图甜。
(5)評估性能(Analyzers):以圖形和風(fēng)險收益等指標(biāo)對交易策略的回測結(jié)果進(jìn)行評價。
“Lines”是backtrader回測的數(shù)據(jù)鳖眼,由一系列的點組成黑毅,通常包括以下類別的數(shù)據(jù):Open(開盤價), High(最高價), Low(最低價), Close(收盤價), Volume(成交量), OpenInterest(無的話設(shè)置為0)。Data Feeds(數(shù)據(jù)加載)钦讳、Indicators(技術(shù)指標(biāo))和Strategies(策略)都會生成 Lines矿瘦。價格數(shù)據(jù)中的所有”O(jiān)pen” (開盤價)按時間組成一條 Line枕面。所以,一組含有以上6個類別的價格數(shù)據(jù)缚去,共有6條 Lines潮秘。如果算上“DateTime”(時間,可以看作是一組數(shù)據(jù)的主鍵)易结,一共有7條 Lines枕荞。當(dāng)訪問一條 Line 的數(shù)據(jù)時,會默認(rèn)指向下標(biāo)為 0 的數(shù)據(jù)搞动。最后一個數(shù)據(jù)通過下標(biāo) -1 來訪問躏精,在-1之后是索引0,用于訪問當(dāng)前時刻鹦肿。因此矗烛,在回測過程中,無需知道已經(jīng)處理了多少條/分鐘/天/月箩溃,”0”一直指向當(dāng)前值瞭吃,下標(biāo) -1 來訪問最后一個值。
3 回測應(yīng)用實例
量化回測說白了是使用歷史數(shù)據(jù)去驗證交易策略的性能涣旨,因此回測的第一步是搭建交易策略虱而,這也是backtrader要設(shè)置的最重要和復(fù)雜的部分,策略設(shè)定好后开泽,其余部分的代碼編寫是手到擒來牡拇。
01 構(gòu)建策略(Strategy)
交易策略類代碼包含重要的參數(shù)和用于執(zhí)行策略的功能,要定義的參數(shù)或函數(shù)名如下:
(1)params-全局參數(shù)穆律,可選:更改交易策略中變量/參數(shù)的值惠呼,可用于參數(shù)調(diào)優(yōu)。?
(2)log:日志峦耘,可選:記錄策略的執(zhí)行日志剔蹋,可以打印出該函數(shù)提供的日期時間和txt變量。
(3) __init__:用于初始化交易策略的類實例的代碼辅髓。?
(4)notify_order泣崩,可選:跟蹤交易指令(order)的狀態(tài)。order具有提交洛口,接受矫付,買入/賣出執(zhí)行和價格,已取消/拒絕等狀態(tài)第焰。?
(5)notify_trade买优,可選:跟蹤交易的狀態(tài),任何已平倉的交易都將報告毛利和凈利潤。?
(6)next杀赢,必選:制定交易策略的函數(shù)烘跺,策略模塊最核心的部分。
下面以一個簡單的單均線策略為例脂崔,展示backtrader的使用過程滤淳,即當(dāng)收盤價上漲突破20日均線買入(做多),當(dāng)收盤價下跌跌穿20日均線賣出(做空)砌左。為簡單起見娇钱,不報告交易回測的日志,因此log绊困、notify_order和notify_trade函數(shù)省略不寫文搂。
classmy_strategy1(bt.Strategy):
#全局設(shè)定交易策略的參數(shù)
params=(
('maperiod',20),
)
def__init__(self):
#指定價格序列
self.dataclose=self.datas[0].close
#?初始化交易指令、買賣價格和手續(xù)費(fèi)
self.order?=None
self.buyprice?=None
self.buycomm?=None
#添加移動均線指標(biāo)秤朗,內(nèi)置了talib模塊
self.sma?=?bt.indicators.SimpleMovingAverage(
self.datas[0],?period=self.params.maperiod)
defnext(self):
ifself.order:#?檢查是否有指令等待執(zhí)行,?
return
#?檢查是否持倉???
ifnotself.position:#?沒有持倉
#執(zhí)行買入條件判斷:收盤價格上漲突破20日均線
ifself.dataclose[0]?>?self.sma[0]:
#執(zhí)行買入
self.order?=?self.buy(size=500)
else:
#執(zhí)行賣出條件判斷:收盤價格跌破20日均線
ifself.dataclose[0]?<?self.sma[0]:
#執(zhí)行賣出
self.order?=?self.sell(size=500)
02 數(shù)據(jù)加載(Data Feeds)
策略設(shè)計好后煤蹭,第二步是數(shù)據(jù)加載,backtrader提供了很多數(shù)據(jù)接口取视,包括quandl(美股)硝皂、yahoo、pandas格式數(shù)據(jù)等作谭,我們主要分析A股數(shù)據(jù)稽物。
mpl.rcParams['axes.unicode_minus']=False
#先引入后面可能用到的包(package)
importpandasaspd
fromdatetimeimportdatetime
importbacktraderasbt
importmatplotlib.pyplotasplt
%matplotlib?inline
#正常顯示畫圖時出現(xiàn)的中文和負(fù)號
frompylabimportmpl
mpl.rcParams['font.sans-serif']=['SimHei']
使用tushare獲取浦發(fā)銀行(代碼:600000)數(shù)據(jù)。
#使用tushare舊版接口獲取數(shù)據(jù)
importtushareasts
defget_data(code,start='2010-01-01',end='2020-03-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']]
returndf
dataframe=get_data('600000')
#回測期間
start=datetime(2010,?3,?31)
end=datetime(2020,?3,?31)
#?加載數(shù)據(jù)
data?=?bt.feeds.PandasData(dataname=dataframe,fromdate=start,todate=end)
03 回測設(shè)置(Cerebro)
回測設(shè)置主要包括幾項:回測系統(tǒng)初始化折欠,數(shù)據(jù)加載到回測系統(tǒng)贝或,添加交易策略, broker設(shè)置(如交易資金和交易傭金)锐秦,頭寸規(guī)模設(shè)置作為策略一部分的交易規(guī)模等咪奖,最后顯示執(zhí)行交易策略時積累的總資金和凈收益。?
#?初始化cerebro回測系統(tǒng)設(shè)置???????????????????????????
cerebro?=?bt.Cerebro()
#將數(shù)據(jù)傳入回測系統(tǒng)
cerebro.adddata(data)
#?將交易策略加載到回測系統(tǒng)中
cerebro.addstrategy(my_strategy1)
#?設(shè)置初始資本為10,000
startcash?=10000
cerebro.broker.setcash(startcash)
#?設(shè)置交易手續(xù)費(fèi)為?0.2%
cerebro.broker.setcommission(commission=0.002)
04 執(zhí)行回測
輸出回測結(jié)果酱床。
print(f'凈收益:{round(pnl,2)}')
d1=start.strftime('%Y%m%d')
d2=end.strftime('%Y%m%d')
print(f'初始資金:{startcash}\n回測期間:{d1}:{d2}')
#運(yùn)行回測系統(tǒng)
cerebro.run()
#獲取回測結(jié)束后的總資金
portvalue?=?cerebro.broker.getvalue()
pnl?=?portvalue?-?startcash
#打印結(jié)果
print(f'總資金:{round(portvalue,2)}')
結(jié)果如下:
初始資金:?10000
回測期間:20100331:20200331
總資金:?12065.36
凈收益:?2065.36
05 可視化
對上述結(jié)果進(jìn)行可視化羊赵,使用內(nèi)置的matplotlib畫圖。至此扇谣,簡單的單均線回測就完成了昧捷。下面圖形展示了浦發(fā)銀行在回測期間的價格走勢、買賣點和交易總資金的變化等罐寨。當(dāng)然靡挥,本文著重以最簡化的例子展示backtrader的框架和運(yùn)行過程,要想更詳細(xì)的展示回測過程和結(jié)果衩茸,還需要加入其他函數(shù)和模塊芹血,關(guān)于Analyzers分析模塊的應(yīng)用請留意下一篇推文。
%matplotlib?inline?#在jupyter notebook上運(yùn)行
cerebro.plot(style='candlestick')
4 結(jié)語
backtrader是目前功能最完善的Python量化回測框架之一(單機(jī)版)楞慈,得到歐洲很多銀行幔烛、基金等金融機(jī)構(gòu)的青睞,并應(yīng)用于實盤交易中囊蓝。作為入門序列之一饿悬,本文簡單介紹了backtrader框架的各個組成部分,然后以20日單均線策略為例聚霜,展示了回測系統(tǒng)的編程和運(yùn)行狡恬。公眾號接下來將以專題的形式為大家全面介紹backtrader的應(yīng)用。學(xué)習(xí)沒有捷徑蝎宇,要想全面而深入地學(xué)習(xí)backtrader回測框架弟劲,最好的方法是研讀其官方文檔。
參考資料:
backtrader官方文檔:
https://www.backtrader.com/docu/
關(guān)于Python金融量化
專注于分享Python在金融量化領(lǐng)域的應(yīng)用姥芥。加入知識星球兔乞,可以免費(fèi)獲取量化投資視頻資料、量化金融相關(guān)PDF資料凉唐、公眾號文章Python完整源碼庸追、量化投資前沿分析框架,與博主直接交流台囱、結(jié)識圈內(nèi)朋友等淡溯。