mirror of
https://github.com/andrewkdinh/fund-indicators.git
synced 2024-11-21 15:04:19 -08:00
Last commit
This commit is contained in:
parent
5423e4e281
commit
765b1f4012
10
README.md
10
README.md
@ -1,23 +1,17 @@
|
||||
# Mutual Fund Indicators
|
||||
|
||||
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
|
||||
|
||||
`$ pip install -r requirements.txt`
|
||||
|
||||
or
|
||||
|
||||
`$ pip install requests`
|
||||
|
||||
`$ pip install numpy`
|
||||
|
||||
### Quickstart
|
||||
|
||||
To begin, run
|
||||
|
||||
`$ python(3) main.py`
|
||||
`$ python main.py`
|
||||
|
||||
Some ticker values to try:
|
||||
SPY, VFINX, AAPL, GOOGL
|
||||
|
@ -477,6 +477,8 @@ class StockData:
|
||||
return False
|
||||
|
||||
def main(self):
|
||||
print('Beginning StockData.py')
|
||||
|
||||
import importlib.util, sys # To check whether a package is installed
|
||||
|
||||
packages = ['requests']
|
||||
@ -495,6 +497,7 @@ class StockData:
|
||||
self.allLists = []
|
||||
|
||||
print('\nNOTE: Only IEX and Alpha Vantage support adjusted returns')
|
||||
print('NOTE: Only Alpha Vantage and Tiingo support mutual fund data')
|
||||
|
||||
# IEX
|
||||
print("\nIEX")
|
||||
@ -526,7 +529,7 @@ class StockData:
|
||||
#print(self.allLists)
|
||||
#print(listOfFirstLastDates)
|
||||
if (len(self.allLists) > 0):
|
||||
print("\n")
|
||||
print("\n", end='')
|
||||
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])
|
||||
@ -541,7 +544,7 @@ class StockData:
|
||||
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")
|
||||
print("\nConverting list of final dates to datetime\n")
|
||||
self.finalDatesAndClose2 = StockData.datetimeDates(self)
|
||||
#print(self.finalDatesAndClose2[0][0])
|
||||
|
||||
|
@ -4,7 +4,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]
|
||||
listOfReturn = [Unadjusted Return, Sharpe Ratio, Sortino Ratio, Treynor Ratio, Jensen's Alpha]
|
||||
'''
|
||||
|
||||
from StockData import StockData
|
||||
@ -14,7 +14,7 @@ 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.timeFrame = newTimeFrame # [years, months (30 days)]
|
||||
self.beta = newBeta
|
||||
self.standardDeviation = newStandardDeviation
|
||||
self.negativeStandardDeviation = newNegativeStandardDeviation
|
||||
@ -23,6 +23,12 @@ class Return:
|
||||
self.sizeOfNeg = newSizeOfNeg
|
||||
self.firstLastDates = newFirstLastDates
|
||||
|
||||
def returnTimeFrame(self):
|
||||
return self.timeFrame
|
||||
|
||||
def setTimeFrame(self, newTimeFrame):
|
||||
self.timeFrame = newTimeFrame
|
||||
|
||||
def getFirstLastDates(self, stock):
|
||||
firstLastDates = []
|
||||
timeFrame = self.timeFrame
|
||||
@ -77,7 +83,6 @@ class Return:
|
||||
|
||||
def getUnadjustedReturn(self, stock):
|
||||
finalDatesAndClose = StockData.returnFinalDatesAndClose(stock)
|
||||
finalDatesAndClose2 = StockData.returnFinalDatesAndClose2(stock)
|
||||
firstDate = self.firstLastDates[0]
|
||||
lastDate = self.firstLastDates[1]
|
||||
finalDates = finalDatesAndClose[0]
|
||||
@ -91,15 +96,34 @@ class Return:
|
||||
i = len(finalDates)
|
||||
|
||||
print('Close values:', firstClose, '...', lastClose)
|
||||
unadjustedReturn = float(lastClose/firstClose)
|
||||
unadjustedReturn = unadjustedReturn * 100
|
||||
fullUnadjustedReturn = float(lastClose/firstClose)
|
||||
unadjustedReturn = fullUnadjustedReturn**(1/(self.timeFrame[0]+(self.timeFrame[1])*.1))
|
||||
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 main(self, stock):
|
||||
def mainBenchmark(self, stock):
|
||||
print('Beginning StockReturn.py')
|
||||
|
||||
# Find date to start from and last date
|
||||
self.timeFrame = []
|
||||
self.listOfReturn = []
|
||||
@ -125,8 +149,31 @@ class Return:
|
||||
print('\nGetting unadjusted return')
|
||||
unadjustedReturn = Return.getUnadjustedReturn(self, stock)
|
||||
self.listOfReturn.append(unadjustedReturn)
|
||||
print(self.listOfReturn[0])
|
||||
print(self.listOfReturn[0]/timeFrameYear, '%')
|
||||
print('Average annual return for the past', self.timeFrame[0], 'years and', self.timeFrame[1], 'months: ', end='')
|
||||
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():
|
||||
stockName = 'spy'
|
||||
@ -135,6 +182,8 @@ def main():
|
||||
StockData.main(stock1)
|
||||
|
||||
stock1Return = Return()
|
||||
Return.setTimeFrame(stock1Return, [5, 0])
|
||||
|
||||
Return.main(stock1Return, stock1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
73
main.py
73
main.py
@ -16,40 +16,83 @@ FIRST TESTING WITH EXPENSE RATIO
|
||||
'''
|
||||
|
||||
from StockData import StockData
|
||||
from StockReturn import Return
|
||||
|
||||
listOfStocks = []
|
||||
numberOfStocks = int(input("How many stocks or mutual funds would you like to analyze? "))
|
||||
listOfStocksData = []
|
||||
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):
|
||||
print("Stock", i+1, ": ", end='')
|
||||
stockName = str(input())
|
||||
listOfStocks.append(i)
|
||||
listOfStocks[i] = StockData()
|
||||
listOfStocks[i].setName(stockName)
|
||||
#print(listOfStocks[i].name)
|
||||
listOfStocksData.append(i)
|
||||
listOfStocksData[i] = StockData()
|
||||
listOfStocksData[i].setName(stockName)
|
||||
# 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
|
||||
for i in range(0, numberOfStocks, 1):
|
||||
print(listOfStocks[i].name)
|
||||
StockData.main(listOfStocks[i])
|
||||
print('\n', listOfStocksData[i].name, sep='')
|
||||
StockData.main(listOfStocksData[i])
|
||||
# Count how many stocks are available
|
||||
temp = StockData.returnAllLists(listOfStocks[i])
|
||||
sumOfListLengths = sumOfListLengths + len(temp)
|
||||
sumOfListLengths = sumOfListLengths + len(StockData.returnAllLists(listOfStocksData[i]))
|
||||
|
||||
if sumOfListLengths == 0:
|
||||
print("No sources have data for given stocks")
|
||||
exit()
|
||||
|
||||
# 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
|
||||
#print(listOfStocks[0].name, listOfStocks[0].absFirstLastDates, listOfStocks[0].finalDatesAndClose)
|
||||
# print(listOfStocksData[0].name, listOfStocksData[0].absFirstLastDates, listOfStocksData[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())
|
||||
print("1. Expense Ratio\n2. Asset Size\n3. Turnover\n4. Persistence\nWhich indicator would you like to look at? ", end='')
|
||||
|
||||
#indicator = str(input()) # CHANGE BACK TO THIS LATER
|
||||
indicator = 'Expense Ratio'
|
||||
print(indicator, end='')
|
||||
|
||||
indicatorFound = True
|
||||
print('\n', end='')
|
||||
|
||||
if indicator == 'Expense Ratio' or indicator == '1' or indicator == 'expense ratio':
|
||||
#from ExpenseRatio import ExpenseRatio
|
||||
@ -66,7 +109,7 @@ while indicatorFound == False:
|
||||
|
||||
else:
|
||||
indicatorFound = False
|
||||
print('\nInvalid input, please enter indicator again')
|
||||
print('Invalid input, please enter indicator again')
|
||||
|
||||
'''
|
||||
stockName = 'IWV'
|
||||
|
Loading…
Reference in New Issue
Block a user