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 usedself.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 line1292
in thestrategy.py
that use the followingvalue = self.broker.getvalue(datas=[data])
. Thie first time that line is executed,value
should be0
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!
-
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 theorder_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?
-
@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. -
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. -
I have the same problem as reported in the initial post:
in my strategy, I call self.order_target_value(...), when debugging into that function I get to the framework call value = self.broker.getvalue(datas=[data]) , this call returns an invalid value(a very large value, close to the value of the entire portfolio), in my case, it should return 0 since the ticker does not exist in IB portfolio
Can you try and replicate this behavior and fix in case there is a bug?
Thank you