Making list with datetime

This commit is contained in:
Andrew Dinh 2019-01-16 08:54:06 -08:00
parent f37e77178d
commit eb44066b5f
6 changed files with 205 additions and 61 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ __pycache__/
*.pyc *.pyc
quickstart.py quickstart.py
creds.json creds.json
test/

View File

@ -5,35 +5,24 @@
''' '''
Asks user for expense ratio of stock (I don't think there's an API for expense ratios) 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) Runs corrrelation study (I'm not sure if I want another class for this or not)
''' '''
import numpy import numpy
#import urllib2, re #import urllib2, re
from urllib.request import urlopen from urllib.request import urlopen
import re import re
class ExpenseRatio:
def __init__(self):
def main(): # For testing purposes def main(): # For testing purposes
''' '''
a = [1,2,3] a = [1,2,3]
b = [2,4,6] b = [2,4,6]
c = numpy.corrcoef(a, b)[0, 1] c = numpy.corrcoef(a, b)[0, 1]
print(c) 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.*?</tr>", data)
if len(row) > 0:
ER = re.findall("<td.*?>(\d+\.\d+).*?</td>", 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__": if __name__ == "__main__":
main() main()

15
Functions.py Normal file
View File

@ -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()

View File

@ -33,16 +33,16 @@ import requests, json, socket
import importlib.util, sys # To check whether a package is installed import importlib.util, sys # To check whether a package is installed
from datetime import datetime 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.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.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 self.allLists = newAllLists
''' '''
Format: Format:
# List from each source containing: [firstDate, lastDate, allDates, values, timeFrame] # List from each source containing: [firstDate, lastDate, allDates, values, timeFrame]
# firstDate & lastDate = '2018-12-18' (year-month-date) # firstDate & lastDate = '2018-12-18' (year-month-date)
allDates = ['2018-12-17', '2018-12-14'] (year-month-date) allDates = ['2018-12-17', '2018-12-14'] (year-month-date)
@ -59,9 +59,18 @@ class Stock:
def setName(self, newName): def setName(self, newName):
self.name = newName self.name = newName
def returnName(self):
def getAllLists(self): return self.name
def returnAllLists(self):
return self.allLists 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): def getIEX(self):
url = ''.join(('https://api.iextrading.com/1.0/stock/', self.name, '/chart/5y')) 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 # Want lists from most recent to oldest, comment this out if you don't want that
finalDates = list(reversed(finalDates)) finalDates = list(reversed(finalDates))
finalClose = list(reversed(finalClose)) finalClose = list(reversed(finalClose))
finalDatesAndClose.append(finalDates) finalDatesAndClose.append(finalDates)
finalDatesAndClose.append(finalClose) finalDatesAndClose.append(finalClose)
return finalDatesAndClose 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(): def is_connected():
try: try:
# connect to the host -- tells us if the host is actually # 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") print(package_name +" is not installed\nPlease type in 'pip install -r requirements.txt' to install all required packages")
# Test internet connection # Test internet connection
internetConnection = Stock.is_connected() internetConnection = StockData.is_connected()
if internetConnection == False: if internetConnection == False:
return return
@ -460,7 +486,7 @@ class Stock:
# IEX # IEX
print("\nIEX") print("\nIEX")
listIEX = Stock.getIEX(self) listIEX = StockData.getIEX(self)
#print(listIEX) #print(listIEX)
if listIEX != 'Not available': if listIEX != 'Not available':
listOfFirstLastDates.append((listIEX[0], listIEX[1])) listOfFirstLastDates.append((listIEX[0], listIEX[1]))
@ -468,7 +494,7 @@ class Stock:
# Alpha Vantage # Alpha Vantage
print("\nAlpha Vantage (AV)") print("\nAlpha Vantage (AV)")
listAV = Stock.getAV(self) listAV = StockData.getAV(self)
#print(listAV) #print(listAV)
if listAV != 'Not available': if listAV != 'Not available':
listOfFirstLastDates.append((listAV[0], listAV[1])) listOfFirstLastDates.append((listAV[0], listAV[1]))
@ -477,38 +503,43 @@ class Stock:
# COMMENTED OUT FOR NOW B/C LIMITED # COMMENTED OUT FOR NOW B/C LIMITED
''' '''
print("\nTiingo") print("\nTiingo")
listTiingo = Stock.getTiingo(self) listTiingo = StockData.getTiingo(self)
#print(listTiingo) #print(listTiingo)
if listTiingo != 'Not available': if listTiingo != 'Not available':
listOfFirstLastDates.append((listTiingo[0], listTiingo[1])) listOfFirstLastDates.append((listTiingo[0], listTiingo[1]))
self.allLists.append(listTiingo) self.allLists.append(listTiingo)
''' '''
#print(self.allLists) #print(self.allLists)
#print(listOfFirstLastDates) #print(listOfFirstLastDates)
if (len(self.allLists) > 0): if (len(self.allLists) > 0):
print("\n") print("\n")
print(len(self.allLists), "available sources for", self.name) 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("\nThe absolute first date with close values is:", self.absFirstLastDates[0])
print("The absolute last date with close values is:", self.absFirstLastDates[1]) print("The absolute last date with close values is:", self.absFirstLastDates[1])
print("\nCombining dates and averaging close values") 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 dates available:", self.finalDatesAndClose[0])
#print("All close values:\n", self.finalDatesAndClose[1]) #print("All close values:\n", self.finalDatesAndClose[1])
finalDates = self.finalDatesAndClose[0] finalDates = self.finalDatesAndClose[0]
finalClose = self.finalDatesAndClose[1] finalClose = self.finalDatesAndClose[1]
print(len(finalDates), "unique dates:", finalDates[len(finalDates)-1], "...", finalDates[0]) print(len(finalDates), "unique dates:", finalDates[len(finalDates)-1], "...", finalDates[0])
print(len(finalClose), "close values:", finalClose[len(finalClose)-1], "...", finalClose[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: else:
print("No sources have data for", self.name) print("No sources have data for", self.name)
def main(): # For testing purposes def main(): # For testing purposes
stockName = 'spy' stockName = 'spy'
stock1 = Stock(stockName) stock1 = StockData(stockName)
print("Finding available dates and close values for", stock1.name) print("Finding available dates and close values for", stock1.name)
Stock.main(stock1) StockData.main(stock1)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

102
StockReturn.py Normal file
View File

@ -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()

58
main.py
View File

@ -1,7 +1,7 @@
# main.py # main.py
# Andrew Dinh # Andrew Dinh
# Python 3.6.1 # Python 3.6.1
# Description: # Description:
''' '''
Asks users for mutual funds/stocks to compare Asks users for mutual funds/stocks to compare
Asks to be compared (expense ratio, turnover, market capitalization, or persistence) 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 FIRST TESTING WITH EXPENSE RATIO
''' '''
from StockData import Stock from StockData import StockData
listOfStocks = [] listOfStocks = []
numberOfStocks = int(input("How many stocks or mutual funds would you like to analyze? ")) 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='') print("Stock", i+1, ": ", end='')
stockName = str(input()) stockName = str(input())
listOfStocks.append(i) listOfStocks.append(i)
listOfStocks[i] = Stock() listOfStocks[i] = StockData()
listOfStocks[i].setName(stockName) listOfStocks[i].setName(stockName)
#print(listOfStocks[i].name) #print(listOfStocks[i].name)
sumOfListLengths = 0 sumOfListLengths = 0
for i in range(0, numberOfStocks, 1): for i in range(0, numberOfStocks, 1):
print(listOfStocks[i].name) print(listOfStocks[i].name)
Stock.main(listOfStocks[i]) StockData.main(listOfStocks[i])
# Count how many stocks are available # Count how many stocks are available
temp = Stock.getAllLists(listOfStocks[i]) temp = StockData.returnAllLists(listOfStocks[i])
sumOfListLengths = sumOfListLengths + len(temp) sumOfListLengths = sumOfListLengths + len(temp)
if sumOfListLengths == 0: if sumOfListLengths == 0:
print("No sources have stock data for given stocks") print("No sources have data for given stocks")
exit()
else: # Find return over time using either Jensen's Alpha, Sharpe Ratio, Sortino Ratio, or Treynor Ratio
#print(listOfStocks[0].name, listOfStocks[0].absFirstLastDates, listOfStocks[0].finalDatesAndClose) #from StockReturn import Return
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
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': # Runs correlation or regression study
print('\nAsset Size') #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': if indicator == 'Expense Ratio' or indicator == '1' or indicator == 'expense ratio':
print('\nTurnover') #from ExpenseRatio import ExpenseRatio
print('\nExpense Ratio')
elif indicator == 'Persistence' or indicator == '4' or indicator == 'persistence': elif indicator == 'Asset Size' or indicator == '2' or indicator == 'asset size':
print('\nPersistence') print('\nAsset Size')
else: elif indicator == 'Turnover' or indicator == '3' or indicator == 'turnover':
indicatorFound = False print('\nTurnover')
print('\nInvalid input, please enter indicator again')
elif indicator == 'Persistence' or indicator == '4' or indicator == 'persistence':
print('\nPersistence')
else:
indicatorFound = False
print('\nInvalid input, please enter indicator again')
''' '''
stockName = 'IWV' stockName = 'IWV'
stock1 = Stock(stockName) stock1 = Stock(stockName)
print("Finding available dates and close values for", stock1.name) print("Finding available dates and close values for", stock1.name)
Stock.main(stock1) StockData.main(stock1)
''' '''