backtesting.py icon indicating copy to clipboard operation
backtesting.py copied to clipboard

list of trade values are all the same for all time steps

Open watsonix opened this issue 3 years ago • 5 comments

Expected Behavior

trade value (current price x volume) should be different across trades

Actual Behavior

each step, trade values are all equal. (note same is not true of .entry_price)

[218.8]
[209.74, 209.74]
[212.0, 212.0, 212.0]
[215.82, 215.82, 215.82, 215.82]

Steps to Reproduce


from backtesting.test import GOOG
from backtesting import Backtest
from backtesting import Strategy
class dummy(Strategy):    
    def init(self): pass
    def next(self):
            print(list(t.value for t in self.trades))
            self.buy(size=2)
bt = Backtest(GOOG, dummy, cash=10_000, commission=0)
stats = bt.run()

Additional info

  • Backtesting version: 0.3.3

watsonix avatar May 17 '22 08:05 watsonix

Trade.value observes the current price, not entry price ... https://github.com/kernc/backtesting.py/blob/65f54f6819cac5f36fd94ebf0377644c62b4ee3d/backtesting/backtesting.py#L615-L619

kernc avatar May 17 '22 21:05 kernc

Got it. Thank you for that clarification. In this framework is there a better way of tracking how much cash remains than subtracting from the total initial cash something like sum(t.entry_price*t.size for t in self.trades)?

watsonix avatar May 24 '22 21:05 watsonix

Maybe Strategy.equity, e.g.

cash = self.equity - sum(t.value for t in self.trades)

kernc avatar May 25 '22 02:05 kernc

Oh this is exactly what I was attempting to do when I caught the behavior in my first post above. I believe this doesn't track how much cash is left for the reasons you already cited. i.e. don't I need to do

cash = self.equity - sum(t.entry_price*t.size for t in self.trades)

? (since I'm interested in how much cash I burned rather than what that cash turned into after the buy)

watsonix avatar May 28 '22 04:05 watsonix

My formula, I believe, gives cash on hand. Trade.value assumed the current asset price, but so does Strategy.equity!

Then again, Strategy.equity adds Trade.pl values ... https://github.com/kernc/backtesting.py/blob/65f54f6819cac5f36fd94ebf0377644c62b4ee3d/backtesting/backtesting.py#L754-L755 I'm not quite certain now. :thinking:

kernc avatar May 28 '22 16:05 kernc

If you're interested in what you burned, you can't use .equity since it recalculates on each iteration. Store the initial value in a separate variable:

def init(self):
    self.initial_cash = self.equity
def next(self):
    print('Initial cash left:', self.initial_cash - sum(t.entry_price*t.size for t in self.trades))

kernc avatar Dec 11 '22 23:12 kernc