Skip to content

Instantly share code, notes, and snippets.

@cameronShadmehry
Last active July 12, 2020 04:53
Show Gist options
  • Save cameronShadmehry/fd046a3c6fcf3792610046f980bcaf14 to your computer and use it in GitHub Desktop.
Save cameronShadmehry/fd046a3c6fcf3792610046f980bcaf14 to your computer and use it in GitHub Desktop.
Code to analyze each stock
# Get the path for each stock file in a list
list_files = (glob.glob("<Your Path>\\SMA_Analysis\\Stocks\\*.csv"))
# You can use this line to limit the analysis to a portion of the stocks in the "stocks folder"
# list_files = list_files[:100]
# Create the dataframe that we will be adding the final analysis of each stock to
Compare_Stocks = pd.DataFrame(columns=["Company", "Days_Observed", "Crosses", "True_Positive", "False_Positive", "True_Negative", "False_Negative", "Sensitivity",
"Specificity", "Accuracy", "TPR", "FPR"])
# While loop to cycle through the stock paths
count = 0
for stock in list_files:
# Dataframe to hold the historical data of the stock we are interested in.
Hist_data = pd.read_csv(stock)
Company = ((os.path.basename(stock)).split(".csv")[0]) # Name of the company
# Constants for the stock that we will be updating later
Days_Observed = 0
Crosses = 0
True_Positive = 0
False_Positive = 0
True_Negative = 0
False_Negative = 0
Sensitivity = 0
Specificity = 0
Accuracy = 0
# This list holds the closing prices of a stock
prices = []
c = 0
# Add the closing prices to the prices list and make sure we start at greater than 2 dollars to reduce outlier calculations.
while c < len(Hist_data):
if Hist_data.iloc[c,4] > float(2.00): # Check that the closing price for this day is greater than $2.00
prices.append(Hist_data.iloc[c,4])
c += 1
prices_df = pd.DataFrame(prices) # Make a dataframe from the prices list
# Calculate exponentiall weighted moving averages:
day12 = prices_df.ewm(span=12).mean() #
day26 = prices_df.ewm(span=26).mean()
macd = [] # List to hold the MACD line values
counter=0 # Loop to substantiate the MACD line
while counter < (len(day12)):
macd.append(day12.iloc[counter,0] - day26.iloc[counter,0]) # Subtract the 26 day EW moving average from the 12 day.
counter += 1
macd_df = pd.DataFrame(macd)
signal_df = macd_df.ewm(span=9).mean() # Create the signal line, which is a 9 day EW moving average
signal = signal_df.values.tolist() # Add the signal line values to a list.
# Loop to Compare the expected MACD crosses results to the actual results
Day = 1
while Day < len(macd)-5: # -1 to be able to use the last day for prediction, -5 so we can look at the 5 day post average.
Prev_Day = Day-1
# Avg_Closing_Next_Days = (prices[Day+1] + prices[Day+2] + prices[Day+3] + prices[Day+4] + prices[Day+5])/5 # To use 5 day average as a decision.
Avg_Closing_Next_Days = (prices[Day+1] + prices[Day+2] + prices[Day+3])/3 # To use 3 day average as a decision.
Days_Observed += 1 # Count how many days were observed
if ((signal[Prev_Day] > macd[Prev_Day]) and (signal[Day] <= macd[Day])): # when the signal line dips below the macd line (Expected increase over the next x days)
Crosses += 1 # register that a cross occurred
if (prices[Day] < Avg_Closing_Next_Days): # Tests if the price increases over the next x days.
True_Positive += 1
else:
False_Negative += 1
if ((signal[Prev_Day] < macd[Prev_Day]) and (signal[Day] >= macd[Day])): # when the signal line moves above the macd line (Expected dip over the next x days)
Crosses += 1
if (prices[Day] > Avg_Closing_Next_Days): # Tests if the price decreases over the next x days.
True_Negative += 1
else:
False_Positive += 1
Day += 1
try:
Sensitivity = (True_Positive / (True_Positive + False_Negative)) # Calculate sensitivity
except ZeroDivisionError: # Catch the divide by zero error
Sensitivity = 0
try:
Specificity = (True_Negative / (True_Negative + False_Positive)) # Calculate specificity
except ZeroDivisionError:
Specificity
try:
Accuracy = (True_Positive + True_Negative) / (True_Negative + True_Positive + False_Positive + False_Negative) # Calculate accuracy
except ZeroDivisionError:
Accuracy = 0
TPR = Sensitivity # Calculate the true positive rate
FPR = 1 - Specificity # Calculate the false positive rate
# Create a row to add to the compare_stocks
add_row = {'Company' : Company, 'Days_Observed' : Days_Observed, 'Crosses' : Crosses, 'True_Positive' : True_Positive, 'False_Positive' : False_Positive,
'True_Negative' : True_Negative, 'False_Negative' : False_Negative, 'Sensitivity' : Sensitivity, 'Specificity' : Specificity, 'Accuracy' : Accuracy, 'TPR' : TPR, 'FPR' : FPR}
Compare_Stocks = Compare_Stocks.append(add_row, ignore_index = True) # Add the analysis on the stock to the existing Compare_Stocks dataframe
count += 1
Compare_Stocks.to_csv("<Your Path>\\SMA_Analysis\\All_Stocks.csv", index = False) # Save the compiled data on each stock to a csv - All_Stocks.csv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment