Clear stale orders on bankruptcy - #1392
Open
OllyNewport wants to merge 2 commits into
Open
Conversation
…ints; clean up Order.__repr__ Addresses three remaining items from kernc#1318: - kernc#6: `_Broker.next()` now clears `self.orders` when equity drops to <=0. Trades were already force-closed on bankruptcy, but any still-pending, unfilled order (e.g. a limit order that never triggered) was left dangling in `Strategy.orders`/`_Broker.orders`, even though it can never execute once the simulation has stopped. - kernc#18: Added missing return-type (and a couple of parameter-type) annotations across `Order` and `Trade` properties/methods, and tightened `Backtest.optimize`'s `method` parameter to `Literal['grid', 'sambo']`. `Trade.sl`/`Trade.tp` setters were typed `float` but the docstring always allowed `None` to cancel the order, so retyped to `Optional[float]`. Annotating the `sl`/`tp` getters as `-> Optional[float]` surfaced a real mypy ambiguity in `self.__sl_order and self.__sl_order.stop` (mypy can't prove `Order` is always truthy); rewrote as an equivalent ternary with no behavior change. - kernc#19: `Order.__repr__` always printed `contingent=...` even when `is_contingent` was `False` (rendered as `contingent=0`, since `round(False, 5) == 0`). Falsy `contingent` is now omitted like any other unset field, while a genuinely contingent order still shows it. Verified against CONTRIBUTING.md: flake8 clean; mypy shows the same 9 pre-existing, unrelated errors as master (in _stats.py, _plotting.py, lib.py) with zero new errors; full suite (python -m backtesting.test) passes, 83 tests, 1 unrelated skip. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses three remaining items from #1318 (following #1389 and the earlier docs PR for #5/#17/#20).
#6 — Bankruptcy leaves stale orders
_Broker.next()already force-closes every openTradewhen equity drops to<= 0(which also cleans up their SL/TP orders), but any still-pending, unfilled order
(e.g. a limit order that never triggered) was left dangling in
Strategy.orders/_Broker.orders, even though the simulation has stopped and it can never execute.self.orders.clear()is now called alongside the rest of the bankruptcy cleanup.Covered by a new regression test that drives an over-leveraged position into a 99%
crash and asserts
stats._strategy.orders == ()afterward.#18 — Type hints polish (Trade, Order, Backtest.optimize)
Filled in missing return-type (and a couple of parameter-type) annotations across
Order's andTrade's properties/methods, and tightenedBacktest.optimize'smethodparameter toLiteral['grid', 'sambo'].Trade.sl/Trade.tpsetters were typedfloatbut the docstring always allowedNoneto cancel the order — retyped toOptional[float].sl/tpgetters as-> Optional[float]surfaced a real mypyambiguity in
self.__sl_order and self.__sl_order.stop(mypy can't proveOrderis always truthy). Rewrote both as an equivalent ternary — no behavior change,
just type-checker-friendly.
No logic changes elsewhere.
#19 —
Order.__repr__verbosityOrder.__repr__always printedcontingent=...even whenis_contingentwasFalse— and rendered it ascontingent=0rather thancontingent=False, becauseround(False, 5) == 0. Falsycontingentis now omitted like any other unsetfield, while a genuinely contingent order still shows it (e.g.
<Order size=-1.0, stop=90.0, contingent=1>).Covered by a new test asserting
'contingent'is absent from a plain order's reprand present on a contingent SL order's repr.
Testing
python -m backtesting.test— 83 passed, 1 skipped (unrelated)flake8 backtesting— cleanmypy backtesting— same 9 pre-existing errors asmaster(all in unrelatedfiles:
_stats.py,_plotting.py,lib.py); zero new errors, two errors inTradeactually fixed as a side effect of thesl/tprewrite above🤖 Generated with Claude Code