For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
Buying based on specific data feed
-
Hi All,
Havn't been here in a while, glad to see the community is still active.
I have 2 data feeds (1-minute and 5-minute data) with 4 unique tickers.
I can't seem to figure out how to buy solely based on the 1-minute data.
Having gone through the docs, it was indicated that I need to do something like "self.buy(data=self.datas[0])", however, when I do this, the script only buys stock for the first ticker.
Any insight is greatly appreciated.
Alfred
import backtrader as bt import datetime from collections import defaultdict #https://community.backtrader.com/topic/2306/easier-way-to-access-active-orders class FixedCommisionScheme(bt.CommInfoBase): ''' This is a simple fixed commission scheme ''' params = ( ('commission', 0.0075), ('stocklike', True), ('commtype', bt.CommInfoBase.COMM_FIXED), ) def _getcommission(self, size, price, pseudoexec): commission = self.p.commission * abs(size) return commission class MyStrategy(bt.Strategy): params = (('sma1', 40),('sma2', 10)) def __init__(self): self.order = {} self.sma1 = {} self.sma2 = {} for i, d in enumerate(self.datas): sma1 = bt.indicators.SimpleMovingAverage(self.datas[i], period=self.params.sma1) sma2 = bt.indicators.SimpleMovingAverage(self.datas[i], period=self.params.sma2) self.sma1[d] = sma1 self.sma2[d] = sma2 def log(self, txt, dt=None): dt = self.datetime.datetime() print(f'{dt.isoformat()} {txt}') def notify_order(self, order): #self.order[order.data._name] = None if order.status in [order.Completed, order.Margin]: if order.isbuy(): self.log(f'-BUY EXECUTED- Price: {order.executed.price:.2f} Comm: {order.executed.comm:.4f}, {order.data._name}') else: self.log(f'-SELL EXECUTED- Price: {order.executed.price:.2f} Comm: {order.executed.comm:.4f}, {order.data._name}') def notify_trade(self, trade): dt = self.data.datetime.datetime() if trade.isclosed: print('{} {} Closed: PnL Gross {}, Net {}'.format( dt, trade.data._name, round(trade.pnl,2), round(trade.pnlcomm,2))) def next(self): for i, d in enumerate(self.datas): pos = self.getposition(d).size if not pos: if d.close > self.sma2[d][0]: self.buy(data=d,size=1) if pos: if d.close < self.sma2[d][0]: self.close(data=d) #Instantiate Cerebro engine cerebro = bt.Cerebro() #Set cash cerebro.broker.setcash(100000.0) #Set commissions comminfo = FixedCommisionScheme() cerebro.broker.addcommissioninfo(comminfo) #Add strategy to Cerebro cerebro.addstrategy(MyStrategy) #Add data feeds symbols = ['AA','MSFT','IBM','AMZN'] for symbol in symbols: #Add data data = bt.feeds.InfluxDB(host='localhost', port='8086', username='root', password='root', database='test_data4', dataname=symbol, timeframe=bt.TimeFrame.Minutes, compression=1, fromdate=datetime.datetime(2021, 12, 1), todate=datetime.datetime(2021, 12, 23), dtformat=("%Y-%m-%d %H:%M:%S"), high='high', low='low', open='open', close='close', volume='volume', ointerest='openinterest') cerebro.adddata(data,name=symbol) #Add data data1 = bt.feeds.InfluxDB(host='localhost', port='8086', username='root', password='root', database='test_data4', dataname=symbol, timeframe=bt.TimeFrame.Minutes, compression=5, fromdate=datetime.datetime(2021, 12, 1), todate=datetime.datetime(2021, 12, 23), #add 1 extra day dtformat=("%Y-%m-%d %H:%M:%S"), high='high', low='low', open='open', close='close', volume='volume', ointerest='openinterest') cerebro.adddata(data1,name=symbol) #Begining portfolio value print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) #Run Cerebro Engine cerebro.run() #Ending portfolio value print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) #And plot it with a single command cerebro.plot()