Python is an amazing tool for back-testing stock trading strategies. In this article and video I will show you how to get started with writing your own Python programs for back-testing.
Make sure you to get your Python environment setup for write stock trading programs!
This Python program consists of a basic trading strategy for the MSFT ticker. The strategy is for demonstration purposes and should not be used to trade the stock market.
Strategy Step by Step.
The program first downloads stock data and parses it into timeseries objects. After that, we generate moving averages from the timeseries data. Our basic strategy says that when the short simple moving average (SMA9) crosses the long moving average (SMA34) we buy the stock. To close out the trade (sell the stock) both the open price and closing price has to fall below the SMA9 line.
We reset the process when the SMA1 cross back down below the SMA34 (aka a sell trigger) which will allow the back-testing program to look out for another buy signal.
This stock trading strategy is executed on 5 minute chart data for the last trading day (October 4, 2019 in this case).
Running the back testing program.
As you can see here, our back-testing program shows each buy and sell transaction and a total profit and loss on a per share basis. This strategy would have netted us $0.49 per share if this strategy was traded on October 4th on the 5 minute charts.
import pandas as pd import sys def SMA(prices, n=14): return prices.rolling(n).mean() api_key = 'demo' ticker = sys.argv api_url = 'https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=' + ticker + '&interval=5min&apikey=' + api_key + '&datatype=csv' data = pd.read_csv(api_url) stock_data = pd.DataFrame(index=range(0,len(data)),columns=['timestamp', 'open','high','low','close','volume']) stock_data = stock_data.reindex(index=stock_data.index[::-1]) for i in range(0,len(data)): ts = data['timestamp'][i] if "2019" in ts or "2018" in ts: stock_data['timestamp'][i] = data['timestamp'][i] stock_data['close'][i] = float(data['close'][i]) stock_data['high'][i] = float(data['high'][i]) stock_data['low'][i] = float(data['low'][i]) stock_data['open'][i] = float(data['open'][i]) stock_data['volume'][i] = int(data['volume'][i]) stock_data.index = stock_data.timestamp stock_data = stock_data.dropna() timestamp = stock_data['timestamp'] close = stock_data['close'] high = stock_data['high'] low = stock_data['low'] open = stock_data['open'] volume = stock_data['volume'] sma1 = SMA(close,9) sma2= SMA(close,18) buy_trigger = False buy_price = 0.0 sell_triggered = False sold_price = 0.0 total = 0.0 for now in range(0,len(stock_data)): if sma1[now] > sma2[now] and buy_trigger == False and buy_price == 0.0 and sell_triggered == False and sold_price == 0.0: print("buy trigger") buy_trigger = True elif buy_trigger == True and buy_price == 0.0 and sell_triggered == False and sold_price == 0.0: buy_price = close[now] print("%s CROSSING UP - BUY %f" % (timestamp[now],buy_price)) elif close[now ] < sma1[now] and open[now] < sma1[now] and buy_price > 0.0 and sold_price == 0.0: PL = close[now] - buy_price total = total + PL print("%s CROSSING DOWN - SELL %f P&L: %f" %(timestamp[now],close[now], PL)) print("") sold_price = close[now] if sma1[now] < sma2[now] and sold_price > 0.0: sell_triggered = True if buy_price > 0.0 and buy_trigger == True and sell_triggered == True and sold_price > 0.0: buy_trigger == False sell_triggered = False buy_price = 0.0 sold_price = 0.0 print("") print("Total P&L: %f" % total)