Skip to content

Stop Loss value being erased when reached #1288

@xyffar

Description

@xyffar

Expected behavior

The SLs should be displayed in the trade list (within the result stats) whenever they are set (according to the strategy).

Image

Actual behavior

When I get the list of the trades, some of them are unprovided with the SL. This seems to happen for the trades being closed for reaching the SL.
Image

Additional info, steps to reproduce, full crash traceback, screenshots

I analyzed the source code and the SL values are correctly passed within the strategy.buy() method. I followed the code and the values are actually erased when order._replace(stop_price=None) is called (due to the the stop loss being reached).

# Check if stop condition was hit
stop_price = order.stop
if stop_price:
is_stop_hit = ((high >= stop_price) if order.is_long else (low <= stop_price))
if not is_stop_hit:
continue
# > When the stop price is reached, a stop order becomes a market/limit order.
# https://www.sec.gov/fast-answers/answersstopordhtm.html
order._replace(stop_price=None)

The reason is the stop_price parameter , aka order.stop, having the same id of the order.parent_trade.sl. The "coupling" arises within the __set_contingent method, line 738-739, where we create the stop order by passing the price variable (and its reference), which is the SL of the order. In brief, the contingent stop order has the attribute stop with the same reference of the attribute sl of the parent order. When the former gets None'd, the latter follows it.

def __set_contingent(self, type, price):
assert type in ('sl', 'tp')
assert price is None or 0 < price < np.inf, f'Make sure 0 < price < inf! price: {price}'
attr = f'_{self.__class__.__qualname__}__{type}_order'
order: Order = getattr(self, attr)
if order:
order.cancel()
if price:
kwargs = {'stop': price} if type == 'sl' else {'limit': price}
order = self.__broker.new_order(-self.size, trade=self, tag=self.tag, **kwargs)
setattr(self, attr, order)

As proof, see below where we can see that the two variables point to the same address.
Image

Software versions

  • backtesting 0.6.4
  • pandas 2.2.3
  • numpy 1.26.0
  • bokeh 3.7.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions