Incorrect commission calculation
Expected behavior
It appears the commission is being added directly to the per-unit adjusted price in: https://github.com/kernc/backtesting.py/blob/d271812c61bf42cb5df93998939109a2b13c578f/backtesting/backtesting.py#L944
Python adjusted_price_plus_commission = adjusted_price + self._commission(order.size, price) If self._commission returns a total commission for the entire order (not per unit), this addition is not correct, since it adds the entire commission fee to each unit price. The commission should either be distributed per unit before adding, or added as a lump sum after computing the total order cost.
Expected behavior: Commission should be correctly applied to the order total, not to each unit, unless self._commission returns a per-unit commission.
Suggested fix: Change the calculation so that the commission is only added once per order, or ensure that self._commission returns a per-unit fee if this logic is intended.
Code sample
bt = Backtest(
data,
DCAStrategy,
cash=1000,
commission=0.0005,
trade_on_close=True,
finalize_trades=True,
margin=1/1,
)
Actual behavior
Additional info, steps to reproduce, full crash traceback, screenshots
No response
Software versions
backtesting.__version__: 0.6.4pandas.__version__: 2.2.3numpy.__version__: 2.1.3bokeh.__version__: 3.7.0- OS: Win 10
It's true that the adjusted_price is per-unit and not per-order ...
https://github.com/kernc/backtesting.py/blob/d271812c61bf42cb5df93998939109a2b13c578f/backtesting/backtesting.py#L941-L944
https://github.com/kernc/backtesting.py/blob/d271812c61bf42cb5df93998939109a2b13c578f/backtesting/backtesting.py#L829-L834
But applying percent-based commission is irrespective of the amount—the percentages are fixed. It's just another multiplier?
But it does, however, have an erroneous effect when using a fixed or partly-fixed commission amount:
https://github.com/kernc/backtesting.py/blob/d271812c61bf42cb5df93998939109a2b13c578f/backtesting/backtesting.py#L743-L754 https://github.com/kernc/backtesting.py/blob/d271812c61bf42cb5df93998939109a2b13c578f/backtesting/backtesting.py#L768-L769
Can you confirm my reasoning is correct?
abs(order_size) * price * self._commission_relative Alwayse return total amount of commission because we multiply by order_size so it can't be added to unit price in adjusted_price + self._commission(order.size, price)
Assume 1000$ as follows
price = 1$
size=1000
commission = 1%
self._commission(order.size, price) will return 1000 * 1 * 0.01 = 10$
adjusted_price_plus_commission = 1 + 10 = 11$ "It should be 1.01$" and total size after commission = 11*1000 = 11000 which is wrong . I assume the correct answer should be 1 + 1 * 0.01 = 1.01$ so the total size after commission is 1.01 * 1000 = 1010
There is a deeper issue with the commission parameter, because it acts like a spread and alters both your win rate and the number of trades.
With commission
Without commission
Commission should be applied as a fee, i.e., deducted from the PnL. Currently, the only way to properly calculate commissions is to export the trades, sum the absolute value of units, deduct the number of lots, and apply the commission per lot that your Broker charges.
Suggested fix: Change the calculation so that the commission is only added once per order
Most brokers charge commission per "side" of the trade: once when you open and once when you close the position, so you pay it twice per trade back to your currency. If you want the commission applied once, you can model it with Backtest(..., spread=...).
Other than that, the commission computations has seemingly been fixed, according to the submitted test case. Please verify. 😅
Many thanks for clear guidance!