Backtrader: Multiple Data Feeds & Indicators
Multi Example
import backtrader as bt
from datetime import datetime
class BOLLStrat(bt.Strategy):
'''
This is a simple mean reversion bollinger band strategy.
Entry Critria:
- Long: Price crossing/close below the upper band
- Short: Price crossing/close above the lower band
Exit Critria
- Long/Short: Price touching the median line
'''
params = (
("period", 20),
("devfactor", 2),
("size", 20),
("debug", False)
)
def __init__(self):
self.boll = bt.indicators.BollingerBands(period=self.p.period, devfactor=self.p.devfactor)
#self.sx = bt.indicators.CrossDown(self.data.close, self.boll.lines.top)
#self.lx = bt.indicators.CrossUp(self.data.close, self.boll.lines.bot)
def next(self):
orders = self.broker.get_orders_open()
# Cancel open orders so we can track the median line
if orders:
for order in orders:
self.broker.cancel(order)
if not self.position:
#if True:
if self.data.close > self.boll.lines.top:
self.sell(exectype=bt.Order.Stop, price=self.boll.lines.top[0], size=self.p.size)
if self.data.close < self.boll.lines.bot:
self.buy(exectype=bt.Order.Stop, price=self.boll.lines.bot[0], size=self.p.size)
else:
if self.position.size > 0:
self.sell(exectype=bt.Order.Limit, price=self.boll.lines.mid[0], size=self.p.size)
#self.sell(exectype=bt.Order.Limit, price=self.boll.lines.top[0], size=self.p.size)
else:
self.buy(exectype=bt.Order.Limit, price=self.boll.lines.mid[0], size=self.p.size)
#self.buy(exectype=bt.Order.Stop, price=self.boll.lines.bot[0], size=self.p.size)
if self.p.debug:
print('---------------------------- NEXT ----------------------------------')
print("1: Data Name: {}".format(data._name))
print("2: Bar Num: {}".format(len(data)))
print("3: Current date: {}".format(data.datetime.datetime()))
print('4: Open: {}'.format(data.open[0]))
print('5: High: {}'.format(data.high[0]))
print('6: Low: {}'.format(data.low[0]))
print('7: Close: {}'.format(data.close[0]))
print('8: Volume: {}'.format(data.volume[0]))
print('9: Position Size: {}'.format(self.position.size))
print('--------------------------------------------------------------------')
def notify_trade(self,trade):
if trade.isclosed:
dt = self.data.datetime.date()
print('---------------------------- TRADE ---------------------------------')
print("1: Data Name: {}".format(trade.data._name))
print("2: Bar Num: {}".format(len(trade.data)))
print("3: Current date: {}".format(dt))
print('4: Status: Trade Complete')
print('5: Ref: {}'.format(trade.ref))
print('6: PnL: {}'.format(round(trade.pnl,2)))
print('--------------------------------------------------------------------')
class OandaCSVData(bt.feeds.GenericCSVData):
params = (
('nullvalue', float('NaN')),
#('dtformat', '%Y-%m-%dT%H:%M:%S.%fZ'),
('dtformat', '%Y-%m-%d'),
('datetime', 1),
('time', -1),
('open', 2),
('high', 3),
('low', 4),
('close', 5),
('volume', 6),
('openinterest', 7),
)
#Variable for our starting cash
startcash = 100000
#Create an instance of cerebro
cerebro = bt.Cerebro()
#Add our strategy
cerebro.addstrategy(BOLLStrat)
#cerebro.addstrategy(BOLLStrat, oneplot=False)
#create our data list
datalist = [
('data.csv', 'BTCUSDT'), #[0] = Data file, [1] = Data name
]
#Loop through the list adding to cerebro.
for i in range(len(datalist)):
data = OandaCSVData(dataname=datalist[i][0])
cerebro.adddata(data, name=datalist[i][1])
# Set our desired cash start
cerebro.broker.setcash(startcash)
# Run over everything
cerebro.run()
#Get final portfolio Value
portvalue = cerebro.broker.getvalue()
pnl = portvalue - startcash
#Print out the final result
print('Final Portfolio Value: ${}'.format(portvalue))
print('P/L: ${}'.format(pnl))
#Finally plot the end results
cerebro.plot(style='candlestick')
Multi Example
import backtrader as bt
from datetime import datetime
class BOLLStrat(bt.Strategy):
'''
This is a simple mean reversion bollinger band strategy.
Entry Critria:
- Long: Price crossing/close below the upper band
- Short: Price crossing/close above the lower band
Exit Critria
- Long/Short: Price touching the median line
'''
params = (
("period", 20),
("devfactor", 2),
("size", 20),
("debug", False)
)
def __init__(self):
self.boll = bt.indicators.BollingerBands(period=self.p.period, devfactor=self.p.devfactor)
#self.sx = bt.indicators.CrossDown(self.data.close, self.boll.lines.top)
#self.lx = bt.indicators.CrossUp(self.data.close, self.boll.lines.bot)
def next(self):
orders = self.broker.get_orders_open()
# Cancel open orders so we can track the median line
if orders:
for order in orders:
self.broker.cancel(order)
if not self.position:
#if True:
if self.data.close > self.boll.lines.top:
self.sell(exectype=bt.Order.Stop, price=self.boll.lines.top[0], size=self.p.size)
if self.data.close < self.boll.lines.bot:
self.buy(exectype=bt.Order.Stop, price=self.boll.lines.bot[0], size=self.p.size)
else:
if self.position.size > 0:
self.sell(exectype=bt.Order.Limit, price=self.boll.lines.mid[0], size=self.p.size)
#self.sell(exectype=bt.Order.Limit, price=self.boll.lines.top[0], size=self.p.size)
else:
self.buy(exectype=bt.Order.Limit, price=self.boll.lines.mid[0], size=self.p.size)
#self.buy(exectype=bt.Order.Stop, price=self.boll.lines.bot[0], size=self.p.size)
if self.p.debug:
print('---------------------------- NEXT ----------------------------------')
print("1: Data Name: {}".format(data._name))
print("2: Bar Num: {}".format(len(data)))
print("3: Current date: {}".format(data.datetime.datetime()))
print('4: Open: {}'.format(data.open[0]))
print('5: High: {}'.format(data.high[0]))
print('6: Low: {}'.format(data.low[0]))
print('7: Close: {}'.format(data.close[0]))
print('8: Volume: {}'.format(data.volume[0]))
print('9: Position Size: {}'.format(self.position.size))
print('--------------------------------------------------------------------')
def notify_trade(self,trade):
if trade.isclosed:
dt = self.data.datetime.date()
print('---------------------------- TRADE ---------------------------------')
print("1: Data Name: {}".format(trade.data._name))
print("2: Bar Num: {}".format(len(trade.data)))
print("3: Current date: {}".format(dt))
print('4: Status: Trade Complete')
print('5: Ref: {}'.format(trade.ref))
print('6: PnL: {}'.format(round(trade.pnl,2)))
print('--------------------------------------------------------------------')
class OandaCSVData(bt.feeds.GenericCSVData):
params = (
('nullvalue', float('NaN')),
#('dtformat', '%Y-%m-%dT%H:%M:%S.%fZ'),
('dtformat', '%Y-%m-%d'),
('datetime', 1),
('time', -1),
('open', 2),
('high', 3),
('low', 4),
('close', 5),
('volume', 6),
('openinterest', 7),
)
#Variable for our starting cash
startcash = 100000
#Create an instance of cerebro
cerebro = bt.Cerebro()
#Add our strategy
cerebro.addstrategy(BOLLStrat)
#cerebro.addstrategy(BOLLStrat, oneplot=False)
#create our data list
datalist = [
('data.csv', 'BTCUSDT'), #[0] = Data file, [1] = Data name
]
#Loop through the list adding to cerebro.
for i in range(len(datalist)):
data = OandaCSVData(dataname=datalist[i][0])
cerebro.adddata(data, name=datalist[i][1])
# Set our desired cash start
cerebro.broker.setcash(startcash)
# Run over everything
cerebro.run()
#Get final portfolio Value
portvalue = cerebro.broker.getvalue()
pnl = portvalue - startcash
#Print out the final result
print('Final Portfolio Value: ${}'.format(portvalue))
print('P/L: ${}'.format(pnl))
#Finally plot the end results
cerebro.plot(style='candlestick')
Комментариев нет:
Отправить комментарий