Skip to content

Commit b456400

Browse files
committed
BUG: Fix AssertionError on multiple calls to trade.close()
1 parent 6a0540c commit b456400

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

backtesting/backtesting.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,17 +822,20 @@ def _process_orders(self):
822822
if order.parent_trade:
823823
trade = order.parent_trade
824824
_prev_size = trade.size
825+
# If order.size is "greater" than trade.size, this order is a trade.close()
826+
# order and part of the trade was already closed beforehand
827+
size = copysign(min(abs(_prev_size), abs(order.size)), order.size)
825828
# If this trade isn't already closed (e.g. on multiple `trade.close(.5)` calls)
826829
if trade in self.trades:
827-
self._reduce_trade(trade, price, order.size, time_index)
830+
self._reduce_trade(trade, price, size, time_index)
828831
assert order.size != -_prev_size or trade not in self.trades
829832
if order in (trade._sl_order,
830833
trade._tp_order):
831834
assert order.size == -trade.size
832835
assert order not in self.orders # Removed when trade was closed
833836
else:
834837
# It's a trade.close() order, now done
835-
assert abs(_prev_size) >= abs(order.size) >= 1
838+
assert abs(_prev_size) >= abs(size) >= 1
836839
self.orders.remove(order)
837840
continue
838841

@@ -913,6 +916,7 @@ def _reduce_trade(self, trade: Trade, price: float, size: float, time_index: int
913916
assert abs(trade.size) >= abs(size)
914917

915918
size_left = trade.size + size
919+
assert size_left * trade.size >= 0
916920
if not size_left:
917921
close_trade = trade
918922
else:

backtesting/test/_test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,17 @@ def coroutine(self):
434434

435435
self._Backtest(coroutine, exclusive_orders=True).run()
436436

437+
def test_trade_multiple_close(self):
438+
def coroutine(self):
439+
yield self.buy()
440+
441+
assert self.trades
442+
self.trades[-1].close(1)
443+
self.trades[-1].close(.1)
444+
yield
445+
446+
self._Backtest(coroutine).run()
447+
437448

438449
class TestOptimize(TestCase):
439450
def test_optimize(self):

0 commit comments

Comments
 (0)