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()