For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

SMA Crossever strategy not showing expected results



  • Greetings (Back)Traders,

    I am working on a program that will backtest SMA Crossover strategy across various combinations of short and long MAs from 1 to 200.

    I have written the following code below.

    The problem i am facing is, for a majority of SMA Crossovers the end result (profit/loss) is 0.

    # Backtest SMA Crossover strategy
    from math import floor
    import pandas, sqlite3
    
    class Algox_bt():
    
        def __init__(self):
            print("Starting Backtest.")
        
    
        def create_db(self):
            self.conn = sqlite3.connect('backtest.db')
            self.c = self.conn.cursor()
            # create a table to hold the short ma, long ma and any profit/loss made during trading SMA (short, long) Crossover 
            self.c.execute('CREATE TABLE IF NOT EXISTS results(symbol TEXT, short INT, long INT, pl REAL)')
            self.conn.commit()
            self.c.execute('DELETE FROM results')
            self.conn.commit()
    
    
    
        def get_symbols(self):
            # this function gets a csv file from the Exchange that lists the symbols traded in the exchange
            names = [
                'symbol', 'series', 'date', 'prev_close', 'open_price',
                'high_price', 'low_price', 'last_price', 'close_price',
                'avg_price', 'ttl_trd_qnty', 'turnover_lacs', 'no_of_trades',
                'deliv_qty', 'deliv_per']
    
            # get the bhav copy
            self.dg = pandas.read_csv('https://www1.nseindia.com/products/content/sec_bhavdata_full.csv', names=names, header=0)
            # selecting only equity stocks
            self.dg = self.dg[self.dg.series == ' EQ']
            # removing penny stocks
            self.dg = self.dg[self.dg['close_price'] > 5]
            self.symbols = self.dg['symbol'].tolist()
    
    
    
        def backtest(self, symbol):
            try:
                # read daily historical data for the symbol
                self.df = pandas.read_csv('{}.csv'.formaat(symbol))
    
                # wish to check all combinations of SMA short and long crossover between 1 and 200
                for short in range(1, 201):
                    for long_ in range(short, 201):
    
                        fund = 100000 # setting funds
                        position = {'side': None, 'quantity' : 0, 'buy_price' : 0.0, 'sell_price' : 0.0, 'buy_amount' : 0.0, 'sell_amount' : 0.0, 'pl' : 0.0}
                        self.df['sma_s'] = self.df['Close'].rolling(short).mean()
                        self.df['sma_l'] = self.df['Close'].rolling(long_).mean()
                        self.df.dropna(inplace=True)
                        rows, _ = self.df.shape
    
                        # looping through all the rows from oldest to newtest in search for a sma crossver signal
                        for i in range(3, rows):
                            # check for buy signal
                            if self.df['sma_s'].iloc[i-3] < self.df['sma_l'].iloc[i-3]:
                                if self.df['sma_s'].iloc[i-2] >= self.df['sma_l'].iloc[i-2]:
                                    if self.df['sma_s'].iloc[i-1] > self.df['sma_l'].iloc[i-1]:
                                        # check if position exists
                                        if position['side'] == None:
                                            position['side'] = 'long'
                                            position['buy_price'] = self.df['Open'].iloc[i]
                                            position['quantity'] = floor(fund / self.df['Open'].iloc[i])
                                            position['buy_amount'] = self.df['Open'].iloc[i] * position['quantity']
                                            # update fund 
                                            fund = fund - position['buy_amount']
                                            # print('Trade\t{}, Bought, Qty: {}, Buy Price: {}, Amount : {}, Remaining Fund: {}'.format(symbol, position['quantity'], position['buy_price'], position['buy_amount'], fund))
                                        else:
                                            pass
                            
                            # check for sell signal
                            if self.df['sma_s'].iloc[i-3] > self.df['sma_l'].iloc[i-3]:
                                if self.df['sma_s'].iloc[i-2] <= self.df['sma_l'].iloc[i-2]:
                                    if self.df['sma_s'].iloc[i-1] < self.df['sma_l'].iloc[i-1]:
                                        if position['side'] != None:
                                            # exit at open
                                            position['sell_price'] = self.df['Open'].iloc[i]
                                            position['sell_amount'] = position['quantity'] * self.df['Open'].iloc[i]
                                            position['pl'] = position['sell_amount'] - position['buy_amount']
                                            fund = fund + position['sell_amount']
                                            position['side'] == None
                                            # print('Trade\t{}, Sold, Qty: {}, Sell Price: {}, Amount : {}, Remaining Fund: {} Profit/Loss: {}'.format(symbol, position['quantity'], position['buy_price'], position['buy_amount'], fund, position['pl']))
                                            position = {'side': None, 'quantity' : 0, 'buy_price' : 0.0, 'sell_price' : 0.0, 'buy_amount' : 0.0, 'sell_amount' : 0.0, 'pl' : 0.0}
    
                                        else:
                                            pass
    
                        print('SMA {}, {} Crossover, Gain/Loss: {}'.format(short, long_, fund-100000))
                        bt.c.execute('INSERT INTO results (symbol, short, long, pl) VALUES (?, ?, ?, ?)', (symbol, short, long_, fund-100000))
                        bt.conn.commit()
    
            except Exception as e:
                print('Error', e)
    
    
    
    if __name__ == '__main__':
    
        bt = Algox_bt()
        bt.get_symbols()
        bt.create_db()
        for bt.symbol in bt.symbols:
            bt.backtest(bt.symbol)
        bt.c.close()
        bt.conn.close()
        print('Completed.')
    

    I would really be grateful if you could kindly take a look at the code and help me understand what am i doing wrong and help me improve this.

    Thanks a lot in advance.



  • Although such a strategy could be easily implemented using the Backtrader framework, the code above has no relation to the framework supported in this forum.

    I suggest you start with Backtrader Quickstart Guide and Simple Sample strategy and
    continue from there.



  • I downvoted because this is 100% pandas and is not backtrader at all.



  • @vladisld and @run-out are you completely sure every post on this forum is related to backtrader ?



  • Yes sir. This is Backtrader framework support forum.

    There are other general algo and non-algo trading forums out there:

    https://www.reddit.com/r/algotrading/
    https://www.elitetrader.com/et/

    and many others - just google it.



  • @vladisld unhelpful people like you should be restricted access to any public forum. People like you not only restrict genuine help seekers for getting the help they need but also discourage people who are willing to help by sabotaging the thread and posting multiple spam posts that do not help anyone.



  • @Sourav-Basu-Roy said in SMA Crossever strategy not showing expected results:

    @vladisld unhelpful people like you

    Perhaps you should look at this link before you call @vladisld unhelpful. Of all the active participants in this forum he is the most helpful. Do you have a backtrader question we can help you with? I would suggest to you that if you wanted to execute the sma strategy you have, backtrader could do it easily, and if you like, then we would be glad to assist you.



  • I bet @run-out should be banned also. ;) Otherwise it would be hundreds of helpers here, who cares that the question is not even close to the forum theme.



  • 05686b80-c9e1-4127-8f29-31b8e102a887-image.png

    As i had guessed @run-out and @vladisld are not just users like me and not even a moderator but yet they are acting like self appointed captains setting all the rules where they have absolutely no power.

    They are helping out a lot but their attitude needs to change.



  • 18664937-3af2-4f83-a490-1bb246c8e464-image.png

    As i had guessed @run-out and @vladisld are just users like me and not even a moderator but yet they are acting like self appointed captains setting all the rules where they have absolutely no power.

    They are helping out a lot but their attitude needs to change.



  • Do you have a backtrader strategy you would like help with?


Log in to reply
 

});