For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
2019-10-02: The community is currently in read-only mode

bt.observers.Broker returning negative values.



  • Hi all,

    bt.observers.Broker is returning negative values. Here is the relevant code:

            cerebro   = backtrader.Cerebro()
            cerebro.addobserver(backtrader.observers.Broker)
            # Add a strategy
            cerebro.addstrategy(StrategyBaseTrading)
            data      = PandasDataStrat1(dataname     = dataframe, 
                                         datetime     = -1, 
                                         open         = -1, 
                                         high         = -1, 
                                         low          = -1, 
                                         close        = -1,
                                         volume       = -1,
                                         openinterest = None)
            cerebro.adddata(data)
            cerebro.broker\
                   .setcash(10000.0)
            cerebro.broker\
                   .setcommission(commission = 2.0 
                                  margin     = 500.0, 
                                  mult       = 1000.0)
                                
            return cerebro.run()
    

    then, I find that values of:

    results[0].observers[0].value.get(size = dataframe.shape[0])

    are negative (at the end of the series)

    My questions are:

    • what does this mean? Do I read this correctly to mean that if I liquidate my positions at that point, I owe my broker money?
    • is there a way to force the broker to act tougher? (liquidate the position if the value is < margin_reqs_per_contract * num_contract).

    Lemme know if I can help by providing more code/details the full example (I did not want to cluter the question as I suspect my misunderstanding of the docs is the likely culprit).


  • administrators

    @kav said in bt.observers.Broker returning negative values.:

    what does this mean? Do I read this correctly to mean that if I liquidate my positions at that point, I owe my broker money?

    Probably. It is only backtesting and you have gone in the minus arena.

    @kav said in bt.observers.Broker returning negative values.:

    is there a way to force the broker to act tougher? (liquidate the position if the value is < margin_reqs_per_contract * num_contract).

    No. It's only a simulation. It would seem obvious you need a better strategy, but you may have your reasons to work with one that goes below 0



  • @backtrader As usual, thanks for your answer.

    I might be wrong on this, but it seems to me that backtrader (the library) is more flexible. It seems to me that a simple block like this in the backtrader.Strategy class could help toughening up the broker:

    def next(self):
            contract    = self.datas[0]
            current_position = self.getposition(contract).size
             
            min_nav    = self.broker.getvalue() -\
                                         ((self.datas[0].close[0] - self.datas[0].high[0])\
                                           if current_position < 0 else\
                                         (self.datas[0].close[0] - self.datas[0].low[0])) *\
                                         self.datas[0].multiplier[0] * current_position
            margin_req = abs(current_position) * self.datas[0].MARGIN[0]
            
            if min_nav <= margin_req:
                if self.order:
                    self.cancel(self.order)                
                if current_position < 0:
                    self.order = self.buy(exectype = backtrader.Order.Limit,
                                                        data     = contract, 
                                                        price    = self.datas[0].high[0],
                                                      size     = abs(current_position))
                else:
                    self.order = self.sell(exectype = backtrader.Order.Limit,
                                                       data     = contract, 
                                                       price    = self.datas[0].low[0],
                                                      size     = current_position)
        else:   
            #normal trading logic
    

    Is this foolish?


  • administrators

    @kav said in bt.observers.Broker returning negative values.:

                         if self.order:
                            self.cancel(self.order) 
    

    To start with, that order could actually be one that would closing part of your position and could help alleviate things.

    @kav said in bt.observers.Broker returning negative values.:

                if current_position < 0:
                    self.order = self.buy(exectype = backtrader.Order.Limit,
                                                        data     = contract, 
                                                        price    = self.datas[0].high,
                                                      size     = abs(current_position))
                else:
                    self.order = self.sell(exectype = backtrader.Order.Limit,
                                                       data     = contract, 
                                                       price    = self.datas[0].low,
                                                      size     = current_position)
    

    Real-life brokers close as much as needed from your position and not the entire lot. Some do it in one go and others do i on a 1 contract at at time basis.

    But one thing is for sure: brokers use Market orders when closing positions and not Limit orders.

    In both scenarios (if you want to close the full position) you may want to use the close method.


Log in to reply
 

});