For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Issue with order_target on live trading



  • Hi, Backtraders!

    I have been using the function self.order_target_percent() in backtesting mode and it works perfectly. Now that I'm testing a strategy in paper trading with Interactive Brokers I'm facing an issue. The system always says that my order is "Rejected". I made a simple test to see if it was something related to my strategy, I used self.order_target_percent(target=0.1) but the problem persists. So, I dug in to know how the function makes the estimation and it seems that all is ok with the logic. The only thing I found was something wrong in line 1292 in the strategy.py that use the following value = self.broker.getvalue(datas=[data]). Thie first time that line is executed, value should be 0 as happened when you are in backtesting mode. But that doesn't happen when I switch to live mode with IB. It seems something related of how to retrieve that info from IB.

    Could it be a bug? Or I'm making something wrong? Any clue of how to fix it?

    Thanks again and happy trading!


  • administrators

    The reported account value is the value of the entire account. The target orders didn't exist when IB came into existence, hence the incompatibility. It will be looked into.



  • The get_value() method it supposes to return the portfolio value, not the value of the entire account. But that method doesn't work properly when is connected with IB. I came up with a solution when I'm working with a single instrument. I override the order_target_value in my strategy as follow:

        def order_target_value(self, data=None, target=0.0, price=None, **kwargs):
    
            # if isinstance(data, string_types):
            #     data = self.getdatabyname(data)
            # elif data is None:
            #    data = self.data
    
            data = self.data  # My moddification
    
            possize = self.getposition(data, self.broker).size
    
            if not target and possize:  # closing a position
                return self.close(data=data, size=possize, price=price, **kwargs)
    
            else:
                # value = self.broker.getvalue(datas=[data])
                value = possize * self.datas[0].close  # My modification
                comminfo = self.broker.getcommissioninfo(data)
    
                # Make sure a price is there
                price = price if price is not None else data.close[0]
    
                if target > value:
                    size = comminfo.getsize(price, target - value)
                    return self.buy(data=data, size=size, price=price, **kwargs)
    
                elif target < value:
                    size = comminfo.getsize(price, value - target)
                    return self.sell(data=data, size=size, price=price, **kwargs)
    
            return None  # no execution size == possize
    

    I tested it without IB and got the right result. So, I could expect the same with IB. What do you think about this solution? Is it correct?


  • administrators

    @j-javier-gálvez said in Issue with order_target on live trading:

    The get_value() method it supposes to return the portfolio value, not the value of the entire account

    The convention in backtrader is to return the sum of the value of the assets and the cash, hence the account value



  • But in the documentation doesn't say that and in practice in backtrader doesn' do that either. self.broker.get_value(data) it shouldn't take into account the cash, because it is the portfolio value, not the account value. Otherwise, it would not work in backtesting with the default broker.


  • administrators

    We are talking about the specific case of the interaction of the order_target_xxx and the broker for Interactive Brokers which was developed before those family of calls existed.