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

Discussão em 'Python' iniciado por Stack, Fevereiro 24, 2025.

  1. Stack

    Stack Membro Participativo

    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

    Continue reading...

Compartilhe esta Página