# -*- coding: utf-8 -*-
"""
Created on Tue Aug 4 16:52:23 2020@author: 四屏
"""from datetime import datetime
%matplotlib inline
import backtrader as bt
import matplotlib.pyplot as plt
import akshare as akplt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = Falsestock_hfq_df = ak.stock_zh_a_daily(symbol="sh600000", adjust="hfq") # 利用 AkShare 獲取后復權數據class MyStrategy(bt.Strategy):"""主策略程序"""params = (("maperiod", 20),) # 全局設定交易策略的參數def __init__(self):"""初始化函數"""self.data_close = self.datas[0].close # 指定價格序列# 初始化交易指令、買賣價格和手續費self.order = Noneself.buy_price = Noneself.buy_comm = None# 添加移動均線指標self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)def next(self):""":return::rtype:"""if self.order: # 檢查是否有指令等待執行,return# 檢查是否持倉if not self.position: # 沒有持倉if self.data_close[0] > self.sma[0]: # 執行買入條件判斷:收盤價格上漲突破20日均線self.order = self.buy(size=100) # 執行買入else:if self.data_close[0] < self.sma[0]: # 執行賣出條件判斷:收盤價格跌破20日均線self.order = self.sell(size=100) # 執行賣出cerebro = bt.Cerebro() # 初始化回測系統
start_date = datetime(2000, 1, 1) # 回測開始時間
end_date = datetime(2020, 8, 4) # 回測結束時間
data = bt.feeds.PandasData(dataname=stock_hfq_df, fromdate=start_date, todate=end_date) # 加載數據
cerebro.adddata(data) # 將數據傳入回測系統
cerebro.addstrategy(MyStrategy) # 將交易策略加載到回測系統中
start_cash = 26000
cerebro.broker.setcash(start_cash) # 設置初始資本為 100000
cerebro.broker.setcommission(commission=0.002) # 設置交易手續費為 0.2%
cerebro.run() # 運行回測系統port_value = cerebro.broker.getvalue() # 獲取回測結束后的總資金
pnl = port_value - start_cash # 盈虧統計print(f"初始資金: {start_cash}\n回測期間:{start_date.strftime('%Y%m%d')}:{end_date.strftime('%Y%m%d')}")
print(f"總資金: {round(port_value, 2)}")
print(f"凈收益: {round(pnl, 2)}")cerebro.plot(style='candlestick') # 畫圖