Last active
July 12, 2020 04:53
-
-
Save cameronShadmehry/fd046a3c6fcf3792610046f980bcaf14 to your computer and use it in GitHub Desktop.
Code to analyze each stock
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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