Skip to content

New Sell order followed by Stop Loss - double _close_position bug #28

Closed
@Voyz

Description

@Voyz

It's a rare situation - you need both stop loss and new order to happen in the same time step - but when happens it is such a pain to nail down what's really wrong, since the framework won't break. Instead, all the data following will be slightly wrong. Started debugging this when trying to understand why ohlc_trades plot would draw two trades going on at the same time, if clearly existing positions need to be closed before opening new ones. That "double trade" plotting is result of that misaligned data due to the erroneous open position and instant stop loss.

image

Expected Behavior

Close the original position, ignore the stop loss and create a new order

Actual Behavior

Close the original position, create a new order, and instantly close it due to stop loss

Steps to Reproduce

  1. Create a strategy that will produce a new sell order the same time step in which a stop loss threshold is reached.

Additional info

A couple of fix suggestions:

  1. Update open, high, low once self._open_position(entry, is_long) is called (backtesting.py line 539)

backtesting.py line 532

if entry or orders._close:
    self._close_position()
    orders._close = False

################ THIS
# First make the entry order, if hit
if entry:
    if entry is _MARKET_PRICE or high > orders._entry > low:
        self._open_position(entry, is_long)
################ THIS

# Check if stop-loss threshold was hit
if sl and self._position:
    price = (sl if low <= sl <= high else              # hit
             open if (is_long and open < sl or         # gapped hit
                      not is_long and open > sl) else
             None)                                     # not hit
    if price is not None:
        self._close_position(price)
        self.orders.cancel()

# Check if take-profit threshold was hit
if tp and self._position:
    price = (tp if low < tp < high else
             open if (is_long and open > tp or
                      not is_long and open > sl) else
             None)
    if price is not None:
        self._close_position(price)
        self.orders.cancel()
   
###########################################
#### SHOULD PROBABLY BE MOVED HERE #######
###########################################

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions