kernc / backtesting.py

:mag_right: :chart_with_upwards_trend: :snake: :moneybag: Backtest trading strategies in Python.
https://kernc.github.io/backtesting.py/
GNU Affero General Public License v3.0
5.39k stars 1.05k forks source link

How to get the equity before applying the strategy ? Having 2 orders at same time, even if exclusive_orders=True #1035

Closed abderrahim-plb closed 1 year ago

abderrahim-plb commented 1 year ago

Hello, First thank you for Backtesting.py, that's really an amazing and very helpful library.

Is there a way, to know the current equity ( equity before applying the srategy for a data row ). When executing this code, i have the equities printed but equities after execution of the strategy on each row.

class SmaCross(Strategy):
    n1 = 10
    n2 = 20

    def init(self):
        close = self.data.Close
        self.sma1 = self.I(SMA, close, self.n1)
        self.sma2 = self.I(SMA, close, self.n2)

    def next(self):
        print(self.equity)
        if crossover(self.sma1, self.sma2):
            self.buy()
        elif crossover(self.sma2, self.sma1):
            self.sell()

bt = Backtest(GOOG, SmaCross,
              cash=10000, commission=.002,
              exclusive_orders=True)

output = bt.run()
bt.plot()

Now, what i want to do is to find the equity before applying the strategy to a row, so i can set custom size (function of equity) to the self.buy and self.sell Thanks.

eervin123 commented 1 year ago

should be just as simple as adding the following right after your next(self):

account_equity = self.equity or just call self.equity whenever you need it.

I do things like this.

right after next

price = self.data.Close[-1]
position_value = self.position.size * price
percent_invested = (position_value / self.equity)
abderrahim-plb commented 1 year ago

should be just as simple as adding the following right after your next(self):

account_equity = self.equity or just call self.equity whenever you need it.

I do things like this.

right after next

price = self.data.Close[-1]
position_value = self.position.size * price
percent_invested = (position_value / self.equity)

Thanks for your response @eervin123 , but that position_value, isn't the precedent equity . What i want is the equity just before applying a trade or a strategy. I want that for another reason, but maybe i am complicating. Let's take the following example, i want if crossover(self.sma1, self.sma2) to run self.buy(), and if crossover(self.sma2, self.sma1) to reduce my position to 0.8. The problem i find is that I sometimes have 2 orders at same time even if I backtest using exclusive_orders set to True, so i was trying to get the equity and put the size to 0.8*equity ( rounded) . I think fixing my problem with close could be more simple .

class SmaCross(Strategy):
    n1 = 10
    n2 = 20

    def init(self):
        close = self.data.Close
        self.sma1 = self.I(SMA, close, self.n1)
        self.sma2 = self.I(SMA, close, self.n2)

    def next(self):
        print(self.equity)
        if crossover(self.sma1, self.sma2):
            self.buy()
        elif crossover(self.sma2, self.sma1):
            self.position.close(portion=0.8)

bt = Backtest(df,SmaCross,cash=1000,commission=0.000,margin=0.84,exclusive_orders=True)
output1=bt.run()
bt.plot()

Thanks.

eervin123 commented 1 year ago

yeah that was just extra stuff that I use for my strategies.

All you need is to call self.equity

if you don't want to type that all the time then

def next(self):
     eq = self.equity
# ... rest of code goes here