From eb44066b5fbb1a797921755d7def1bbac06bf8b7 Mon Sep 17 00:00:00 2001 From: Andrew Dinh Date: Wed, 16 Jan 2019 08:54:06 -0800 Subject: [PATCH 1/4] Making list with datetime --- .gitignore | 1 + ExpenseRatio.py | 25 ++++-------- Functions.py | 15 +++++++ StockData.py | 65 ++++++++++++++++++++++-------- StockReturn.py | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 58 +++++++++++++++------------ 6 files changed, 205 insertions(+), 61 deletions(-) create mode 100644 Functions.py create mode 100644 StockReturn.py diff --git a/.gitignore b/.gitignore index b254bd6..46723b9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ __pycache__/ *.pyc quickstart.py creds.json +test/ diff --git a/ExpenseRatio.py b/ExpenseRatio.py index 3d14d05..f6d6df0 100644 --- a/ExpenseRatio.py +++ b/ExpenseRatio.py @@ -5,35 +5,24 @@ ''' Asks user for expense ratio of stock (I don't think there's an API for expense ratios) Runs corrrelation study (I'm not sure if I want another class for this or not) -''' +''' import numpy #import urllib2, re from urllib.request import urlopen import re +class ExpenseRatio: + def __init__(self): + + def main(): # For testing purposes - ''' + ''' a = [1,2,3] b = [2,4,6] c = numpy.corrcoef(a, b)[0, 1] print(c) - ''' - #http://finance.yahoo.com/q/pr?s=spy+profile - stockSymbols = [ "VDIGX", "VFIAX" ] - expenses = [ [ "Fund", "Most Recent Expense Ratio" ] ] - for stockSymbol in stockSymbols: - page = urlopen("http://finance.yahoo.com/q/pr?s=" + stockSymbol + "+profile" ) - data = str(page.read()) - row = re.findall("Annual Report Expense Ratio.*?", data) - if len(row) > 0: - ER = re.findall("(\d+\.\d+).*?", row[0] )[0] - expenses.append( [ stockSymbol, ER ] ) - else: - print(stockSymbol, "does not appear to be a fund with an expense ratio") - print("\n".join( i[0] + "," + i[1] for i in expenses)) - - + ''' if __name__ == "__main__": main() diff --git a/Functions.py b/Functions.py new file mode 100644 index 0000000..fc58eba --- /dev/null +++ b/Functions.py @@ -0,0 +1,15 @@ +# Python file for general functions +class Functions: + def getNearest(items, pivot): + return min(items, key=lambda x: abs(x - pivot)) + def stringToDate(date): + from datetime import datetime + #datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p') + datetime_object = datetime.strptime(date, '%Y-%m-%d').date() + return(datetime_object) + +def main(): + exit() + +if __name__ == "__main__": + main() diff --git a/StockData.py b/StockData.py index 0d6cff7..76485f5 100644 --- a/StockData.py +++ b/StockData.py @@ -33,16 +33,16 @@ import requests, json, socket import importlib.util, sys # To check whether a package is installed from datetime import datetime -class Stock: +class StockData: - def __init__(self, newName = '', newFirstLastDates = [], newAbsFirstLastDates = [], newFinalDatesAndClose = [], newAllLists = []): + def __init__(self, newName = '', newAbsFirstLastDates = [], newFinalDatesAndClose = [], newFinalDatesAndClose2 = [],newAllLists = []): self.name = newName # Name of stock - self.firstLastDates = newFirstLastDates # Dates that at least 2 sources have (or should it be all?) - Maybe let user decide self.absFirstLastDates = newAbsFirstLastDates # Absolute first and last dates from all sources - self.finalDatesAndClose = newFinalDatesAndClose # All available dates + self.finalDatesAndClose = newFinalDatesAndClose # All available dates with corresponding close values + self.finalDatesAndClose2 = newFinalDatesAndClose2 # After some consideration, I decided to keep what I had already done here and make a new list that's the same except dates are in datetime format self.allLists = newAllLists ''' - Format: + Format: # List from each source containing: [firstDate, lastDate, allDates, values, timeFrame] # firstDate & lastDate = '2018-12-18' (year-month-date) allDates = ['2018-12-17', '2018-12-14'] (year-month-date) @@ -59,9 +59,18 @@ class Stock: def setName(self, newName): self.name = newName - - def getAllLists(self): + def returnName(self): + return self.name + def returnAllLists(self): return self.allLists + def returnAbsFirstLastDates(self): + return self.absFirstLastDates + def returnAllLists(self): + return self.allLists + def returnFinalDatesAndClose(self): + return self.finalDatesAndClose + def returnFinalDatesAndClose2(self): + return self.finalDatesAndClose2 def getIEX(self): url = ''.join(('https://api.iextrading.com/1.0/stock/', self.name, '/chart/5y')) @@ -424,12 +433,29 @@ class Stock: # Want lists from most recent to oldest, comment this out if you don't want that finalDates = list(reversed(finalDates)) - finalClose = list(reversed(finalClose)) + finalClose = list(reversed(finalClose)) finalDatesAndClose.append(finalDates) finalDatesAndClose.append(finalClose) return finalDatesAndClose + def datetimeDates(self): + finalDatesAndClose2 = [] + finalDatesAndClose = self.finalDatesAndClose + finalDatesStrings = finalDatesAndClose[0] + finalClose = finalDatesAndClose[1] + finalDates = [] + + for i in range(0, len(finalDatesStrings), 1): + from Functions import Functions + temp = Functions.stringToDate(finalDatesStrings[i]) + finalDates.append(temp) + #print(finalDates) + + finalDatesAndClose2.append(finalDates) + finalDatesAndClose2.append(finalClose) + return(finalDatesAndClose2) + def is_connected(): try: # connect to the host -- tells us if the host is actually @@ -451,7 +477,7 @@ class Stock: print(package_name +" is not installed\nPlease type in 'pip install -r requirements.txt' to install all required packages") # Test internet connection - internetConnection = Stock.is_connected() + internetConnection = StockData.is_connected() if internetConnection == False: return @@ -460,7 +486,7 @@ class Stock: # IEX print("\nIEX") - listIEX = Stock.getIEX(self) + listIEX = StockData.getIEX(self) #print(listIEX) if listIEX != 'Not available': listOfFirstLastDates.append((listIEX[0], listIEX[1])) @@ -468,7 +494,7 @@ class Stock: # Alpha Vantage print("\nAlpha Vantage (AV)") - listAV = Stock.getAV(self) + listAV = StockData.getAV(self) #print(listAV) if listAV != 'Not available': listOfFirstLastDates.append((listAV[0], listAV[1])) @@ -477,38 +503,43 @@ class Stock: # COMMENTED OUT FOR NOW B/C LIMITED ''' print("\nTiingo") - listTiingo = Stock.getTiingo(self) + listTiingo = StockData.getTiingo(self) #print(listTiingo) if listTiingo != 'Not available': listOfFirstLastDates.append((listTiingo[0], listTiingo[1])) self.allLists.append(listTiingo) ''' - + #print(self.allLists) #print(listOfFirstLastDates) if (len(self.allLists) > 0): print("\n") print(len(self.allLists), "available sources for", self.name) - self.absFirstLastDates = Stock.getFirstLastDate(self, listOfFirstLastDates) + self.absFirstLastDates = StockData.getFirstLastDate(self, listOfFirstLastDates) print("\nThe absolute first date with close values is:", self.absFirstLastDates[0]) print("The absolute last date with close values is:", self.absFirstLastDates[1]) print("\nCombining dates and averaging close values") - self.finalDatesAndClose = Stock.getFinalDatesAndClose(self) # Returns [List of Dates, List of Corresponding Close Values] + self.finalDatesAndClose = StockData.getFinalDatesAndClose(self) # Returns [List of Dates, List of Corresponding Close Values] #print("All dates available:", self.finalDatesAndClose[0]) #print("All close values:\n", self.finalDatesAndClose[1]) finalDates = self.finalDatesAndClose[0] finalClose = self.finalDatesAndClose[1] print(len(finalDates), "unique dates:", finalDates[len(finalDates)-1], "...", finalDates[0]) print(len(finalClose), "close values:", finalClose[len(finalClose)-1], "...", finalClose[0]) + + print("\nConverting list of final dates to datetime") + self.finalDatesAndClose2 = StockData.datetimeDates(self) + #print(self.finalDatesAndClose2[0][0]) + else: print("No sources have data for", self.name) def main(): # For testing purposes stockName = 'spy' - stock1 = Stock(stockName) + stock1 = StockData(stockName) print("Finding available dates and close values for", stock1.name) - Stock.main(stock1) + StockData.main(stock1) if __name__ == "__main__": main() diff --git a/StockReturn.py b/StockReturn.py new file mode 100644 index 0000000..1f5bf53 --- /dev/null +++ b/StockReturn.py @@ -0,0 +1,102 @@ +# ExpenseRatio.py +# Andrew Dinh +# Python 3.6.7 +# Description: +''' +Calculates return for each stock from the lists from ExpenseRatio.py +listOfReturn = [Unadjsted Return, Sharpe Ratio, Sortino Ratio, Treynor Ratio, Jensen's Alpha] +''' + +from StockData import StockData +import datetime +from Functions import Functions + +class Return: + def __init__(self, newListOfReturn = [], newTimeFrame = [], newBeta = 0, newStandardDeviation = 0, newNegativeStandardDeviation = 0, newMarketReturn = 0, newSize = 0, newSizeOfNeg = 0, newFirstLastDates = [], newAllLists = [], newAbsFirstLastDates = ''): + self.listOfReturn = newListOfReturn + self.timeFrame = newTimeFrame # [year, months (30 days)] + self.beta = newBeta + self.standardDeviation = newStandardDeviation + self.negativeStandardDeviation = newNegativeStandardDeviation + self.marketReturn = newMarketReturn + self.size = newSize + self.sizeOfNeg = newSizeOfNeg + self.firstLastDates = newFirstLastDates + + def getFirstLastDates(self, stock): + firstLastDates = [] + timeFrame = self.timeFrame + firstDate = datetime.datetime.now() - datetime.timedelta(days=timeFrame[0]*365) + firstDate = firstDate - datetime.timedelta(days=timeFrame[1]*30) + firstDate = ''.join((str(firstDate.year),'-', str(firstDate.month), '-', str(firstDate.day))) + + lastDate = StockData.returnAbsFirstLastDates(stock)[1] + #print(lastDate) + firstLastDates.append(firstDate) + firstLastDates.append(lastDate) + return firstLastDates + + def getUnadjustedReturn(self, stock): + finalDatesAndClose = StockData.returnFinalDatesAndClose(stock) + finalDatesAndClose2 = StockData.returnFinalDatesAndClose2(stock) + firstDate = self.firstLastDates[0] + lastDate = self.firstLastDates[1] + finalDates = finalDatesAndClose[0] + finalClose = finalDatesAndClose[1] + + firstClose = 0 + for i in range(0, len(finalDates), 1): + if finalDates[i] == firstDate: + firstClose = finalClose[i] + elif finalDates[i] == lastDate: + lastClose = finalClose[i] + i = len(finalDates) + + if firstClose == 0: + print("Could not find first date. Changing first date to closest date") + temp = Functions.stringToDate(firstDate) # Change to datetime + print('Original first date: ', temp) + newFirstDate = Functions.getNearest(finalDatesAndClose2[0], temp) + print('New first date: ', newFirstDate) + + for i in range(0, len(finalDates), 1): + if finalDates[i] == str(newFirstDate): + firstClose = finalClose[i] + + print(firstClose) + print(lastClose) + +# def getBeta(self, timeFrame): + +# def getStandardDeviation(self, timeFrame): + + def main(self, stock): + # Find date to start from and last date + self.timeFrame = [] + print("\nPlease enter a time frame in years: ", end='') + #timeFrameYear = int(input()) + timeFrameYear = 5 + self.timeFrame.append(timeFrameYear) + print("Please enter a time frame in months (30 days): ", end='') + #timeFrameMonth = int(input()) + timeFrameMonth = 0 + print('') + self.timeFrame.append(timeFrameMonth) + #print(self.timeFrame) + self.firstLastDates = Return.getFirstLastDates(self, stock) + print('Dates: ', self.firstLastDates) + + print('\nGetting unadjusted return') + Return.getUnadjustedReturn(self, stock) + +def main(): + stockName = 'spy' + stock1 = StockData(stockName) + print("Finding available dates and close values for", stock1.name) + StockData.main(stock1) + + stock1Return = Return() + Return.main(stock1Return, stock1) + +if __name__ == "__main__": + main() diff --git a/main.py b/main.py index dc8fe5e..ccf3692 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ # main.py # Andrew Dinh # Python 3.6.1 -# Description: +# Description: ''' Asks users for mutual funds/stocks to compare Asks to be compared (expense ratio, turnover, market capitalization, or persistence) @@ -15,7 +15,7 @@ Gives correlation value using equation at the end (from 0 to 1) FIRST TESTING WITH EXPENSE RATIO ''' -from StockData import Stock +from StockData import StockData listOfStocks = [] numberOfStocks = int(input("How many stocks or mutual funds would you like to analyze? ")) @@ -23,48 +23,54 @@ for i in range(0, numberOfStocks, 1): print("Stock", i+1, ": ", end='') stockName = str(input()) listOfStocks.append(i) - listOfStocks[i] = Stock() + listOfStocks[i] = StockData() listOfStocks[i].setName(stockName) #print(listOfStocks[i].name) sumOfListLengths = 0 for i in range(0, numberOfStocks, 1): print(listOfStocks[i].name) - Stock.main(listOfStocks[i]) + StockData.main(listOfStocks[i]) # Count how many stocks are available - temp = Stock.getAllLists(listOfStocks[i]) + temp = StockData.returnAllLists(listOfStocks[i]) sumOfListLengths = sumOfListLengths + len(temp) if sumOfListLengths == 0: - print("No sources have stock data for given stocks") + print("No sources have data for given stocks") + exit() -else: - #print(listOfStocks[0].name, listOfStocks[0].absFirstLastDates, listOfStocks[0].finalDatesAndClose) - indicatorFound = False - while indicatorFound == False: - print("\n1. Expense Ratio\n2. Asset Size\n3. Turnover\n4. Persistence\nWhich indicator would you like to look at? ", end='') - indicator = str(input()) - indicatorFound = True +# Find return over time using either Jensen's Alpha, Sharpe Ratio, Sortino Ratio, or Treynor Ratio +#from StockReturn import Return - if indicator == 'Expense Ratio' or indicator == '1' or indicator == 'expense ratio': - print('\nExpense Ratio') - elif indicator == 'Asset Size' or indicator == '2' or indicator == 'asset size': - print('\nAsset Size') +# Runs correlation or regression study +#print(listOfStocks[0].name, listOfStocks[0].absFirstLastDates, listOfStocks[0].finalDatesAndClose) +indicatorFound = False +while indicatorFound == False: + print("\n1. Expense Ratio\n2. Asset Size\n3. Turnover\n4. Persistence\nWhich indicator would you like to look at? ", end='') + indicator = str(input()) + indicatorFound = True - elif indicator == 'Turnover' or indicator == '3' or indicator == 'turnover': - print('\nTurnover') + if indicator == 'Expense Ratio' or indicator == '1' or indicator == 'expense ratio': + #from ExpenseRatio import ExpenseRatio + print('\nExpense Ratio') - elif indicator == 'Persistence' or indicator == '4' or indicator == 'persistence': - print('\nPersistence') + elif indicator == 'Asset Size' or indicator == '2' or indicator == 'asset size': + print('\nAsset Size') - else: - indicatorFound = False - print('\nInvalid input, please enter indicator again') + elif indicator == 'Turnover' or indicator == '3' or indicator == 'turnover': + print('\nTurnover') + + elif indicator == 'Persistence' or indicator == '4' or indicator == 'persistence': + print('\nPersistence') + + else: + indicatorFound = False + print('\nInvalid input, please enter indicator again') ''' stockName = 'IWV' stock1 = Stock(stockName) print("Finding available dates and close values for", stock1.name) -Stock.main(stock1) -''' \ No newline at end of file +StockData.main(stock1) +''' From 61e0cd0d91be3df1c9ceb8e08043cc27f69d996c Mon Sep 17 00:00:00 2001 From: Andrew Dinh Date: Thu, 17 Jan 2019 08:50:19 -0800 Subject: [PATCH 2/4] Check list of dates in StockReturn.py --- Functions.py | 9 +++++++ StockData.py | 7 +++--- StockReturn.py | 66 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/Functions.py b/Functions.py index fc58eba..1ec3db4 100644 --- a/Functions.py +++ b/Functions.py @@ -4,9 +4,18 @@ class Functions: return min(items, key=lambda x: abs(x - pivot)) def stringToDate(date): from datetime import datetime + #datetime_object = datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p') datetime_object = datetime.strptime(date, '%Y-%m-%d').date() return(datetime_object) + ''' + dateSplit = date.split('-') + year = int(dateSplit[0]) + month = int(dateSplit[1]) + day = int(dateSplit[2]) + datetime_object = datetime.date(year, month, day) + ''' + return datetime_object def main(): exit() diff --git a/StockData.py b/StockData.py index 76485f5..1571222 100644 --- a/StockData.py +++ b/StockData.py @@ -29,8 +29,7 @@ Daily Requests = 20,000 Symbol Requests = 500 ''' -import requests, json, socket -import importlib.util, sys # To check whether a package is installed +import requests, json from datetime import datetime class StockData: @@ -446,8 +445,8 @@ class StockData: finalClose = finalDatesAndClose[1] finalDates = [] + from Functions import Functions for i in range(0, len(finalDatesStrings), 1): - from Functions import Functions temp = Functions.stringToDate(finalDatesStrings[i]) finalDates.append(temp) #print(finalDates) @@ -457,6 +456,7 @@ class StockData: return(finalDatesAndClose2) def is_connected(): + import socket # To check internet connection try: # connect to the host -- tells us if the host is actually # reachable @@ -468,6 +468,7 @@ class StockData: return False def main(self): + import importlib.util, sys # To check whether a package is installed packages = ['requests'] for i in range(0, len(packages), 1): diff --git a/StockReturn.py b/StockReturn.py index 1f5bf53..80435be 100644 --- a/StockReturn.py +++ b/StockReturn.py @@ -36,35 +36,51 @@ class Return: firstLastDates.append(lastDate) return firstLastDates + def getFirstLastDates2(self, stock): + finalDatesAndClose = StockData.returnFinalDatesAndClose(stock) + finalDatesAndClose2 = StockData.returnFinalDatesAndClose2(stock) + firstDate = self.firstLastDates[0] + lastDate = self.firstLastDates[1] + finalDates = finalDatesAndClose[0] + + firstDateExists = False + lastDateExists = False + for i in range(0, len(finalDates), 1): + if finalDates[i] == str(firstDate): + firstDateExists = True + elif finalDates[i] == lastDate: + lastDateExists = True + i = len(finalDates) + + if firstDateExists == False: + print("Could not find first date. Changing first date to closest date") + tempDate = Functions.stringToDate(firstDate) # Change to datetime + print('Original first date: ', tempDate) + #tempDate = datetime.date(2014,1,17) + newFirstDate = Functions.getNearest(finalDatesAndClose2[0], tempDate) + print('New first date: ', newFirstDate) + firstDate = str(newFirstDate) + + if lastDateExists == False: + print("Could not find final date. Changing final date to closest date") + tempDate2 = Functions.stringToDate(lastDate) # Change to datetime + print('Original final date: ', tempDate2) + #tempDate2 = datetime.date(2014,1,17) + newLastDate = Functions.getNearest(finalDatesAndClose2[0], tempDate2) + print('New final date: ', newLastDate) + lastDate = str(newLastDate) + + firstLastDates = [] + firstLastDates.append(firstDate) + firstLastDates.append(lastDate) + return firstLastDates + def getUnadjustedReturn(self, stock): finalDatesAndClose = StockData.returnFinalDatesAndClose(stock) finalDatesAndClose2 = StockData.returnFinalDatesAndClose2(stock) firstDate = self.firstLastDates[0] lastDate = self.firstLastDates[1] finalDates = finalDatesAndClose[0] - finalClose = finalDatesAndClose[1] - - firstClose = 0 - for i in range(0, len(finalDates), 1): - if finalDates[i] == firstDate: - firstClose = finalClose[i] - elif finalDates[i] == lastDate: - lastClose = finalClose[i] - i = len(finalDates) - - if firstClose == 0: - print("Could not find first date. Changing first date to closest date") - temp = Functions.stringToDate(firstDate) # Change to datetime - print('Original first date: ', temp) - newFirstDate = Functions.getNearest(finalDatesAndClose2[0], temp) - print('New first date: ', newFirstDate) - - for i in range(0, len(finalDates), 1): - if finalDates[i] == str(newFirstDate): - firstClose = finalClose[i] - - print(firstClose) - print(lastClose) # def getBeta(self, timeFrame): @@ -86,6 +102,10 @@ class Return: self.firstLastDates = Return.getFirstLastDates(self, stock) print('Dates: ', self.firstLastDates) + print('\nMaking sure dates are within list...') + self.firstLastDates = Return.getFirstLastDates2(self, stock) + print('New dates: ', self.firstLastDates) + print('\nGetting unadjusted return') Return.getUnadjustedReturn(self, stock) From 7f675e25ae91a76944c4048dbbea310654676f93 Mon Sep 17 00:00:00 2001 From: Andrew Dinh Date: Thu, 17 Jan 2019 16:40:42 -0800 Subject: [PATCH 3/4] Update StockReturn.py --- StockReturn.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/StockReturn.py b/StockReturn.py index 80435be..c99579a 100644 --- a/StockReturn.py +++ b/StockReturn.py @@ -55,19 +55,19 @@ class Return: if firstDateExists == False: print("Could not find first date. Changing first date to closest date") tempDate = Functions.stringToDate(firstDate) # Change to datetime - print('Original first date: ', tempDate) + print('Original first date:', tempDate) #tempDate = datetime.date(2014,1,17) newFirstDate = Functions.getNearest(finalDatesAndClose2[0], tempDate) - print('New first date: ', newFirstDate) + print('New first date:', newFirstDate) firstDate = str(newFirstDate) if lastDateExists == False: print("Could not find final date. Changing final date to closest date") tempDate2 = Functions.stringToDate(lastDate) # Change to datetime - print('Original final date: ', tempDate2) + print('Original final date:', tempDate2) #tempDate2 = datetime.date(2014,1,17) newLastDate = Functions.getNearest(finalDatesAndClose2[0], tempDate2) - print('New final date: ', newLastDate) + print('New final date:', newLastDate) lastDate = str(newLastDate) firstLastDates = [] @@ -81,6 +81,19 @@ class Return: firstDate = self.firstLastDates[0] lastDate = self.firstLastDates[1] finalDates = finalDatesAndClose[0] + finalClose = finalDatesAndClose[1] + + for i in range(0, len(finalDates), 1): + if finalDates[i] == str(firstDate): + firstClose = finalClose[i] + elif finalDates[i] == lastDate: + lastClose = finalClose[i] + i = len(finalDates) + + print('Close values:', firstClose, '...', lastClose) + unadjustedReturn = float(lastClose/firstClose) + unadjustedReturn = unadjustedReturn * 100 + return unadjustedReturn # def getBeta(self, timeFrame): @@ -89,6 +102,8 @@ class Return: def main(self, stock): # Find date to start from and last date self.timeFrame = [] + self.listOfReturn = [] + print("\nPlease enter a time frame in years: ", end='') #timeFrameYear = int(input()) timeFrameYear = 5 @@ -107,7 +122,9 @@ class Return: print('New dates: ', self.firstLastDates) print('\nGetting unadjusted return') - Return.getUnadjustedReturn(self, stock) + unadjustedReturn = Return.getUnadjustedReturn(self, stock) + self.listOfReturn.append(unadjustedReturn) + print(self.listOfReturn[0], '%') def main(): stockName = 'spy' From d1888d2779bac04c9228da4055d43893a01d6ba0 Mon Sep 17 00:00:00 2001 From: Andrew Dinh Date: Tue, 22 Jan 2019 10:49:58 -0800 Subject: [PATCH 4/4] Added support for datetime --- .gitignore | 2 ++ README.md | 2 ++ StockData.py | 24 ++++++++++++++++++------ StockReturn.py | 6 ++++-- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 46723b9..293b5a3 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ __pycache__/ quickstart.py creds.json test/ +.vscode/ +listGoogle.py \ No newline at end of file diff --git a/README.md b/README.md index 0670ca7..36ff698 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A project to determine indicators of overperforming mutual funds. This project is written in Python and will examine market capitalization, persistence, turnover, and expense ratios. ### Prerequisites +`$ pip install -r requirements.txt` +or `$ pip install requests` Created by Andrew Dinh from Dr. TJ Owens Gilroy Early College Academy diff --git a/StockData.py b/StockData.py index 1571222..e2a90a9 100644 --- a/StockData.py +++ b/StockData.py @@ -141,9 +141,17 @@ class StockData: def getAV(self): listAV = [] - url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=', self.name, '&apikey=', apiAV)) + #url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=', self.name, '&apikey=', apiAV)) # https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=MSFT&apikey=demo + + #url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=', self.name, '&outputsize=full&apikey=', apiAV)) + # https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=demo + + url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=', self.name, '&outputsize=full&apikey=', apiAV)) + # https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&outputsize=full&apikey=demo + print("\nSending request to:", url) + print("(This will take a while)") f = requests.get(url) json_data = f.text loaded_json = json.loads(json_data) @@ -156,9 +164,9 @@ class StockData: return 'Not available' #print(loaded_json['Monthly Time Series']) - monthlyTimeSeries = loaded_json['Monthly Time Series'] + dailyTimeSeries = loaded_json['Time Series (Daily)'] #print(monthlyTimeSeries) - listOfDates = list(monthlyTimeSeries) + listOfDates = list(dailyTimeSeries) #print(listOfDates) firstDate = listOfDates[-1] @@ -179,8 +187,9 @@ class StockData: values = [] for i in range(0, len(listOfDates), 1): temp = listOfDates[i] - loaded_json2 = monthlyTimeSeries[temp] - value = loaded_json2['4. close'] + loaded_json2 = dailyTimeSeries[temp] + #value = loaded_json2['4. close'] + value = loaded_json2['5. adjusted close'] values.append(value) listAV.append(values) #print(listOfDates[0]) @@ -485,6 +494,8 @@ class StockData: listOfFirstLastDates = [] self.allLists = [] + print('\nNOTE: Only IEX and Alpha Vantage support adjusted returns') + # IEX print("\nIEX") listIEX = StockData.getIEX(self) @@ -504,6 +515,7 @@ class StockData: # COMMENTED OUT FOR NOW B/C LIMITED ''' print("\nTiingo") + print("NOTE: Tiingo does not return adjusted returns!!") listTiingo = StockData.getTiingo(self) #print(listTiingo) if listTiingo != 'Not available': @@ -515,7 +527,7 @@ class StockData: #print(listOfFirstLastDates) if (len(self.allLists) > 0): print("\n") - print(len(self.allLists), "available sources for", self.name) + print(len(self.allLists), "available source(s) for", self.name) self.absFirstLastDates = StockData.getFirstLastDate(self, listOfFirstLastDates) print("\nThe absolute first date with close values is:", self.absFirstLastDates[0]) print("The absolute last date with close values is:", self.absFirstLastDates[1]) diff --git a/StockReturn.py b/StockReturn.py index c99579a..44e36bb 100644 --- a/StockReturn.py +++ b/StockReturn.py @@ -107,11 +107,12 @@ class Return: print("\nPlease enter a time frame in years: ", end='') #timeFrameYear = int(input()) timeFrameYear = 5 + print(timeFrameYear) self.timeFrame.append(timeFrameYear) print("Please enter a time frame in months (30 days): ", end='') #timeFrameMonth = int(input()) timeFrameMonth = 0 - print('') + print(timeFrameMonth) self.timeFrame.append(timeFrameMonth) #print(self.timeFrame) self.firstLastDates = Return.getFirstLastDates(self, stock) @@ -124,7 +125,8 @@ class Return: print('\nGetting unadjusted return') unadjustedReturn = Return.getUnadjustedReturn(self, stock) self.listOfReturn.append(unadjustedReturn) - print(self.listOfReturn[0], '%') + print(self.listOfReturn[0]) + print(self.listOfReturn[0]/timeFrameYear, '%') def main(): stockName = 'spy'