Skip to content

Commit 4aee89a

Browse files
committed
BUG: Fix "stop-loss executed at a higher than market price"
Fixes #521 Thanks!
1 parent b21b4b6 commit 4aee89a

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

backtesting/backtesting.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,6 @@ def next(self):
816816
def _process_orders(self):
817817
data = self._data
818818
open, high, low = data.Open[-1], data.High[-1], data.Low[-1]
819-
prev_close = data.Close[-2]
820819
reprocess_orders = False
821820

822821
# Process orders
@@ -856,7 +855,9 @@ def _process_orders(self):
856855
max(stop_price or open, order.limit))
857856
else:
858857
# Market-if-touched / market order
859-
price = prev_close if self._trade_on_close else open
858+
# Contingent orders always on next open
859+
prev_close = data.Close[-2]
860+
price = prev_close if self._trade_on_close and not order.is_contingent else open
860861
price = (max(price, stop_price or -np.inf)
861862
if order.is_long else
862863
min(price, stop_price or np.inf))

backtesting/test/_test.py

+19
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,25 @@ def test_readme_contains_stats_keys(self):
964964
self.assertIn(key, readme)
965965

966966

967+
class TestRegressions(TestCase):
968+
def test_gh_521(self):
969+
class S(Strategy):
970+
def init(self): pass
971+
972+
def next(self):
973+
if self.data.Close[-1] == 100:
974+
self.buy(size=1, sl=90)
975+
976+
df = pd.DataFrame({
977+
'Open': [100, 100, 100, 50, 50],
978+
'High': [100, 100, 100, 50, 50],
979+
'Low': [100, 100, 100, 50, 50],
980+
'Close': [100, 100, 100, 50, 50],
981+
})
982+
bt = Backtest(df, S, cash=100, trade_on_close=True)
983+
self.assertEqual(bt.run()._trades['ExitPrice'][0], 50)
984+
985+
967986
if __name__ == '__main__':
968987
warnings.filterwarnings('error')
969988
unittest.main()

0 commit comments

Comments
 (0)