一、双均线策略介绍
- 买入:MA5 上穿 MA20
- 卖出:MA5 下穿 MA20
- 回测对象:上证指数
- 起始时间:2020.1.1
- 截止时间:2022.11.25
- 佣金:双边各 0.03%
- 滑点:双边各 0.01%
二、数据获取代码
import akshare as ak
sh_index = ak.stock_zh_index_daily(symbol="sh000001")
sh_index['openinterest'] = 0
sh_index.index = pd.to_datetime(sh_index.date)
sh_index = sh_index[['open', 'high', 'low', 'close', 'volume', 'openinterest']]

三、策略完整代码
import pandas as pd
import backtrader as bt
import akshare as ak
class DoubleMA_Strategy(bt.Strategy):
params = (
("sma5",5),
("sma20",20)
)
def log(self, txt, dt=None):
dt = dt or self.data.datetime.date(0)
print("%s, %s, "%(dt, txt))
def __init__(self):
self.order = None
self.sma5 = bt.ind.MovingAverageSimple(self.data.close,period=self.params.sma5)
self.sma20 = bt.ind.MovingAverageSimple(self.data.close,period=self.params.sma20)
def notify_order(self,order):
if order.status in [order.Submitted, order.Accepted]:
return
if order.status in [order.Completed]:
if order.isbuy():
self.log(
'买入,价格: %.2f, 成本: %.2f, 佣金 %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm)
)
else:
self.log(
'卖出,价格: %.2f, 成本: %.2f, 佣金 %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm)
)
elif order.status in [order.Cancled, order.Margin, order.Rejected]:
self.log("Order Canceled(取消)/Margin()/Rejected(拒绝)")
self.order = None
def notify_trade(self, trade):
if not trade.isclosed:
return
self.log('盈利: %.2f, 手续费: %.2f\n' %
(trade.pnl, trade.pnlcomm))
def next(self):
if self.sma5[0] > self.sma20[0] and self.sma5[-1] < self.sma20[-1]:
if self.order:
return
self.order = self.buy()
elif self.sma5[0] < self.sma20[0] and self.sma5[-1] > self.sma20[-1]:
self.order = self.sell()
if __name__ == "__main__":
sh_index = ak.stock_zh_index_daily(symbol="sh000001")
sh_index['openinterest'] = 0
sh_index.index = pd.to_datetime(sh_index.date)
sh_index = sh_index[['open', 'high', 'low', 'close', 'volume', 'openinterest']]
data = bt.feeds.PandasData(
dataname=sh_index,
fromdate=pd.to_datetime("2020-01-01"),
todate=pd.to_datetime("2022-11-25")
)
cerebro = bt.Cerebro()
cerebro.addstrategy(DoubleMA_Strategy)
cerebro.adddata(data, name="SH")
cerebro.broker.setcash(1000000.0)
cerebro.broker.setcommission(commission=0.0003)
cerebro.broker.set_slippage_perc(perc=0.0001)
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.run()
print('Ending Portfolio Value: %.2f' % cerebro.broker.getvalue())
cerebro.plot(style='candlestick',volume=False)
