Skip to content

Commit 3450455

Browse files
committed
Change parameter name, simplify tests
1 parent 20a0371 commit 3450455

File tree

3 files changed

+16
-38
lines changed

3 files changed

+16
-38
lines changed

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ These were the major changes contributing to each release:
55

66
### 0.x.x
77

8-
98
### 0.5.0
109
(2025-01-21)
1110

@@ -157,4 +156,4 @@ These were the major changes contributing to each release:
157156
### 0.1.0
158157
(2019-01-15)
159158

160-
* Initial release
159+
* Initial release

backtesting/backtesting.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ def __init__(self,
10891089
trade_on_close=False,
10901090
hedging=False,
10911091
exclusive_orders=False,
1092-
close_all_at_end=False
1092+
finalize_trades=False,
10931093
):
10941094
"""
10951095
Initialize a backtest. Requires data and a strategy to test.
@@ -1156,11 +1156,13 @@ def __init__(self,
11561156
trade/position, making at most a single trade (long or short) in effect
11571157
at each time.
11581158
1159-
If `close_all_at_end` is `False`, the trade will not be close at end,
1160-
and will not apear in _Stats.
1159+
If `finalize_trades` is `True`, the trades that are still
1160+
[active and ongoing] at the end of the backtest will be closed on
1161+
the last bar and will contribute to the computed backtest statistics.
11611162
11621163
[FIFO]: https://www.investopedia.com/terms/n/nfa-compliance-rule-2-43b.asp
1163-
"""
1164+
[active and ongoing]: https://kernc.github.io/backtesting.py/doc/backtesting/backtesting.html#backtesting.backtesting.Strategy.trades
1165+
""" # noqa: E501
11641166

11651167
if not (isinstance(strategy, type) and issubclass(strategy, Strategy)):
11661168
raise TypeError('`strategy` must be a Strategy sub-type')
@@ -1213,7 +1215,7 @@ def __init__(self,
12131215
warnings.warn('Data index is not datetime. Assuming simple periods, '
12141216
'but `pd.DateTimeIndex` is advised.',
12151217
stacklevel=2)
1216-
self._close_all_at_end = bool(close_all_at_end)
1218+
12171219
self._data: pd.DataFrame = data
12181220
self._broker = partial(
12191221
_Broker, cash=cash, spread=spread, commission=commission, margin=margin,
@@ -1222,6 +1224,7 @@ def __init__(self,
12221224
)
12231225
self._strategy = strategy
12241226
self._results: Optional[pd.Series] = None
1227+
self._finalize_trades = bool(finalize_trades)
12251228

12261229
def run(self, **kwargs) -> pd.Series:
12271230
"""
@@ -1308,13 +1311,13 @@ def run(self, **kwargs) -> pd.Series:
13081311
# Next tick, a moment before bar close
13091312
strategy.next()
13101313
else:
1311-
if self._close_all_at_end is True:
1314+
if self._finalize_trades is True:
13121315
# Close any remaining open trades so they produce some stats
13131316
for trade in broker.trades:
13141317
trade.close()
13151318

1316-
# Re-run broker one last time to handle orders placed in the last strategy
1317-
# iteration. Use the same OHLC values as in the last broker iteration.
1319+
# HACK: Re-run broker one last time to handle close orders placed in the last
1320+
# strategy iteration. Use the same OHLC values as in the last broker iteration.
13181321
if start < len(self._data):
13191322
try_(broker.next, exception=_OutOfMoneyError)
13201323

backtesting/test/_test.py

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ def test_compute_drawdown(self):
282282
np.testing.assert_array_equal(peaks, pd.Series([7, 4], index=[3, 5]).reindex(dd.index))
283283

284284
def test_compute_stats(self):
285-
stats = Backtest(GOOG, SmaCross, close_all_at_end=True).run()
285+
stats = Backtest(GOOG, SmaCross, finalize_trades=True).run()
286286
expected = pd.Series({
287287
# NOTE: These values are also used on the website!
288288
'# Trades': 66,
@@ -438,32 +438,8 @@ def next(self):
438438
elif len(self.data) == len(SHORT_DATA):
439439
self.position.close()
440440

441-
self.assertTrue(Backtest(SHORT_DATA, S).run()._trades.empty)
442-
443-
def test_dont_close_orders_from_last_strategy_iteration(self):
444-
class S(Strategy):
445-
def init(self): pass
446-
447-
def next(self):
448-
if not self.position:
449-
self.buy()
450-
elif len(self.data) == len(SHORT_DATA):
451-
self.position.close()
452-
self.assertEqual(len(
453-
Backtest(SHORT_DATA, S, close_all_at_end=False).run()._strategy.closed_trades), 0)
454-
self.assertEqual(len(
455-
Backtest(SHORT_DATA, S, close_all_at_end=False).run()._strategy.trades), 1)
456-
457-
def test_dont_close_orders_trades_from_last_strategy_iteration(self):
458-
class S(Strategy):
459-
def init(self): pass
460-
461-
def next(self):
462-
if not self.position:
463-
self.buy()
464-
465-
self.assertEqual(len(
466-
Backtest(SHORT_DATA, S, close_all_at_end=False).run()._strategy.trades), 1)
441+
self.assertTrue(Backtest(SHORT_DATA, S, finalize_trades=False).run()._trades.empty)
442+
self.assertFalse(Backtest(SHORT_DATA, S, finalize_trades=True).run()._trades.empty)
467443

468444
def test_check_adjusted_price_when_placing_order(self):
469445
class S(Strategy):
@@ -565,7 +541,7 @@ def test_autoclose_trades_on_finish(self):
565541
def coroutine(self):
566542
yield self.buy()
567543

568-
stats = self._Backtest(coroutine, close_all_at_end=True).run()
544+
stats = self._Backtest(coroutine, finalize_trades=True).run()
569545
self.assertEqual(len(stats._trades), 1)
570546

571547
def test_order_tag(self):

0 commit comments

Comments
 (0)