Last commit

This commit is contained in:
Andrew Dinh 2019-01-30 08:18:34 -08:00
parent 5423e4e281
commit 765b1f4012
4 changed files with 123 additions and 34 deletions

View File

@ -1,23 +1,17 @@
# Mutual Fund Indicators # Mutual Fund Indicators
A project to determine indicators of overperforming mutual funds. 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. This project is written in Python 3 and will examine market capitalization, persistence, turnover, and expense ratios.
### Prerequisites ### Prerequisites
`$ pip install -r requirements.txt` `$ pip install -r requirements.txt`
or
`$ pip install requests`
`$ pip install numpy`
### Quickstart ### Quickstart
To begin, run To begin, run
`$ python(3) main.py` `$ python main.py`
Some ticker values to try: Some ticker values to try:
SPY, VFINX, AAPL, GOOGL SPY, VFINX, AAPL, GOOGL

View File

@ -477,6 +477,8 @@ class StockData:
return False return False
def main(self): def main(self):
print('Beginning StockData.py')
import importlib.util, sys # To check whether a package is installed import importlib.util, sys # To check whether a package is installed
packages = ['requests'] packages = ['requests']
@ -495,6 +497,7 @@ class StockData:
self.allLists = [] self.allLists = []
print('\nNOTE: Only IEX and Alpha Vantage support adjusted returns') print('\nNOTE: Only IEX and Alpha Vantage support adjusted returns')
print('NOTE: Only Alpha Vantage and Tiingo support mutual fund data')
# IEX # IEX
print("\nIEX") print("\nIEX")
@ -526,7 +529,7 @@ class StockData:
#print(self.allLists) #print(self.allLists)
#print(listOfFirstLastDates) #print(listOfFirstLastDates)
if (len(self.allLists) > 0): if (len(self.allLists) > 0):
print("\n") 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(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])
@ -541,7 +544,7 @@ class StockData:
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") print("\nConverting list of final dates to datetime\n")
self.finalDatesAndClose2 = StockData.datetimeDates(self) self.finalDatesAndClose2 = StockData.datetimeDates(self)
#print(self.finalDatesAndClose2[0][0]) #print(self.finalDatesAndClose2[0][0])

View File

@ -4,7 +4,7 @@
# Description: # Description:
''' '''
Calculates return for each stock from the lists from ExpenseRatio.py Calculates return for each stock from the lists from ExpenseRatio.py
listOfReturn = [Unadjsted Return, Sharpe Ratio, Sortino Ratio, Treynor Ratio, Jensen's Alpha] listOfReturn = [Unadjusted Return, Sharpe Ratio, Sortino Ratio, Treynor Ratio, Jensen's Alpha]
''' '''
from StockData import StockData from StockData import StockData
@ -14,7 +14,7 @@ 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
self.timeFrame = newTimeFrame # [year, months (30 days)] self.timeFrame = newTimeFrame # [years, months (30 days)]
self.beta = newBeta self.beta = newBeta
self.standardDeviation = newStandardDeviation self.standardDeviation = newStandardDeviation
self.negativeStandardDeviation = newNegativeStandardDeviation self.negativeStandardDeviation = newNegativeStandardDeviation
@ -23,6 +23,12 @@ class Return:
self.sizeOfNeg = newSizeOfNeg self.sizeOfNeg = newSizeOfNeg
self.firstLastDates = newFirstLastDates self.firstLastDates = newFirstLastDates
def returnTimeFrame(self):
return self.timeFrame
def setTimeFrame(self, newTimeFrame):
self.timeFrame = newTimeFrame
def getFirstLastDates(self, stock): def getFirstLastDates(self, stock):
firstLastDates = [] firstLastDates = []
timeFrame = self.timeFrame timeFrame = self.timeFrame
@ -77,7 +83,6 @@ class Return:
def getUnadjustedReturn(self, stock): def getUnadjustedReturn(self, stock):
finalDatesAndClose = StockData.returnFinalDatesAndClose(stock) finalDatesAndClose = StockData.returnFinalDatesAndClose(stock)
finalDatesAndClose2 = StockData.returnFinalDatesAndClose2(stock)
firstDate = self.firstLastDates[0] firstDate = self.firstLastDates[0]
lastDate = self.firstLastDates[1] lastDate = self.firstLastDates[1]
finalDates = finalDatesAndClose[0] finalDates = finalDatesAndClose[0]
@ -91,15 +96,34 @@ class Return:
i = len(finalDates) i = len(finalDates)
print('Close values:', firstClose, '...', lastClose) print('Close values:', firstClose, '...', lastClose)
unadjustedReturn = float(lastClose/firstClose) fullUnadjustedReturn = float(lastClose/firstClose)
unadjustedReturn = unadjustedReturn * 100 unadjustedReturn = fullUnadjustedReturn**(1/(self.timeFrame[0]+(self.timeFrame[1])*.1))
return unadjustedReturn return unadjustedReturn
# def getBeta(self, timeFrame): def getBeta(self):
# Can be calculated with correlation
import numpy as np
finalDatesAndClose = StockData.returnFinalDatesAndClose(stock)
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]
55ggbh
#list1 =
list2 = [1,2,4,1]
print(numpy.corrcoef(list1, list2)[0, 1])
# def getStandardDeviation(self, timeFrame): # def getStandardDeviation(self, timeFrame):
def main(self, stock): def mainBenchmark(self, stock):
print('Beginning StockReturn.py')
# Find date to start from and last date # Find date to start from and last date
self.timeFrame = [] self.timeFrame = []
self.listOfReturn = [] self.listOfReturn = []
@ -125,8 +149,31 @@ 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(self.listOfReturn[0]) print('Average annual return for the past', self.timeFrame[0], 'years and', self.timeFrame[1], 'months: ', end='')
print(self.listOfReturn[0]/timeFrameYear, '%') print((self.listOfReturn[0]-1)*100, '%', sep='')
def main(self, stock):
print('Beginning StockReturn.py')
# Find date to start from and last date
self.listOfReturn = []
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')
unadjustedReturn = Return.getUnadjustedReturn(self, stock)
self.listOfReturn.append(unadjustedReturn)
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('\nGetting beta')
#beta = Return.getBeta(self, stock)
def main(): def main():
stockName = 'spy' stockName = 'spy'
@ -135,6 +182,8 @@ def main():
StockData.main(stock1) StockData.main(stock1)
stock1Return = Return() stock1Return = Return()
Return.setTimeFrame(stock1Return, [5, 0])
Return.main(stock1Return, stock1) Return.main(stock1Return, stock1)
if __name__ == "__main__": if __name__ == "__main__":

73
main.py
View File

@ -16,40 +16,83 @@ FIRST TESTING WITH EXPENSE RATIO
''' '''
from StockData import StockData from StockData import StockData
from StockReturn import Return
listOfStocks = [] listOfStocksData = []
numberOfStocks = int(input("How many stocks or mutual funds would you like to analyze? ")) listOfStocksReturn = []
#numberOfStocks = int(input("How many stocks or mutual funds would you like to analyze? ")) # CHANGE BACK LATER
numberOfStocks = 1
for i in range(0, numberOfStocks, 1): 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) listOfStocksData.append(i)
listOfStocks[i] = StockData() listOfStocksData[i] = StockData()
listOfStocks[i].setName(stockName) listOfStocksData[i].setName(stockName)
#print(listOfStocks[i].name) # print(listOfStocksData[i].name)
#listOfStocksReturn.append(i)
#listOfStocksReturn[i] = StockReturn()
# Decide on a benchmark
benchmarkTicker = ''
while benchmarkTicker == '':
listOfBenchmarks = ['S&P500', 'DJIA', 'Russell 3000', 'MSCI EAFE']
listOfBenchmarksTicker = ['SPY', 'DJIA', 'VTHR', 'EFT']
print('\nList of benchmarks:', listOfBenchmarks)
#benchmark = str(input('Benchmark to compare to: '))
benchmark = 'S&P500'
for i in range(0,len(listOfBenchmarks), 1):
if benchmark == listOfBenchmarks[i]:
benchmarkTicker = listOfBenchmarksTicker[i]
i = len(listOfBenchmarks)
if benchmarkTicker == '':
print('Benchmark not found. Please type in a benchmark from the list')
print('\n', benchmark, ' (', benchmarkTicker, ')', sep='')
benchmarkName = str(benchmark)
benchmark = StockData()
benchmark.setName(benchmarkName)
StockData.main(benchmark)
benchmarkReturn = Return()
Return.mainBenchmark(benchmarkReturn, benchmark)
timeFrame = Return.returnTimeFrame(benchmarkReturn)
print('Time Frame [years, months]:', timeFrame)
sumOfListLengths = 0 sumOfListLengths = 0
for i in range(0, numberOfStocks, 1): for i in range(0, numberOfStocks, 1):
print(listOfStocks[i].name) print('\n', listOfStocksData[i].name, sep='')
StockData.main(listOfStocks[i]) StockData.main(listOfStocksData[i])
# Count how many stocks are available # Count how many stocks are available
temp = StockData.returnAllLists(listOfStocks[i]) sumOfListLengths = sumOfListLengths + len(StockData.returnAllLists(listOfStocksData[i]))
sumOfListLengths = sumOfListLengths + len(temp)
if sumOfListLengths == 0: if sumOfListLengths == 0:
print("No sources have data for given stocks") print("No sources have data for given stocks")
exit() exit()
# Find return over time using either Jensen's Alpha, Sharpe Ratio, Sortino Ratio, or Treynor Ratio # Find return over time using either Jensen's Alpha, Sharpe Ratio, Sortino Ratio, or Treynor Ratio
#from StockReturn import Return for i in range(0, numberOfStocks, 1):
print('\n', listOfStocksData[i].name, sep='')
#StockReturn.main(listOfStocksReturn[i])
# Runs correlation or regression study # Runs correlation or regression study
#print(listOfStocks[0].name, listOfStocks[0].absFirstLastDates, listOfStocks[0].finalDatesAndClose) # print(listOfStocksData[0].name, listOfStocksData[0].absFirstLastDates, listOfStocksData[0].finalDatesAndClose)
indicatorFound = False indicatorFound = False
while 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='') print("1. Expense Ratio\n2. Asset Size\n3. Turnover\n4. Persistence\nWhich indicator would you like to look at? ", end='')
indicator = str(input())
#indicator = str(input()) # CHANGE BACK TO THIS LATER
indicator = 'Expense Ratio'
print(indicator, end='')
indicatorFound = True indicatorFound = True
print('\n', end='')
if indicator == 'Expense Ratio' or indicator == '1' or indicator == 'expense ratio': if indicator == 'Expense Ratio' or indicator == '1' or indicator == 'expense ratio':
#from ExpenseRatio import ExpenseRatio #from ExpenseRatio import ExpenseRatio
@ -66,7 +109,7 @@ while indicatorFound == False:
else: else:
indicatorFound = False indicatorFound = False
print('\nInvalid input, please enter indicator again') print('Invalid input, please enter indicator again')
''' '''
stockName = 'IWV' stockName = 'IWV'