Market Tech,
Coding has always been a struggle for me. I only invest the time and effort when there is a large benefit. Creating algorithmic trading strategies with Quantopian is one of these cases. Because of my steep learning curve, I appreciate when competent coders provide a template that I can tweak and adjust to accomplish my goal. Thank you for this post, and your many other contributions!
With that said, I have some ideas to improve your algorithm template. Consider this to be psuedocode, since I don't fully understand the syntax required. When you find a mistake, please correct me.
1) Provide the ability to adjust the impact of each criteria, using weights. (The code below shows how the variables might be used, but doesn't provide the logic.)
# Criteria Weighting
# Provides the ability to change the impact of each criteria when making a decision.
# Range: 0 to 10
# 0 = Prevents an indicator from having any impact in the decision process
# 5 = Default setting
# 10 = Gives an indicator twice as much impact compared to the default, and 10 times the impact of a criteria with a weight of 1.
weightPctPriceChange = 5
weightRelativeVolume = 5
weightStochastics = 5
weightKeltnerChannels = 5
weightChoppiness = 5
weightMFI = 5
weightOBV = 5
weightROC = 5
weightMACD = 5
weightHighestHigh = 5
weightLongMA = 5
weightRSI = 5
weightHMA = 5
weightVolatilityVariance = 5
2) Due to the recently added low-beta requirement, many algorithms need to add the ability to short stocks to lower their beta. Do you think it would be a good idea to keep a LongScore and a ShortScore for each stock? Here is an example using two new functions:
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def calcRelativeVolumeScore(context, data):
# Calculate the relative volume based on the 50 day moving average of volume, and the volume of the previous day
volumes = history(50, '1d', field='volume')
# Calculate the 50-day average volume
AverageVolumes = volumes.mean()
for stock in data:
# Divide the previous day's volume by the average volume
RelativeVolume = volumes[stock][iloc[-1]].volume() / AverageVolumes[stock]
if RelativeVolume >= 48:
context.S[stock].LongScore =+ (5 * weightRelativeVolume)
context.S[stock].ShortScore =+ (5 * weightRelativeVolume)
elif RelativeVolume >= 24:
context.S[stock].LongScore =+ (4 * weightRelativeVolume)
context.S[stock].ShortScore =+ (4 * weightRelativeVolume)
elif RelativeVolume >= 12:
context.S[stock].LongScore =+ (3 * weightRelativeVolume)
context.S[stock].ShortScore =+ (3 * weightRelativeVolume)
elif RelativeVolume >= 6:
context.S[stock].LongScore =+ (2 * weightRelativeVolume)
context.S[stock].ShortScore =+ (2 * weightRelativeVolume)
elif RelativeVolume >= 3:
context.S[stock].LongScore =+ (1 * weightRelativeVolume)
context.S[stock].ShortScore =+ (1 * weightRelativeVolume)
else: # RelativeVolumes[stock] < 3
# Stock doesn't meet minimum requirements
context.S[stock].Eligible = No
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def calcPctPriceChangeScore(context, data):
# Calculate the percent price change from the previous close to the current price
closing_prices = history(2, '1d', 'close_price')
PctPriceChange = closing_prices.iloc[-1, -2].pct_change()
for stock in data:
# Add weighted values to Long scores
if PctPriceChange[stock] >= 80:
context.S[stock].LongScore =+ (5 * weightPctPriceChange)
elif PctPriceChange[stock] >= 40:
context.S[stock].LongScore =+ (4 * weightPctPriceChange)
elif PctPriceChange[stock] >= 20:
context.S[stock].LongScore =+ (3 * weightPctPriceChange)
elif PctPriceChange[stock] >= 10:
context.S[stock].LongScore =+ (2 * weightPctPriceChange)
elif PctPriceChange[stock] >= 5:
context.S[stock].LongScore =+ (1 * weightPctPriceChange)
# Add weighted values to Short scores
if PctPriceChange[stock] <= -80:
context.S[stock].ShortScore =+ (5 * weightPctPriceChange)
elif PctPriceChange[stock] <= -40:
context.S[stock].ShortScore =+ (4 * weightPctPriceChange)
elif PctPriceChange[stock] <= -20:
context.S[stock].ShortScore =+ (3 * weightPctPriceChange)
elif PctPriceChange[stock] <= -10:
context.S[stock].ShortScore =+ (2 * weightPctPriceChange)
elif PctPriceChange[stock] >= -5:
context.S[stock].ShortScore =+ (1 * weightPctPriceChange)
else: # -5% < PctPriceChange > 5%
# Stock doesn't meet minimum requirements
context.S[stock].Eligible = No