Search code examples
pythoninstantiationabstract

Can't instantiate abstract class with abstract methods backtesting


import pandas as pd

class BuyAndHold(Strategy):
    def __init__(self, data, buy_percentage, keep_buying_percentage, sell_percentage):
        Strategy.__init__(self)
        self.data = data
        self.buy_percentage = buy_percentage
        self.keep_buying_percentage = keep_buying_percentage
        self.sell_percentage = sell_percentage
        self.portfolio_history = []
    
    def buy_more_quantity(self, current_price, initial_buy_price, last_quantity):
        return int(last_quantity * 2)

    def next(self, portfolio, current_price, initial_buy_price, last_quantity, cash):
        if portfolio is None:
            # Initial buy
            buy_price = initial_buy_price * (1 - self.buy_percentage)
            buy_quantity = int(cash / buy_price)
            portfolio = buy_price * buy_quantity
            cash -= portfolio
            self.portfolio_history.append(portfolio + cash)
            return portfolio, cash, buy_quantity

        sell_price = initial_buy_price * (1 + self.sell_percentage)
        if current_price >= sell_price:
            portfolio = current_price * last_quantity
            cash += portfolio
            self.portfolio_history.append(portfolio + cash)
            return None, cash, 0

        keep_buying_price = initial_buy_price * (1 - self.keep_buying_percentage)
        if current_price <= keep_buying_price:
            buy_price = current_price
            buy_quantity = self.buy_more_quantity(current_price, initial_buy_price, last_quantity)
            portfolio = buy_price * buy_quantity
            cash -= portfolio
            self.portfolio_history.append(portfolio + cash)
            return portfolio, cash, buy_quantity

        self.portfolio_history.append(portfolio + cash)
        return portfolio, cash, last_quantity
               
    def stop(self):
        portfolio_value = 0
        portfolio_history = []
        for i, p in enumerate(self.portfolio):
            if 'sell_price' in p:
                portfolio_value += p['sell_price'] * p['quantity']
            else:
                portfolio_value += self.data.close[-(len(self.portfolio) - i)] * p['quantity']
            portfolio_history.append(portfolio_value)
        self.portfolio_history = pd.Series(portfolio_history, index=self.data.index)

I have seen this question asked multiple times but am not able to solve my problem with those answers.Any help will be appreciated. Thanks.

Later when this code is called

bt = Backtest(data['Close']['XLB'], BuyAndHold(data['Close']['XLB'], buy_percentage=0.1, keep_buying_percentage=0.05, sell_percentage=0.1))

But it keeps throwing that error: "Can't instantiate abstract class with abstract methods and points towards the above line bt = blahblah


Solution

  • The docs say

    class Strategy

    A trading strategy base class. Extend this class and override methods Strategy.init() and Strategy.next() to define your own strategy.

    You have written an __init__ method, but need an init method too. Without it, your subclass remains abstract.