Problem fetching execution price
-
Hello everyone,
I'm trying to exit a position if price > executed price + x.
How can I fetch theorder.executed.price
?I tried it with
_orders[data][0]
but it doesn't work:def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): DISTCALC = ((self.ema1[0]-order.executed.price)/order.executed.price*100) self.log('BUY EXECUTED, %.2f' % order.executed.price) self.log('EMA Price, %.2f' % self.ema1[0]) self.log('Price distance to EMA, %.2f' % DISTCALC + str('%')) elif order.issell(): self.log('SELL EXECUTED, %.2f' % order.executed.price) def next(self): if not self.position and self.order==None: if self.distance and self.below800EMA: self.price = self.sma1[0] self.order = self.buy(self.datas[0], exectype=bt.Order.Market, size=1) if self.sma1[0] > self._orders[data][0]+10: self.order = self.close()
The error is:
TypeError: list indices must be integers or slices, not GenericCSVData
-
@stanski
_orders
is designed to be only used internally in Backtrader framework I think.The better way to implement what you want is to probably manage an association (dictionary) between
data
andorder
(assuming only a single active order could ever be created for each data) in your own strategy class. -
@stanski For a non-standard, non-approved and untested answer (well, I use it all the time... )
When you are in notify order that your new order is complete and your position is filled, and preferrably when no one is looking....
Attach an attribute to your data line that is the value of the executed price.
# In notify order and presuming a long only strategy for simplicity. if order.status in [order.Completed]: if order.isbuy(): order.data.enter_price = order.executed.price
Then in your next:
if self.datas[0].close[0] > self.datas[0].enter_price + x: <more code>
-
@run-out I've tried it with the attached attribute, but unfortunately, I get an
AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'enter_price
-
@stanski That's why I should have tested! Missed a couple lines.
We have to initialize the variable on the datas in init. And then use if to check if None in next.
def __init__(self): self.datas[0].enter_price = None ... if self.datas[0].enter_price: print(f"From next: {self.datas[0].enter_price}") Output From next: 3239.5 From next: 3239.5 From next: 3239.5 From next: 3239.5 From next: 3239.5
-
just use self.position.price.
self.positions[data].price if using multiple data sets.
-
@run-out well, whatever I do now with
self.datas[0].enter_price
in terms of multiplication or addition, I get aTypeError: unsupported operand type(s) for *: 'float' and 'NoneType'
I'm considering to discard this idea. This is actually an alternative try-out for a percentage-based take profit, which I couldn't get working in another way.
Maybe I should post the initial code in a new post -
@stanski No worries. It's just a technique I use from time to time when attaching info on datas.
-
@run-out nonetheless, thank you for sharing the idea! I just made a new post with the initial code with my take profit problem
-
in the:
def next(self) ... if self.position: print(self.position.price)
it works for me, also in a parallel environment.