Python library for testing and deploying customized stock trading algorithms. Live technical indicators (RSI, Bollinger Bands, EMA, etc.) are calculated using WebDriver output from Yahoo Finance and historical price data. Structured efficiently to handle many trading algorithms at once and record their performance metrics (Profit Factor, Win percentage, etc.) in an Excel sheet. Customized strategies can be deployed through Robinhood using the robin_stocks library.
How to use it
To use the TradingStrategies library, import the TradingStrategies class. To execute the TradingStrategies’ run_strategies() function, you must define at least one “strategy”, which is a combination of a stock selection function, an entrance function, and an exit function.
– The stock selection function should return a T/F Boolean value on whether a stock will be considered for buying/short selling. The input for selection functions must consist of a dictionary of statistics such as Market Cap and Volume.
– The entrance function should return a T/F Boolean on whether a trade will be entered. This includes buying and short selling. The input for entrance functions must consist of a dictionary of live technical indicators such as RSI, MACD, EMA, etc.
– The exit function should return a T/F Boolean on whether a trade will be exited. The input for exit functions must consist of a technical indicators dictionary, the price at the time of entrance, and a Boolean representing whether the stock was bought or shorted at the time of entrance.
Here is some example code that I ran on my Raspberry Pi throughout the trading day:
#Example for using the Trading Strategies class
from TradingStrategies import TradingStrategies
#Selection strategy that filters out stocks with a market cap of less than 2 Billion and a price of less than $20 dollars per share.
def selection_one(stats) :
return stats["MARKET_CAP"] > 2000000000 and stats["PRICE"] > 20
#Entrance Strategy geared towards standard settings for MACD, BBands, RSI, etc.
def midterm_entrance(inds) :
#Get the live MACD setting of (12, 26, 9) <-- (fast EMA line, slow EMA line, MACD EMA)
macd_tuple = inds["MACD"][(12, 26, 9)]
#Get the live BBands setting of (20, 2) <-- (SMA, standard deviations)
bbands_tuple = inds["BBands"][(20, 2)]
#If the following are true, buy the stock:
#1. The price is below the lower Bollinger Band.
#2. The Relative Strength Index (period=14) is less than or equal to 40.
#3. The 20-day Exponential Moving Average is greater than the 50-day Exponential Moving Average.
#4. The difference between the fast EMA and the slow EMA is greater than the MACD EMA
#5. The 20-day Simple Moving Average is greater than the 50-day Simple Moving Average.
if inds["PRICE"] <= bbands_tuple[0] and inds["RSI"][14] <= 40 and inds["EMA"][20] > inds["EMA"][50] and macd_tuple[0] > macd_tuple[1] and inds["SMA"][20] > inds["SMA"][50] :
return True
#If the following are true, short-sell the stock:
#1. The price is above the upper Bollinger Band.
#2. The Relative Strength Index (period=14) is greater than or equal to 60.
#3. The 20-day Exponential Moving Average is less than the 50-day Exponential Moving Average.
#4. The difference between the fast EMA and the slow EMA is less than the MACD EMA
#5. The 20-day Simple Moving Average is less than the 50-day Simple Moving Average.
if inds["PRICE"] >= bbands_tuple[2] and inds["RSI"][14] >= 60 and inds["EMA"][20] < inds["EMA"][50] and macd_tuple[1] > macd_tuple[0] and inds["SMA"][20] < inds["SMA"][50] :
return False
#Entrance Strategy geared towards shorter-term settings for MACD, BBands, RSI, etc.
def shortterm_entrance(inds) :
#Get the live MACD setting of (5, 35, 5) <-- (fast EMA line, slow EMA line, MACD EMA)
macd_tuple = inds["MACD"][(5, 35, 5)]
#Get the live BBands setting of (10, 2) <-- (SMA, standard deviations)
bbands_tuple = inds["BBands"][(10, 2)]
#If the following are true, buy the stock:
#1. The price is below the lower Bollinger Band.
#2. The Relative Strength Index (period=9) is less than or equal to 40.
#3. The 10-day Exponential Moving Average is greater than the 20-day Exponential Moving Average.
#4. The difference between the fast EMA and the slow EMA is greater than the MACD EMA
#5. The 10-day Simple Moving Average is greater than the 20-day Simple Moving Average.
if inds["PRICE"] <= bbands_tuple[0] and inds["RSI"][9] <= 40 and inds["EMA"][10] > inds["EMA"][20] and macd_tuple[0] > macd_tuple[1] and inds["SMA"][10] > inds["SMA"][20] :
return True
#If the following are true, short-sell the stock:
#1. The price is above the upper Bollinger Band.
#2. The Relative Strength Index (period=9) is greater than or equal to 60.
#3. The 10-day Exponential Moving Average is less than the 20-day Exponential Moving Average.
#4. The difference between the fast EMA and the slow EMA is less than the MACD EMA
#5. The 10-day Simple Moving Average is less than the 20-day Simple Moving Average.
if inds["PRICE"] >= bbands_tuple[2] and inds["RSI"][9] >= 60 and inds["EMA"][10] < inds["EMA"][20] and macd_tuple[1] > macd_tuple[0] and inds["SMA"][10] < inds["SMA"][20] :
return False
#Exit Strategy based on simple stoploss.
def one_percent_stoploss(inds, price_entered_at, bought_or_shorted) :
percent_change = (inds["PRICE"]-price_entered_at)/price_entered_at
if abs(percent_change) > 0.01 :
return True
return False
#"strategies" list that contains all of the different strategies I want to try. TradingStrategies can handle many strategies, not just two.
strategies = [
[selection_one, midterm_entrance, one_percent_stoploss, "MidtermStrat"],
[selection_one, shortterm_entrance, one_percent_stoploss, "ShorttermStrat"]
]
obj = TradingStrategies(strategies)
#Run TradingStrategies.run_strategies(testing_mode, excel_path)
obj.run_strategies(True, "C:/Users/regin/OneDrive/Desktop/TestBook.xlsx")
Valuable Learning Experiences from this project
– Gained a deeper understanding of applied technical analysis and algorithmic trading practices.
– Applied technical indicator formulas and statistical formulas such as the rolling variance formula to calculate live indicator values in the most efficient way possible.
– Learned how to calculate and record performance metrics such as Profit Factors for algorithmic trading strategies.
– Structured the library in a way that prioritizes efficiency to ensure optimal runtime by minimizing the amount of data that needs to be scraped continuously.
– Learned how to use Python’s selenium to deploy and control web drivers.
– Learned how to use Python’s openpyxl to manipulate and edit Excel spreadsheets.
– Learned how to use Python’s robin_stocks to automate stock orders on Robinhood.
– Learned that my passion lies in the application of Math and Computer Science in the financial markets.