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.
-
-
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.
-
-
-
Do you have a backtrader strategy you would like help with?