I've just started using backtrader.
I've fetched 1min candles data from pandas dataframe.
When running backtrader I get this log message after every buy order: "Order Canceled/Margin/Rejected"
I'm using jupyter notebook
This is my trading strategy:
import backtrader
class TestStrategy(backtrader.Strategy):
def log(self, txt, dt=None):
''' Logging function for this strategy'''
dt = dt or self.datas[0].datetime.date(0)
print('%s, %s' % (dt.isoformat(), txt))
def __init__(self):
# Keep a reference to the "close" line in the data[0] dataseries
self.dataclose = self.datas[0].close
self.order = None
def notify_order(self, order):
# if order.status in [order.Submitted, order.Accepted]:
# return
# if order.status in [order.Completed]:
# if order.isbuy():
# self.log("BUY EXECUTED {}".format(order.executed.price))
# elif order.issell():
# self.log("SELL EXECUTED {}".format(order.executed.price))
# self.bar_executed = len(self)
if order.status in [order.Submitted, order.Accepted]:
# Buy/Sell order submitted/accepted to/by broker - Nothing to do
return
# Check if an order has been completed
# Attention: broker could reject order if not enough cash
if order.status in [order.Completed]:
if order.isbuy():
self.log('BUY EXECUTED, %.2f' % order.executed.price)
elif order.issell():
self.log('SELL EXECUTED, %.2f' % order.executed.price)
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected')
self.order = None
def next(self):
# Simply log the closing price of the series from the reference
self.log('Close, %.2f' % self.dataclose[0])
# print(len(self))
# print(self.order)
# print(self.position)
# print("self.bar_executed: ")
# print(self.bar_executed)
#if in order do nothing
if self.order:
return
#if NOT in order (do buy or sell)
#video tutorial https://www.youtube.com/watch?v=K8buXUxEfMc&ab_channel=PartTimeLarry
if not self.position:
if self.dataclose[0] < self.dataclose[-1]:
self.log('BUY CREATE %.2f' % self.dataclose[0])
self.order = self.buy()
else:
if len(self) >= (self.bar_executed + 2):
#self.log('SELL CREATE %.2f' % self.dataclose[0])
self.log("SELL CREATED {}".format(self.dataclosed[0]))
self.order = self.sell()
this is my main code
import backtrader
class PandasData_Custom(bt.feeds.PandasData):
# params = (
# ('datetime', 0),
# ('open', 1),
# ('high', None),
# ('low', None),
# ('close', 2),
# ('volume', None),
# )
params = (
# Possible values for datetime (must always be present)
# None : datetime is the "index" in the Pandas Dataframe
# -1 : autodetect position or case-wise equal name
# >= 0 : numeric index to the colum in the pandas dataframe
# string : column name (as index) in the pandas dataframe
('datetime', None),
# Possible values below:
# None : column not present
# -1 : autodetect position or case-wise equal name
# >= 0 : numeric index to the colum in the pandas dataframe
# string : column name (as index) in the pandas dataframe
('open', -1),
('high', -1),
('low', -1),
('close', -1),
('volume', -1),
# ('openinterest', -1),
)
feed2 = PandasData_Custom(dataname=bt_feed)
cerebro = backtrader.Cerebro()
cerebro.broker.setcash(1000000)
#for feed data look here https://stackoverflow.com/questions/62301378/backtrader-error-dataframe-object-has-no-attribute-setenvironment
# feed = backtrader.feeds.PandasData(dataname=bt_feed)
# cerebro.adddata(feed)
cerebro.adddata(feed2)
cerebro.addstrategy(TestStrategy)
# cerebro.addsizer(backtrader.sizers.FixedSize, stake = 100)
# cerebro.broker.setcash(10000)
# cerebro.broker.setcommission(0.1/100)
cerebro.broker.setcash(100000.0)
cerebro.addsizer(bt.sizers.FixedSize, stake=10)
cerebro.broker.setcommission(commission=0.001)
# cerebro.broker.setcommission(commission=0.5, margin=0.5, mult=2.0)
print("Starting portfolio value: " + str(cerebro.broker.getvalue()))
cerebro.run()
print("Final portfolio value: " + str(cerebro.broker.getvalue()))
this is my dataframe data
open high low close volume openinterest
datetime
2020-09-10 00:19:00 10309.5 10309.5 10294.5 10300.5 1 1
2020-09-10 00:20:00 10300.5 10308.5 10300.0 10302.5 1 1
2020-09-10 00:21:00 10302.5 10303.0 10302.5 10302.5 1 1
2020-09-10 00:22:00 10302.5 10312.0 10302.5 10311.5 1 1
2020-09-10 00:23:00 10311.5 10312.0 10300.0 10300.0 1 1
... ... ... ... ... ... ...
2020-09-29 23:55:00 10839.5 10839.5 10839.0 10839.5 1 1
2020-09-29 23:56:00 10839.5 10839.5 10839.0 10839.0 1 1
2020-09-29 23:57:00 10839.0 10839.5 10839.0 10839.0 1 1
2020-09-29 23:58:00 10839.0 10839.5 10839.0 10839.0 1 1
2020-09-29 23:59:00 10839.0 10839.5 10839.0 10839.5 1 1
these are the logs, plus the final balance is the same from the start of the test.
2020-09-29, BUY CREATE 10840.00
2020-09-29, Order Canceled/Margin/Rejected
2020-09-29, Close, 10839.00
2020-09-29, BUY CREATE 10839.00
2020-09-29, Order Canceled/Margin/Rejected
2020-09-29, Close, 10839.50
2020-09-29, Close, 10839.50
2020-09-29, Close, 10839.50
2020-09-29, Close, 10839.00
2020-09-29, BUY CREATE 10839.00
2020-09-29, Order Canceled/Margin/Rejected
2020-09-29, Close, 10839.00
2020-09-29, Close, 10839.00
2020-09-29, Close, 10839.50
Final portfolio value: 100000.0
the stake is 10, so at 2020-09-29, your buying 10840 * 10 = 108400. Which larger than capital you allocated = 100,000