Add async function

This commit is contained in:
Andrew Dinh 2019-02-21 11:43:46 -08:00
parent d398924c0d
commit 531c41862a
6 changed files with 87 additions and 69 deletions

3
.gitignore vendored
View File

@ -1,6 +1,5 @@
__pycache__/StockData.cpython-37.pyc
__pycache__/ __pycache__/
*.pyc
test/ test/
.vscode/ .vscode/
requests_cache.sqlite requests_cache.sqlite
README.html

View File

@ -42,6 +42,7 @@ def stringIsInt(s):
except ValueError: except ValueError:
return False return False
def strintIsFloat(s): def strintIsFloat(s):
try: try:
float(s) float(s)
@ -49,10 +50,13 @@ def strintIsFloat(s):
except ValueError: except ValueError:
return False return False
def fromCache(r): def fromCache(r):
import requests_cache import requests_cache
if r.from_cache == True: if r.from_cache == True:
print('(Response taken from cache)') print('(Response taken from cache)')
return
def main(): def main():
exit() exit()

View File

@ -1,19 +1,25 @@
# Mutual Fund Indicators # Mutual Fund Indicators
A project to determine indicators of overperforming mutual funds. [![License](https://img.shields.io/github/license/andrewkdinh/fund-indicators.svg)](https://raw.githubusercontent.com/andrewkdinh/fund-indicators/master/LICENSE)
This project is written in Python 3 and will examine market capitalization, persistence, turnover, and expense ratios. ![](https://img.shields.io/github/last-commit/andrewkdinh/fund-indicators.svg)
![](https://img.shields.io/github/languages/top/andrewkdinh/fund-indicators.svg)
![](https://img.shields.io/github/languages/code-size/andrewkdinh/fund-indicators.svg)
### Prerequisites A project to determine indicators of overperforming mutual funds.
Examine correlation between performance and market capitalization, persistence, turnover, and expense ratios.
## Prerequisites
`$ pip install -r requirements.txt` `$ pip install -r requirements.txt`
### Quickstart ## Quickstart
To begin, run To begin, run
`$ python main.py` `$ python main.py`
Some ticker values to try: Some ticker values to try:
SPY, VFINX, AAPL, GOOGL SPY, VFINX, VTHR, DJIA
Created by Andrew Dinh from Dr. TJ Owens Gilroy Early College Academy Created by Andrew Dinh from Dr. TJ Owens Gilroy Early College Academy

80
main.py
View File

@ -4,6 +4,7 @@
# Python 3.6.7 # Python 3.6.7
# Required # Required
from concurrent.futures import ThreadPoolExecutor as PoolExecutor
import requests import requests
import json import json
import datetime import datetime
@ -16,10 +17,10 @@ import sys
# Optional # Optional
import requests_cache import requests_cache
# https://requests-cache.readthedocs.io/en/lates/user_guide.html
requests_cache.install_cache( requests_cache.install_cache(
'requests_cache', backend='sqlite', expire_after=43200) # 12 hours 'requests_cache', backend='sqlite', expire_after=43200) # 12 hours
# API Keys # API Keys
apiAV = 'O42ICUV58EIZZQMU' apiAV = 'O42ICUV58EIZZQMU'
# apiBarchart = 'a17fab99a1c21cd6f847e2f82b592838' # apiBarchart = 'a17fab99a1c21cd6f847e2f82b592838'
@ -119,7 +120,7 @@ class Stock:
f = requests.get(url) f = requests.get(url)
Functions.fromCache(f) Functions.fromCache(f)
json_data = f.text json_data = f.text
if json_data == 'Unknown symbol' or f.status_code == 404: if json_data == 'Unknown symbol' or f.status_code != 200:
print("IEX not available") print("IEX not available")
return 'Not available' return 'Not available'
loaded_json = json.loads(json_data) loaded_json = json.loads(json_data)
@ -160,7 +161,7 @@ class Stock:
json_data = f.text json_data = f.text
loaded_json = json.loads(json_data) loaded_json = json.loads(json_data)
if len(loaded_json) == 1 or f.status_code == 404: if len(loaded_json) == 1 or f.status_code != 200:
print("Alpha Vantage not available") print("Alpha Vantage not available")
return 'Not available' return 'Not available'
@ -195,7 +196,7 @@ class Stock:
f = requests.get(url, headers=headers) f = requests.get(url, headers=headers)
Functions.fromCache(f) Functions.fromCache(f)
loaded_json = f.json() loaded_json = f.json()
if len(loaded_json) == 1 or f.status_code == 404 or loaded_json['startDate'] == None: if len(loaded_json) == 1 or f.status_code != 200 or loaded_json['startDate'] == None:
print("Tiingo not available") print("Tiingo not available")
return 'Not available' return 'Not available'
@ -497,11 +498,11 @@ def datesToDays(dates):
def isConnected(): def isConnected():
import socket # To check internet connection import socket # To check internet connection
print('Checking internet connection') #print('Checking internet connection')
try: try:
# connect to the host -- tells us if the host is actually reachable # connect to the host -- tells us if the host is actually reachable
socket.create_connection(("www.andrewkdinh.com", 80)) socket.create_connection(("www.andrewkdinh.com", 80))
print('Internet connection is good!') print('Internet connection is good')
return True return True
except OSError: except OSError:
# pass # pass
@ -526,6 +527,22 @@ def checkPackages():
return packagesInstalled return packagesInstalled
def checkPythonVersion():
import platform
#print('Checking Python version')
i = platform.python_version()
r = i.split('.')
k = ''.join((r[0], '.', r[1]))
k = float(k)
if k < 3.3:
print('Your Python version is', i,
'\nIt needs to be greater than version 3.3')
return False
else:
print('Your Python version of', i, 'is good')
return True
def benchmarkInit(): def benchmarkInit():
# Treat benchmark like stock # Treat benchmark like stock
benchmarkTicker = '' benchmarkTicker = ''
@ -601,11 +618,45 @@ def stocksInit():
return listOfStocks return listOfStocks
def asyncData(benchmark, listOfStocks):
# Make list of urls to send requests to
urlList = []
# Benchmark
url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=',
benchmark.name, '&outputsize=full&apikey=', apiAV))
urlList.append(url)
# Stocks
for i in range(0, len(listOfStocks), 1):
# Alpha Vantage
url = ''.join(('https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol=',
listOfStocks[i].name, '&outputsize=full&apikey=', apiAV))
urlList.append(url)
# Risk-free rate
url = ''.join(
('https://www.quandl.com/api/v3/datasets/USTREASURY/LONGTERMRATES.json?api_key=', apiQuandl))
urlList.append(url)
# Send async requests
print('\nSending async requests (Assuming Alpha Vantage is first choice)')
with PoolExecutor(max_workers=3) as executor:
for _ in executor.map(sendAsync, urlList):
pass
return
def sendAsync(url):
requests.get(url)
return
def timeFrameInit(): def timeFrameInit():
isInteger = False isInteger = False
while isInteger == False: while isInteger == False:
print( print(
'\nPlease enter the time frame in years (10 years or less recommended):', end='') '\nPlease enter the time frame in years (<10 years recommended):', end='')
temp = input(' ') temp = input(' ')
isInteger = Functions.stringIsInt(temp) isInteger = Functions.stringIsInt(temp)
if isInteger == True: if isInteger == True:
@ -660,7 +711,7 @@ def riskFreeRate():
riskFreeRate = round(riskFreeRate, 2) riskFreeRate = round(riskFreeRate, 2)
print('Risk-free rate:', riskFreeRate, end='\n\n') print('Risk-free rate:', riskFreeRate, end='\n\n')
if f.status_code == 404: if f.status_code != 200:
print("Quandl not available") print("Quandl not available")
print('Returning 2.50 as risk-free rate', end='\n\n') print('Returning 2.50 as risk-free rate', end='\n\n')
# return 0.0250 # return 0.0250
@ -950,12 +1001,18 @@ def main():
packagesInstalled = checkPackages() packagesInstalled = checkPackages()
if not packagesInstalled: if not packagesInstalled:
return return
else:
print('All required packages are installed')
# Check python version is above 3.3
pythonVersionGood = checkPythonVersion()
if not pythonVersionGood:
return
# Choose benchmark and makes it class Stock # Choose benchmark and makes it class Stock
benchmark = benchmarkInit() benchmark = benchmarkInit()
# Add it to a list to work with other functions # Add it to a list to work with other functions
benchmarkAsList = [] benchmarkAsList = [benchmark]
benchmarkAsList.append(benchmark)
# Asks for stock(s) ticker and makes them class Stock # Asks for stock(s) ticker and makes them class Stock
listOfStocks = stocksInit() listOfStocks = stocksInit()
@ -964,6 +1021,9 @@ def main():
timeFrame = timeFrameInit() timeFrame = timeFrameInit()
Stock.timeFrame = timeFrame # Needs to be a global variable for all stocks Stock.timeFrame = timeFrame # Needs to be a global variable for all stocks
# Send async request to AV for listOfStocks and benchmark
asyncData(benchmark, listOfStocks)
# Gather data for benchmark and stock(s) # Gather data for benchmark and stock(s)
dataMain(benchmarkAsList) dataMain(benchmarkAsList)
dataMain(listOfStocks) dataMain(listOfStocks)

View File

@ -1,51 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="/cdn-cgi/apps/head/GA7wuz-FE88SDVynGgn9Aq5W6rI.js"></script><link rel="apple-touch-icon" sizes="57x57" href="/images/logo/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/images/logo/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/images/logo/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/images/logo/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/images/logo/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/images/logo/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/images/logo/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/images/logo/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/images/logo/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/images/logo/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/logo/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/images/logo/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/logo/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/images/logo/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
<title>Andrew Dinh</title>
<meta name="description" content="Andrew Dinh is a young professional delving into the world of computer science to expand financial literacy." />
<meta name="keywords" content="Andrew Dinh, Andrew K Dinh, Gilroy, GECA, Gavilan College, Dr. TJ Owens Gilroy Early College Academy, computer science" />
<meta property="og:title" content="Andrew Dinh" />
<meta property="og:description" content="A young professional delving into the world of computer science to expand financial literacy" />
<meta property="og:image" content="/images/profile.jpg" />
<meta name="apple-mobile-web-app-capable" content="yes">
<script>(function(a,b,c){if(c in b&&b[c]){var d,e=a.location,f=/^(a|html)$/i;a.addEventListener("click",function(a){d=a.target;while(!f.test(d.nodeName))d=d.parentNode;"href"in d&&(chref=d.href).replace(e.href,"").indexOf("#")&&(!/^[a-z\+\.\-]+:/i.test(chref)||chref.indexOf(e.protocol+"//"+e.host)===0)&&(a.preventDefault(),e.href=d.href)},!1)}})(document,window.navigator,"standalone");</script>
<script> function myFunction() {var x = document.getElementById("myTopnav");if (x.className === "topnav") {x.className += " responsive";} else {x.className = "topnav";}}</script>
<script>window.onload=function(){function a(a,b){var c=/^(?:file):/,d=new XMLHttpRequest,e=0;d.onreadystatechange=function(){4==d.readyState&&(e=d.status),c.test(location.href)&&d.responseText&&(e=200),4==d.readyState&&200==e&&(a.outerHTML=d.responseText)};try{d.open("GET",b,!0),d.send()}catch(f){}}var b,c=document.getElementsByTagName("*");for(b in c)c[b].hasAttribute&&c[b].hasAttribute("data-include")&&a(c[b],c[b].getAttribute("data-include"))};</script>
<link rel="stylesheet preload" title="classic" href="/css/general.css" media="screen" />
</head>
<body>
<div data-include="/html/menu.html"></div>
<main>
</main>
</body>
</html>

View File