Finished overhaul of version-1

This commit is contained in:
Andrew Dinh 2019-01-31 13:22:02 -08:00
parent 5f63eeb57e
commit 0dcdd1049d
9 changed files with 1059 additions and 606 deletions

3
.gitignore vendored
View File

@ -1,8 +1,5 @@
__pycache__/StockData.cpython-37.pyc __pycache__/StockData.cpython-37.pyc
__pycache__/ __pycache__/
*.pyc *.pyc
quickstart.py
creds.json
test/ test/
.vscode/ .vscode/
listGoogle.py

View File

@ -12,6 +12,7 @@ import numpy
from urllib.request import urlopen from urllib.request import urlopen
import re import re
class ExpenseRatio: class ExpenseRatio:
def __init__(self): def __init__(self):
@ -24,5 +25,6 @@ def main(): # For testing purposes
print(c) print(c)
''' '''
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -1,7 +1,7 @@
# Python file for general functions # Python file for general functions
class Functions:
def getNearest(items, pivot): def getNearest(items, pivot):
return min(items, key=lambda x: abs(x - pivot)) return min(items, key=lambda x: abs(x - pivot))
def stringToDate(date): def stringToDate(date):
from datetime import datetime from datetime import datetime
@ -17,8 +17,31 @@ class Functions:
''' '''
return datetime_object return datetime_object
def removeExtraDatesAndCloseValues(list1, list2):
# Returns the two lists but with the extra dates and corresponding close values removed
# list = [[dates], [close values]]
newList1 = [[], []]
newList2 = [[], []]
for i in range(0, len(list1[0]), 1):
for j in range(0, len(list2[0]), 1):
if list1[0][i] == list2[0][j]:
newList1[0].append(list1[0][i])
newList2[0].append(list1[0][i])
newList1[1].append(list1[1][i])
newList2[1].append(list2[1][j])
break
returnList = []
returnList.append(newList1)
returnList.append(newList2)
return returnList
def main(): def main():
exit() exit()
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -16,6 +16,4 @@ To begin, run
Some ticker values to try: Some ticker values to try:
SPY, VFINX, AAPL, GOOGL SPY, VFINX, AAPL, GOOGL
`$ pip install numpy`
Created by Andrew Dinh from Dr. TJ Owens Gilroy Early College Academy Created by Andrew Dinh from Dr. TJ Owens Gilroy Early College Academy

View File

@ -3,6 +3,9 @@
# Python 3.6.1 # Python 3.6.1
# Description: Returns all available dates and prices for each stock requested. # Description: Returns all available dates and prices for each stock requested.
import json
import requests
from datetime import datetime
''' '''
Available API's: Can it do mutual funds? Available API's: Can it do mutual funds?
IEX: No IEX: No
@ -29,16 +32,17 @@ Daily Requests = 20,000
Symbol Requests = 500 Symbol Requests = 500
''' '''
import requests, json
from datetime import datetime
class StockData: class StockData:
def __init__(self, newName='', newAbsFirstLastDates=[], newFinalDatesAndClose=[], newFinalDatesAndClose2=[], newAllLists=[]): def __init__(self, newName='', newAbsFirstLastDates=[], newFinalDatesAndClose=[], newFinalDatesAndClose2=[], newAllLists=[]):
self.name = newName # Name of stock self.name = newName # Name of stock
self.absFirstLastDates = newAbsFirstLastDates # Absolute first and last dates from all sources # Absolute first and last dates from all sources
self.finalDatesAndClose = newFinalDatesAndClose # All available dates with corresponding close values self.absFirstLastDates = newAbsFirstLastDates
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 # All available dates with corresponding close values
self.finalDatesAndClose = newFinalDatesAndClose
# 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.finalDatesAndClose2 = newFinalDatesAndClose2
self.allLists = newAllLists self.allLists = newAllLists
''' '''
Format: Format:
@ -51,28 +55,37 @@ class StockData:
def set(self, newName, newFirstLastDates, newAbsFirstLastDates, newFinalDatesAndClose, newAllLists): def set(self, newName, newFirstLastDates, newAbsFirstLastDates, newFinalDatesAndClose, 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 # 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.firstLastDates = newFirstLastDates
# Absolute first and last dates from all sources
self.absFirstLastDates = newAbsFirstLastDates
self.finalDatesAndClose = newFinalDatesAndClose self.finalDatesAndClose = newFinalDatesAndClose
self.allLists = newAllLists self.allLists = newAllLists
def setName(self, newName): def setName(self, newName):
self.name = newName self.name = newName
def returnName(self): def returnName(self):
return self.name return self.name
def returnAllLists(self): def returnAllLists(self):
return self.allLists return self.allLists
def returnAbsFirstLastDates(self): def returnAbsFirstLastDates(self):
return self.absFirstLastDates return self.absFirstLastDates
def returnAllLists(self): def returnAllLists(self):
return self.allLists return self.allLists
def returnFinalDatesAndClose(self): def returnFinalDatesAndClose(self):
return self.finalDatesAndClose return self.finalDatesAndClose
def returnFinalDatesAndClose2(self): def returnFinalDatesAndClose2(self):
return self.finalDatesAndClose2 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'))
#link = "https://api.iextrading.com/1.0/stock/spy/chart/5y" #link = "https://api.iextrading.com/1.0/stock/spy/chart/5y"
print("\nSending request to:", url) print("\nSending request to:", url)
f = requests.get(url) f = requests.get(url)
@ -92,7 +105,8 @@ class StockData:
firstDate = firstLine['date'] firstDate = firstLine['date']
# print("firstDate:",firstDate) # print("firstDate:",firstDate)
# Find lastDate (comes last) # Find lastDate (comes last)
lastLine = loaded_json[-1] # Returns last value of the list (Equivalent to len(loaded_json)-1) # Returns last value of the list (Equivalent to len(loaded_json)-1)
lastLine = loaded_json[-1]
#print("lastLine:", lastLine) #print("lastLine:", lastLine)
lastDate = lastLine['date'] lastDate = lastLine['date']
#print("last date:", lastDate) #print("last date:", lastDate)
@ -147,7 +161,8 @@ class StockData:
#url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=', self.name, '&outputsize=full&apikey=', apiAV)) #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 # 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)) 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 # https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=MSFT&outputsize=full&apikey=demo
print("\nSending request to:", url) print("\nSending request to:", url)
@ -263,7 +278,8 @@ class StockData:
print("\nFinding all dates given") print("\nFinding all dates given")
dates = [] dates = []
values = [] # Used loop for finding values values = [] # Used loop for finding values
url2 = ''.join((url, '/prices?startDate=', firstDate, '&endDate=', lastDate)) url2 = ''.join((url, '/prices?startDate=',
firstDate, '&endDate=', lastDate))
# https://api.tiingo.com/tiingo/daily/<ticker>/prices?startDate=2012-1-1&endDate=2016-1-1 # https://api.tiingo.com/tiingo/daily/<ticker>/prices?startDate=2012-1-1&endDate=2016-1-1
print("\nSending request to:", url2) print("\nSending request to:", url2)
requestResponse2 = requests.get(url2, headers=headers) requestResponse2 = requests.get(url2, headers=headers)
@ -479,7 +495,8 @@ class StockData:
def main(self): def main(self):
print('Beginning StockData.py') print('Beginning StockData.py')
import importlib.util, sys # To check whether a package is installed import importlib.util
import sys # To check whether a package is installed
packages = ['requests'] packages = ['requests']
for i in range(0, len(packages), 1): for i in range(0, len(packages), 1):
@ -531,18 +548,24 @@ class StockData:
if (len(self.allLists) > 0): if (len(self.allLists) > 0):
print("\n", end='') print("\n", end='')
print(len(self.allLists), "available source(s) for", self.name) print(len(self.allLists), "available source(s) for", self.name)
self.absFirstLastDates = StockData.getFirstLastDate(self, listOfFirstLastDates) self.absFirstLastDates = StockData.getFirstLastDate(
print("\nThe absolute first date with close values is:", self.absFirstLastDates[0]) self, listOfFirstLastDates)
print("The absolute last date with close values is:", self.absFirstLastDates[1]) 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") print("\nCombining dates and averaging close values")
self.finalDatesAndClose = StockData.getFinalDatesAndClose(self) # Returns [List of Dates, List of Corresponding Close Values] # Returns [List of Dates, List of Corresponding Close Values]
self.finalDatesAndClose = StockData.getFinalDatesAndClose(self)
#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:",
print(len(finalClose), "close values:", finalClose[len(finalClose)-1], "...", finalClose[0]) 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\n") print("\nConverting list of final dates to datetime\n")
self.finalDatesAndClose2 = StockData.datetimeDates(self) self.finalDatesAndClose2 = StockData.datetimeDates(self)
@ -551,11 +574,13 @@ class StockData:
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 = StockData(stockName) stock1 = StockData(stockName)
print("Finding available dates and close values for", stock1.name) print("Finding available dates and close values for", stock1.name)
StockData.main(stock1) StockData.main(stock1)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -11,6 +11,7 @@ from StockData import StockData
import datetime import datetime
from Functions import Functions from Functions import Functions
class Return: class Return:
def __init__(self, newListOfReturn=[], newTimeFrame=[], newBeta=0, newStandardDeviation=0, newNegativeStandardDeviation=0, newMarketReturn=0, newSize=0, newSizeOfNeg=0, newFirstLastDates=[], newAllLists=[], newAbsFirstLastDates=''): def __init__(self, newListOfReturn=[], newTimeFrame=[], newBeta=0, newStandardDeviation=0, newNegativeStandardDeviation=0, newMarketReturn=0, newSize=0, newSizeOfNeg=0, newFirstLastDates=[], newAllLists=[], newAbsFirstLastDates=''):
self.listOfReturn = newListOfReturn self.listOfReturn = newListOfReturn
@ -32,9 +33,11 @@ class Return:
def getFirstLastDates(self, stock): def getFirstLastDates(self, stock):
firstLastDates = [] firstLastDates = []
timeFrame = self.timeFrame timeFrame = self.timeFrame
firstDate = datetime.datetime.now() - datetime.timedelta(days=timeFrame[0]*365) firstDate = datetime.datetime.now(
) - datetime.timedelta(days=timeFrame[0]*365)
firstDate = firstDate - datetime.timedelta(days=timeFrame[1]*30) firstDate = firstDate - datetime.timedelta(days=timeFrame[1]*30)
firstDate = ''.join((str(firstDate.year),'-', str(firstDate.month), '-', str(firstDate.day))) firstDate = ''.join(
(str(firstDate.year), '-', str(firstDate.month), '-', str(firstDate.day)))
lastDate = StockData.returnAbsFirstLastDates(stock)[1] lastDate = StockData.returnAbsFirstLastDates(stock)[1]
# print(lastDate) # print(lastDate)
@ -63,7 +66,8 @@ class Return:
tempDate = Functions.stringToDate(firstDate) # Change to datetime tempDate = Functions.stringToDate(firstDate) # Change to datetime
print('Original first date:', tempDate) print('Original first date:', tempDate)
#tempDate = datetime.date(2014,1,17) #tempDate = datetime.date(2014,1,17)
newFirstDate = Functions.getNearest(finalDatesAndClose2[0], tempDate) newFirstDate = Functions.getNearest(
finalDatesAndClose2[0], tempDate)
print('New first date:', newFirstDate) print('New first date:', newFirstDate)
firstDate = str(newFirstDate) firstDate = str(newFirstDate)
@ -72,7 +76,8 @@ class Return:
tempDate2 = Functions.stringToDate(lastDate) # Change to datetime tempDate2 = Functions.stringToDate(lastDate) # Change to datetime
print('Original final date:', tempDate2) print('Original final date:', tempDate2)
#tempDate2 = datetime.date(2014,1,17) #tempDate2 = datetime.date(2014,1,17)
newLastDate = Functions.getNearest(finalDatesAndClose2[0], tempDate2) newLastDate = Functions.getNearest(
finalDatesAndClose2[0], tempDate2)
print('New final date:', newLastDate) print('New final date:', newLastDate)
lastDate = str(newLastDate) lastDate = str(newLastDate)
@ -97,7 +102,8 @@ class Return:
print('Close values:', firstClose, '...', lastClose) print('Close values:', firstClose, '...', lastClose)
fullUnadjustedReturn = float(lastClose/firstClose) fullUnadjustedReturn = float(lastClose/firstClose)
unadjustedReturn = fullUnadjustedReturn**(1/(self.timeFrame[0]+(self.timeFrame[1])*.1)) unadjustedReturn = fullUnadjustedReturn**(
1/(self.timeFrame[0]+(self.timeFrame[1])*.1))
return unadjustedReturn return unadjustedReturn
def getBeta(self): def getBeta(self):
@ -113,7 +119,7 @@ class Return:
for i in range(0, len(finalDates), 1): for i in range(0, len(finalDates), 1):
if finalDates[i] == str(firstDate): if finalDates[i] == str(firstDate):
firstClose = finalClose[i] firstClose = finalClose[i]
55ggbh
# list1 = # list1 =
list2 = [1, 2, 4, 1] list2 = [1, 2, 4, 1]
@ -149,10 +155,10 @@ class Return:
print('\nGetting unadjusted return') print('\nGetting unadjusted return')
unadjustedReturn = Return.getUnadjustedReturn(self, stock) unadjustedReturn = Return.getUnadjustedReturn(self, stock)
self.listOfReturn.append(unadjustedReturn) self.listOfReturn.append(unadjustedReturn)
print('Average annual return for the past', self.timeFrame[0], 'years and', self.timeFrame[1], 'months: ', end='') print('Average annual return for the past',
self.timeFrame[0], 'years and', self.timeFrame[1], 'months: ', end='')
print((self.listOfReturn[0]-1)*100, '%', sep='') print((self.listOfReturn[0]-1)*100, '%', sep='')
def main(self, stock): def main(self, stock):
print('Beginning StockReturn.py') print('Beginning StockReturn.py')
@ -169,12 +175,14 @@ class Return:
print('\nGetting unadjusted return') print('\nGetting unadjusted return')
unadjustedReturn = Return.getUnadjustedReturn(self, stock) unadjustedReturn = Return.getUnadjustedReturn(self, stock)
self.listOfReturn.append(unadjustedReturn) self.listOfReturn.append(unadjustedReturn)
print('Average annual return for the past', self.timeFrame[0], 'years and', self.timeFrame[1], 'months: ', end='') print('Average annual return for the past',
self.timeFrame[0], 'years and', self.timeFrame[1], 'months: ', end='')
print((self.listOfReturn[0]-1)*100, '%', sep='') print((self.listOfReturn[0]-1)*100, '%', sep='')
#print('\nGetting beta') #print('\nGetting beta')
#beta = Return.getBeta(self, stock) #beta = Return.getBeta(self, stock)
def main(): def main():
stockName = 'spy' stockName = 'spy'
stock1 = StockData(stockName) stock1 = StockData(stockName)
@ -186,5 +194,6 @@ def main():
Return.main(stock1Return, stock1) Return.main(stock1Return, stock1)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -1,54 +0,0 @@
# https://support.google.com/docs/answer/3093281?hl=en
# Historical data cannot be downloaded or accessed via the Sheets API or Apps Script. If you attempt to do so, you will see a #N/A error in place of the values in the corresponding cells of your spreadsheet.
import gspread, time, webbrowser, msvcrt
from oauth2client.service_account import ServiceAccountCredentials
def main():
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('creds.json', scope)
gc = gspread.authorize(credentials)
'''
# Just by ID:
#sheet = gc.open_by_key('1YS8qBQCXKNfSgQgXeUdSGOd6lM2wm-inV0_1YE36vQM')
sheet = gc.open_by_url('https://docs.google.com/spreadsheets/d/1YS8qBQCXKNfSgQgXeUdSGOd6lM2wm-inV0_1YE36vQM')
worksheet = sheet.get_worksheet(0)
worksheet.update_acell('B1', 'bingo!')
#worksheet.update_cell(1, 2, 'Bingo!')
val = worksheet.acell('B1').value
#val = worksheet.cell(1, 2).value
print(val)
'''
url = 'https://docs.google.com/spreadsheets/d/1YS8qBQCXKNfSgQgXeUdSGOd6lM2wm-inV0_1YE36vQM'
surl = 'https://www.andrewkdinh.com/u/listGoogle'
print("Opening", url)
#webbrowser.open(surl)
sheet = gc.open_by_url(url)
worksheet = sheet.get_worksheet(0)
print('Writing Google Finance function to A1')
worksheet.update_cell(1, 1, '=GOOGLEFINANCE("GOOG", "price", DATE(2014,1,1), DATE(2014,12,31), "DAILY")')
print('\nOpening link to the Google Sheet. Please download the file as comma-separated values (.csv) and move it to the directory of this Python file',
'\nFile > Download as > Comma-separated values(.csv,currentsheet)')
print("If the link did not open, please go to", surl)
print("Press any key to continue")
#time.sleep(45)
'''
for i in range(60, 0, -1):
print(i, end='\r')
time.sleep(1)
'''
waiting = True
while waiting == True:
if msvcrt.kbhit():
waiting = False
print("e")
#val = worksheet.acell('A1').value
#print(val)
if __name__ == '__main__':
main()

479
main.py
View File

@ -1,20 +1,474 @@
# main.py # main.py
# Andrew Dinh # Andrew Dinh
# Python 3.6.1 # Python 3.6.7
# Description:
'''
Asks users for mutual funds/stocks to compare
Asks to be compared (expense ratio, turnover, market capitalization, or persistence)
Asks for time period (Possibly: 1 year, 5 years, 10 years)
Makes the mutual funds as class Stock
Gets data from each API
Compare and contrast dates and end changeOverTime for set time period
NOTES: Later can worry about getting close values to make a graph or something
Gives correlation value using equation at the end (from 0 to 1)
FIRST TESTING WITH EXPENSE RATIO import requests
import json
import datetime
import numpy
import Functions
# API Keys
apiAV = 'O42ICUV58EIZZQMU'
# apiBarchart = 'a17fab99a1c21cd6f847e2f82b592838'
apiBarchart = 'f40b136c6dc4451f9136bb53b9e70ffa'
apiTiingo = '2e72b53f2ab4f5f4724c5c1e4d5d4ac0af3f7ca8'
apiTradier = 'n26IFFpkOFRVsB5SNTVNXicE5MPD'
# If you're going to take these API keys and abuse it, you should really reconsider your life priorities
'''
API Keys:
Alpha Vantage API Key: O42ICUV58EIZZQMU
Barchart API Key: a17fab99a1c21cd6f847e2f82b592838
Possible other one? f40b136c6dc4451f9136bb53b9e70ffa
150 getHistory queries per day
Tiingo API Key: 2e72b53f2ab4f5f4724c5c1e4d5d4ac0af3f7ca8
Tradier API Key: n26IFFpkOFRVsB5SNTVNXicE5MPD
Monthly Bandwidth = 5 GB
Hourly Requests = 500
Daily Requests = 20,000
Symbol Requests = 500
Mutual funds:
Yes: Alpha Vantage, Tiingo
No: IEX, Barchart
''' '''
class Stock:
# GLOBAL VARIABLES
timeFrame = []
benchmarkDates = []
benchmarkCloseValues = []
benchmarkUnadjustedReturn = 0
def __init__(self):
# BASIC DATA
self.name = '' # Ticker symbol
self.allDates = []
self.allCloseValues = []
self.dates = []
self.closeValues = []
self.datesMatchBenchmark = []
self.closeValuesMatchBenchmark = []
# CALCULATED RETURN
self.unadjustedReturn = 0
self.sortino = 0
self.sharpe = 0
self.treynor = 0
self.alpha = 0
self.beta = 0
self.standardDeviation = 0
self.negStandardDeviation = 0
# INDICATOR VALUES
self.expenseRatio = 0
self.assetSize = 0
self.turnover = 0
self.persistence = [] # [Years, Months]
# CALCULATED VALUES FOR INDICATORS
self.correlation = 0
self.regression = 0
def setName(self, newName):
self.name = newName
def getName(self):
return self.name
def getAllDates(self):
return self.allDates
def getAllCloseValues(self):
return self.allCloseValues
def IEX(self):
print('IEX')
url = ''.join(
('https://api.iextrading.com/1.0/stock/', self.name, '/chart/5y'))
#link = "https://api.iextrading.com/1.0/stock/spy/chart/5y"
print("\nSending request to:", url)
f = requests.get(url)
json_data = f.text
if json_data == 'Unknown symbol' or f.status_code == 404:
print("IEX not available")
return 'Not available'
loaded_json = json.loads(json_data)
listIEX = []
print("\nFinding all dates given")
allDates = []
for i in range(0, len(loaded_json), 1): # If you want to do oldest first
# for i in range(len(loaded_json)-1, -1, -1):
line = loaded_json[i]
date = line['date']
allDates.append(date)
listIEX.append(allDates)
print(len(listIEX[0]), "dates")
print("\nFinding close values for each date")
values = []
for i in range(0, len(loaded_json), 1): # If you want to do oldest first
# for i in range(len(loaded_json)-1, -1, -1):
line = loaded_json[i]
value = line['close']
values.append(value)
listIEX.append(values)
print(len(listIEX[1]), "close values")
return listIEX
def AV(self):
print('Alpha Vantage')
listAV = []
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)
if len(loaded_json) == 1 or f.status_code == 404:
print("Alpha Vantage not available")
return 'Not available'
dailyTimeSeries = loaded_json['Time Series (Daily)']
listOfDates = list(dailyTimeSeries)
# listAV.append(listOfDates)
listAV.append(list(reversed(listOfDates)))
print("\nFinding close values for each date")
values = []
for i in range(0, len(listOfDates), 1):
temp = listOfDates[i]
loaded_json2 = dailyTimeSeries[temp]
#value = loaded_json2['4. close']
value = loaded_json2['5. adjusted close']
values.append(value)
# listAV.append(values)
listAV.append(list(reversed(values)))
print(len(listAV[1]), "close values")
return listAV
def Tiingo(self):
print('Tiingo')
token = ''.join(('Token ', apiTiingo))
headers = {
'Content-Type': 'application/json',
'Authorization': token
}
url = ''.join(('https://api.tiingo.com/tiingo/daily/', self.name))
print("\nSending request to:", url)
f = requests.get(url, headers=headers)
loaded_json = f.json()
if len(loaded_json) == 1 or f.status_code == 404:
print("Tiingo not available")
return 'Not available'
listTiingo = []
print("\nFinding first and last date")
firstDate = loaded_json['startDate']
lastDate = loaded_json['endDate']
print(firstDate, '...', lastDate)
print("\nFinding all dates given", end='')
dates = []
values = []
url2 = ''.join((url, '/prices?startDate=',
firstDate, '&endDate=', lastDate))
# https://api.tiingo.com/tiingo/daily/<ticker>/prices?startDate=2012-1-1&endDate=2016-1-1
print("\nSending request to:", url2, '\n')
requestResponse2 = requests.get(url2, headers=headers)
loaded_json2 = requestResponse2.json()
for i in range(0, len(loaded_json2)-1, 1):
line = loaded_json2[i]
dateWithTime = line['date']
temp = dateWithTime.split('T00:00:00.000Z')
date = temp[0]
dates.append(date)
value = line['close']
values.append(value)
listTiingo.append(dates)
print(len(listTiingo[0]), "dates")
print("Finding close values for each date")
# Used loop from finding dates
listTiingo.append(values)
print(len(listTiingo[1]), "close values")
return listTiingo
def datesAndClose(self):
print('\n', Stock.getName(self), sep='')
# sourceList = ['AV', 'Tiingo', 'IEX'] # Change back to this later
sourceList = ['Tiingo', 'IEX', 'AV']
# Use each source until you get a value
for j in range(0, len(sourceList), 1):
source = sourceList[j]
print('\nSource being used: ', source)
if source == 'AV':
datesAndCloseList = Stock.AV(self)
elif source == 'Tiingo':
datesAndCloseList = Stock.Tiingo(self)
elif source == 'IEX':
datesAndCloseList = Stock.IEX(self)
if datesAndCloseList != 'Not available':
break
else:
#print(sourceList[j], 'does not have data available')
if j == len(sourceList)-1:
print('\nNo sources have data for', self.name)
return
# FIGURE OUT WHAT TO DO HERE
# Convert dates to datetime
allDates = datesAndCloseList[0]
for j in range(0, len(allDates), 1):
allDates[j] = Functions.stringToDate(allDates[j])
datesAndCloseList[0] = allDates
return datesAndCloseList
def datesAndClose2(self):
print('Shortening list to fit time frame')
# Have to do this because if I just make dates = self.allDates & closeValues = self.allCloseValues, then deleting from dates & closeValues also deletes it from self.allDates & self.allCloseValues (I'm not sure why)
dates = []
closeValues = []
for i in range(0, len(self.allDates), 1):
dates.append(self.allDates[i])
closeValues.append(self.allCloseValues[i])
firstDate = datetime.datetime.now().date() - datetime.timedelta(
days=self.timeFrame[0]*365) - datetime.timedelta(days=self.timeFrame[1]*30)
print('\n', self.timeFrame[0], ' years and ',
self.timeFrame[1], ' months ago: ', firstDate, sep='')
closestDate = Functions.getNearest(dates, firstDate)
if closestDate != firstDate:
print('Closest date available for', self.name, ':', closestDate)
firstDate = closestDate
else:
print(self.name, 'has a close value for', firstDate)
# Remove dates in list up to firstDate
while dates[0] != firstDate:
dates.remove(dates[0])
# Remove close values until list is same length as dates
while len(closeValues) != len(dates):
closeValues.remove(closeValues[0])
datesAndCloseList2 = []
datesAndCloseList2.append(dates)
datesAndCloseList2.append(closeValues)
print(len(dates), 'dates')
print(len(closeValues), 'close values')
return datesAndCloseList2
def unadjustedReturn(self):
unadjustedReturn = (float(self.closeValues[len(
self.closeValues)-1]/self.closeValues[0])**(1/(self.timeFrame[0]+(self.timeFrame[1])*.1)))-1
print('Annual unadjusted return:', unadjustedReturn)
return unadjustedReturn
def beta(self, benchmarkMatchDatesAndCloseValues):
beta = numpy.corrcoef(self.closeValuesMatchBenchmark,
benchmarkMatchDatesAndCloseValues[1])[0, 1]
print('Beta:', beta)
return beta
def isConnected():
import socket # To check internet connection
try:
# connect to the host -- tells us if the host is actually reachable
socket.create_connection(("www.andrewkdinh.com", 80))
print('Internet connection is good!')
return True
except OSError:
# pass
print("No internet connection!")
return False
def checkPackages():
import importlib.util
import sys
packagesInstalled = True
packages = ['requests', 'numpy']
for i in range(0, len(packages), 1):
package_name = packages[i]
spec = importlib.util.find_spec(package_name)
if spec is None:
print(
package_name +
" is not installed\nPlease type in 'pip install -r requirements.txt' to install all required packages")
packagesInstalled = False
return packagesInstalled
def benchmarkInit():
# Treat benchmark like stock
benchmarkTicker = ''
while benchmarkTicker == '':
benchmarks = ['S&P500', 'DJIA', 'Russell 3000', 'MSCI EAFE']
benchmarksTicker = ['SPY', 'DJIA', 'VTHR', 'EFT']
print('\nList of benchmarks:', benchmarks)
# benchmark = str(input('Benchmark to compare to: '))
benchmark = 'S&P500'
for i in range(0, len(benchmarks), 1):
if benchmark == benchmarks[i]:
benchmarkTicker = benchmarksTicker[i]
if benchmarkTicker == '':
print('Benchmark not found. Please type in a benchmark from the list')
print(benchmark, ' (', benchmarkTicker, ')', sep='')
benchmark = Stock()
benchmark.setName(benchmarkTicker)
return benchmark
def stocksInit():
listOfStocks = []
# numberOfStocks = int(input('\nHow many stocks/mutual funds/ETFs would you like to analyze? '))
numberOfStocks = 1
print('\nHow many stocks/mutual funds/ETFs would you like to analyze? ', numberOfStocks)
for i in range(0, numberOfStocks, 1):
print('Stock', i + 1, ': ', end='')
#stockName = str(input())
stockName = 'FBGRX'
print(stockName)
listOfStocks.append(stockName)
listOfStocks[i] = Stock()
listOfStocks[i].setName(stockName)
return listOfStocks
def timeFrameInit():
print('\nPlease enter the time frame in years and months (30 days)')
print("Years: ", end='')
#years = int(input())
years = 5
print(years)
print("Months: ", end='')
#months = int(input())
months = 0
print(months)
timeFrame = []
timeFrame.append(years)
timeFrame.append(months)
return timeFrame
def dataMain(listOfStocks):
print('\nGathering dates and close values')
for i in range(0, len(listOfStocks), 1):
datesAndCloseList = Stock.datesAndClose(listOfStocks[i])
listOfStocks[i].allDates = datesAndCloseList[0]
listOfStocks[i].allCloseValues = datesAndCloseList[1]
# Clip list to fit time frame
datesAndCloseList2 = Stock.datesAndClose2(listOfStocks[i])
listOfStocks[i].dates = datesAndCloseList2[0]
listOfStocks[i].closeValues = datesAndCloseList2[1]
def returnMain(benchmark, listOfStocks):
print('\nCalculating unadjusted return, Sharpe ratio, Sortino ratio, and Treynor ratio\n')
print(benchmark.name)
benchmark.unadjustedReturn = Stock.unadjustedReturn(benchmark)
# Make benchmark data global
# Maybe remove this later
Stock.benchmarkDates = benchmark.dates
Stock.benchmarkCloseValues = benchmark.closeValues
Stock.benchmarkUnadjustedReturn = benchmark.unadjustedReturn
for i in range(0, len(listOfStocks), 1):
print(listOfStocks[i].name)
# Make sure each date has a value for both the benchmark and the stock
list1 = []
list2 = []
list1.append(listOfStocks[i].dates)
list1.append(listOfStocks[i].closeValues)
list2.append(Stock.benchmarkDates)
list2.append(Stock.benchmarkCloseValues)
temp = Functions.removeExtraDatesAndCloseValues(list1, list2)
listOfStocks[i].datesMatchBenchmark = temp[0][0]
listOfStocks[i].closeValuesMatchBenchmark = temp[0][1]
benchmarkMatchDatesAndCloseValues = temp[1]
listOfStocks[i].unadjustedReturn = Stock.unadjustedReturn(
listOfStocks[i])
listOfStocks[i].beta = Stock.beta(
listOfStocks[i], benchmarkMatchDatesAndCloseValues)
def main():
# Test internet connection
internetConnection = isConnected()
if not internetConnection:
return
# Check that all required packages are installed
packagesInstalled = checkPackages()
if not packagesInstalled:
return
# Choose benchmark and makes it class Stock
benchmark = benchmarkInit()
# Add it to a list to work with other functions
benchmarkAsList = []
benchmarkAsList.append(benchmark)
# Asks for stock(s) ticker and makes them class Stock
listOfStocks = stocksInit()
# Determine time frame [Years, Months]
timeFrame = timeFrameInit()
Stock.timeFrame = timeFrame # Needs to be a global variable for all stocks
# Gather data for benchmark and stock(s)
dataMain(benchmarkAsList)
dataMain(listOfStocks)
# Calculate return for benchmark and stock(s)
returnMain(benchmark, listOfStocks)
if __name__ == "__main__":
main()
'''
from StockData import StockData from StockData import StockData
from StockReturn import Return from StockReturn import Return
@ -111,7 +565,6 @@ while indicatorFound == False:
indicatorFound = False indicatorFound = False
print('Invalid input, please enter indicator again') print('Invalid 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)

View File

@ -1,2 +1,2 @@
requests==2.21.0 requests~=2.21.0
numpy==1.15.4 numpy~=1.15.4