Multiple Data Feeds (Instruments) on a single strategy
-
Hi All
I am new to Back trader and I am in need of your help to test my strategy on multiple instrument data.
I have pasted the code below, I am expecting the strategy to run for both the data feeds, but actually its running for only one data feed. Please let me know what I should be changing to make it run for both the instrument data feeds. Thanks in advance-- Satheesh Kumar
from future import (absolute_import, division, print_function,
unicode_literals)import argparse
import backtrader as bt
import backtrader.feeds as btfeeds
import datetime as dt
import pandas as pclass TestStrategy(bt.Strategy):
params = (
('smaPeriod', 10),
)def __init__(self): #Retrieves Close price data from the object self.dataclose = self.data.close #To keep track of pending orders and buy price / commission. self.order = None self.buyprice = None self.commission = None #SMA Indicator self.sma = bt.indicators.MovingAverageSimple(self.data, period=self.params.smaPeriod) # Indicators for the plotting show bt.indicators.ExponentialMovingAverage(self.data, period=25) bt.indicators.WeightedMovingAverage(self.data, period=25).subplot = True bt.indicators.StochasticSlow(self.data) bt.indicators.MACDHisto(self.data) rsi = bt.indicators.RSI(self.data) bt.indicators.SmoothedMovingAverage(rsi, period=10) bt.indicators.ATR(self.data).plot = False def notify_order(self, order): #Check whether an order is Submitted or Accepted by the Broker if order.status in [order.Submitted, order.Accepted]: return #Check if an order is completed if order.status in [order.Completed]: if order.isbuy(): print('Buy Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % (order.executed.price, order.executed.value, order.executed.comm )) self.buyprice = order.executed.price self.commission = order.executed.comm elif order.issell(): print('Sell Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % (order.executed.price, order.executed.value, #for sell this is not working as expected order.executed.comm )) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: print('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return print('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): print('Date, %s, Close, %.2f' % (self.data.datetime.date(0), self.dataclose[0])) #Check if an order is in Pending state, if yes, we cannot send a 2nd one if self.order: print('An order already in Pending state') return #Check whether we have an open position already, if no, then we can enter a new position by entering a BUY trade if not self.position: if self.dataclose[0] > self.sma[0]: print('BUY Signal:, %.2f' % self.dataclose[0]) self.order = self.buy() #if there is an existing position already, then we have to close it after 5 consecutive bars else: if self.dataclose[0] < self.sma[0]: print('Sell Signal:, %.2f' % self.dataclose[0]) self.order = self.sell()
if name == 'main':
cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) #Adds the strategy orcl = p.read_csv('D:\Algoticks\Excercises\Data\orcl_price-history-05-21-2018.csv') orcl['datetime'] = orcl['datetime'].astype('datetime64[ns]') orcl_stg = bt.feeds.PandasData(dataname = orcl) hcl = p.read_csv('D:\Algoticks\Excercises\Data\hcl_price-history-05-21-2018.csv') hcl['datetime'] = hcl['datetime'].astype('datetime64[ns]') hcl_stg = bt.feeds.PandasData(dataname = hcl) cerebro.adddata(orcl_stg) #Adds the data for the strategy cerebro.adddata(hcl_stg) #set the cash cerebro.broker.setcash(100000.0) #set broker commission cerebro.broker.setcommission(commission = 0.001) #.1 percentage #set the quantity cerebro.addsizer(bt.sizers.FixedSize, stake = 10) #cerebro.addwriter(bt.WriterFile, csv=True) print('Starting Portfolio Value : %.2f' % cerebro.broker.getvalue()) cerebro.run() #data.head() print('Final Portfolio Value : %.2f' % cerebro.broker.getvalue())
-
Hi All
Please ignore the previous code and please look at this code block. Sorry for the mistake
from future import (absolute_import, division, print_function,
unicode_literals)import argparse
import backtrader as bt
import backtrader.feeds as btfeeds
import datetime as dtimport pandas as p
class TestStrategy(bt.Strategy):
params = (
('smaPeriod', 10),
)def __init__(self): #Retrieves Close price data from the object #self.dataclose = self.data.close #To keep track of pending orders and buy price / commission. self.order = None self.buyprice = None self.commission = None def notify_order(self, order): #Check whether an order is Submitted or Accepted by the Broker if order.status in [order.Submitted, order.Accepted]: return #Check if an order is completed if order.status in [order.Completed]: if order.isbuy(): print('Buy Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % (order.executed.price, order.executed.value, order.executed.comm )) self.buyprice = order.executed.price self.commission = order.executed.comm elif order.issell(): print('Sell Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % (order.executed.price, order.executed.value, #for sell this is not working as expected order.executed.comm )) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: print('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return print('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): for datafeed in self.getdatanames(): print('Date, %s, Close, %.2f' % (self.getdatabyname(datafeed).datetime.date(0), self.getdatabyname(datafeed).close[0])) #Check if an order is in Pending state, if yes, we cannot send a 2nd one if self.order: print('An order already in Pending state') return #Check whether we have an open position already, if no, then we can enter a new position by entering a BUY trade if not self.position: if self.getdatabyname(datafeed).close[0] < self.getdatabyname(datafeed).close[-1]: if self.getdatabyname(datafeed).close[-1] < self.getdatabyname(datafeed).close[-2]: print('BUY Signal:, %.2f' % self.getdatabyname(datafeed).close[0]) self.order = self.buy() elif self.position: if len(self) >= (self.bar_executed + 4): print('Sell Signal:, %.2f' % self.getdatabyname(datafeed).close[0]) self.order = self.sell()
if name == 'main':
cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) #Adds the strategy orcl = p.read_csv('D:\Algoticks\Excercises\Data\orcl_price-history-05-21-2018.csv') orcl['datetime'] = orcl['datetime'].astype('datetime64[ns]') orcl_stg = bt.feeds.PandasData(dataname = orcl) hcl = p.read_csv('D:\Algoticks\Excercises\Data\hcl_price-history-05-21-2018.csv') hcl['datetime'] = hcl['datetime'].astype('datetime64[ns]') hcl_stg = bt.feeds.PandasData(dataname = hcl) cerebro.adddata(orcl_stg) #Adds the data for the strategy cerebro.adddata(hcl_stg) #set the cash cerebro.broker.setcash(100000.0) #set broker commission cerebro.broker.setcommission(commission = 0.001) #.1 percentage #set the quantity cerebro.addsizer(bt.sizers.FixedSize, stake = 10) #cerebro.addwriter(bt.WriterFile, csv=True) print('Starting Portfolio Value : %.2f' % cerebro.broker.getvalue()) cerebro.run() #data.head() print('Final Portfolio Value : %.2f' % cerebro.broker.getvalue())
-
@satheesh7134 Go through the multi data feeds example.
You need to use enumerate(self.datas) to evaluate strategy on each data feed separately.
-
@divyanshu-bagga :
In that case, wouldn't cerebro.run( ) execute twice? If I run twice then I would get two different datasets.What if, I want to execute this strategy on both data sets and generate single report as one single portfolio.
-
@satheesh7134 said in Multiple Data Feeds (Instruments) on a single strategy:
print('BUY Signal:, %.2f' % self.getdatabyname(datafeed).close[0]) self.order = self.buy()
He wasn't telling the system what to buy (or sell). See Docs - Strategy and the reference for
buy
/sell
or as pointed out by @Divyanshu-Bagga
@divyanshu-bagga said in Multiple Data Feeds (Instruments) on a single strategy:
@satheesh7134 Go through the multi data feeds example.
@param-jeet said in Multiple Data Feeds (Instruments) on a single strategy:
In that case, wouldn't cerebro.run( ) execute twice? If I run twice then I would get two different datasets.
What if, I want to execute this strategy on both data sets and generate single report as one single portfolio.You enumerate within the strategy.