Repository navigation
Clarify Best/Worst Trade [%] definition and add regression tests for #810 - #875
Conversation
…olakowo#810 Best Trade [%] is max individual trade return where return = PnL / entry value, not PnL / portfolio initial cash. Adds comment and regression tests documenting this behavior for short positions.
Test evidenceRan the new regression test plus all trade-related tests in Environment: fresh venv, Python 3.12, numpy/pandas/scipy/plotly/numba installed from To clarify the semantics (issue #810): Best Trade [%] is the maximum of individual trade returns, where return = PnL / trade entry value — not PnL / portfolio |
|
The definition in the new comment and docstrings is right for the zero-fee case, but the tests never leave it, and the docstring "return = trade PnL / trade entry value" can mislead once fees exist. In entry_val = size * entry_price
...
pnl = val_diff - entry_fees - exit_fees
ret = pnl / entry_valSo the numerator is net of both fees and the denominator is the gross I'd add one case with Smaller one: the identity Read from the diff and nb.py on master, not run. |
|
Thanks for the helpful review, @arhancanli! Both points are addressed in f5a705e:
Relevant tests: 7 passed, 178 deselected. |
Summary
Issue #810 reported that "Best Trade [%]" in portfolio statistics shows an incorrect value for short-only strategies. Investigation (with GPT-5.6) confirmed this is a semantic misunderstanding, not a calculation bug:
Best Trade [%]=max(pf.trades.returns) * 100, where each trade'sreturn = PnL / (size × entry_price)— i.e., relative to that trade's own entry notional.PnL / 1,000,000(PnL relative to total portfolio initial cash), which is a different metric with a different ranking.The short-position handling in
get_trade_stats_nb(val_diff *= -1for shorts) is correct, and the issue reporter and maintainer both confirmed the behavior is expected.Changes
vectorbt/portfolio/base.py: added a clarifying comment on thebest_trade/worst_trademetric definitions explaining that returns are relative to each trade's entry value, not portfolio initial cash.tests/test_portfolio.py: added regression tests documenting the correct semantics for short positions:Best Trade [%]equalsclosed.returns.max() * 100.(entry_price - exit_price) / entry_price.No calculation changes — behavior is intentionally unchanged.
Fixes #810 (documents the resolution).