获取数据
result = pd.read_csv('11.csv')
df = pd.DataFrame(data=result)
df = df.set_index(['datetime'])
df
策略
class MultiTFStrategy(bt.Strategy):params = (('period', 20),)# states definationEmpty, M15Hold, H1Hold, D1Hold = range(4)States = ['Empty', 'M15Hold', 'H1Hold', 'D1Hold',]def log(self, txt):''' Logging function for this strategy'''dt = self.datas[0].datetime.datetime(0)print('%s, %s' % (dt.isoformat(), txt))def __init__(self):self.ma15m = bt.talib.SMA(self.dnames.hs15m, timeperiod=self.p.period)self.ma1h = bt.talib.SMA(self.dnames.hs1h, timeperiod=self.p.period)self.ma1d = bt.talib.SMA(self.dnames.hs1d, timeperiod=self.p.period)self.c15m = bt.indicators.CrossOver(self.dnames.hs15m, self.ma15m, plot=False)self.c1h = bt.indicators.CrossOver(self.dnames.hs1h, self.ma1h, plot=False)self.c1d = bt.indicators.CrossOver(self.dnames.hs1d, self.ma1d, plot=False)self.bsig15m = self.c15m==1self.bsig1h = self.c1h==1self.bsig1d = self.c1d==1self.sell_signal = self.c1d==-1self.st = self.Emptyself.st_map = {self.Empty : self._empty,self.M15Hold : self._m15hold,self.H1Hold : self._h1hold,self.D1Hold : self._d1hold,}# To keep track of pending ordersself.order = Nonedef notify_order(self, order):if order.status in [order.Submitted, order.Accepted]:# Buy/Sell order submitted/accepted to/by broker - Nothing to doreturn# Check if an order has been completed# Attention: broker could reject order if not enough cashif order.status == order.Completed:if order.isbuy():self.log('BUY EXECUTED, St: %s, Size: %d, Price: %.2f, Cost: %.2f, Comm %.2f' %(self.States[self.st],order.executed.size,order.executed.price,order.executed.value,order.executed.comm,))else: # Sellself.log('SELL EXECUTED, St: %s, Size: %d, Price: %.2f, Cost: %.2f, Comm %.2f' %(self.States[self.st],order.executed.size,order.executed.price,order.executed.value,order.executed.comm))elif order.status in [order.Canceled, order.Margin, order.Rejected]:self.log('Order Canceled/Margin/Rejected')# Write down: no pending orderself.order = Nonedef notify_trade(self, trade):if not trade.isclosed:returnself.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %(trade.pnl, trade.pnlcomm))def next(self):# Check if an order is pending ... if yes, we cannot send a 2nd oneif self.order:return# just call state_map functionself.order = self.st_map[self.st]()# Check if we are in the market and no buy order issuedif self.position and not self.order:# Already in the market ... we might sellif self.sell_signal:self.st = self.Empty# Keep track of the created order to avoid a 2nd orderself.order = self.close()def _empty(self):if self.bsig15m:price = self.data0.close[0]cash = self.broker.get_cash()# 20% of the cashshare = int(math.floor((0.2*cash)/price))# set stateself.st = self.M15Holdreturn self.buy(size=share)def _m15hold(self):if self.bsig1h:price = self.data0.close[0]cash = self.broker.get_cash()# half of the remain cash ( 60% )share = int(math.floor((0.5*cash)/price))# set stateself.st = self.H1Holdreturn self.buy(size=share)def _h1hold(self):if self.bsig1d:price = self.data0.close[0]cash = self.broker.get_cash()# half of the remain cash (80%)share = int(math.floor((0.5*cash)/price))# set stateself.st = self.D1Holdreturn self.buy(size=share)def _d1hold(self):return None
cerebro存入数据
cerebro = bt.Cerebro(oldtrades=True)feed = bt.feeds.PandasData(dataname=df, openinterest=None, compression=15, timeframe=bt.TimeFrame.Minutes)cerebro.adddata(feed, name='hs15m')
cerebro.resampledata(feed, name='hs1h', timeframe=bt.TimeFrame.Minutes, compression=60)
cerebro.resampledata(feed, name='hs1d', timeframe=bt.TimeFrame.Days)cerebro.addstrategy(MultiTFStrategy)# 小场面1万起始资金
cerebro.broker.setcash(10000.0)# 手续费万5
cerebro.broker.setcommission(0.0005)print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())result = cerebro.run()print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
绘图:
cerebro.plot(iplot=False,start=datetime.date(2019, 11, 1),end=datetime.date(2020, 1, 1),style='bar',barup='red',bardown='green',
)