when running backtest and buying I always get Order Canceled/Margin/Rejected

1.8k views Asked by At

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
1

There are 1 answers

1
kevtae On

the stake is 10, so at 2020-09-29, your buying 10840 * 10 = 108400. Which larger than capital you allocated = 100,000