-
Notifications
You must be signed in to change notification settings - Fork 0
/
fi.py
119 lines (102 loc) · 3.5 KB
/
fi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import json
import numpy as np
from yahoo import yahoo_url, historical_url
from stock import Stock
from datetime import date, timedelta
import threading
lock = threading.Lock()
def request_json(url, gae=True):
'''
Abstraction of making the call to the url
'''
data = None
try:
from google.appengine.api import urlfetch
urlfetch.set_default_fetch_deadline(30)
response = urlfetch.fetch(url)
if response.status_code >= 500:
raise Exception('Error on yahoo server', response.msg)
if response.status_code >= 400:
raise Exception('Error in call formatting', response.msg)
response_string = response.content
data = json.loads(response_string)
except:
import urllib2
response = urllib2.urlopen(url)
if response.getcode() >= 500:
raise Exception('Error on yahoo server', response.msg)
if response.getcode() >= 400:
raise Exception('Error in call formatting', response.msg)
response_string = response.read()
data = json.loads(response_string)
return data
def create_stock(quote, max_iterations, start, end, stocks, index):
'''
Create a stock from a quote
'''
if (quote['StockExchange'] == None):
return
success = False
for i in range(max_iterations):
if not success:
url = historical_url(quote['symbol'], start, end)
data = request_json(url)
if 'error' in data and i == (max_iterations-1):
raise Exception('Error in call to historical api',
data)
elif 'error' not in data:
success = True
quotes = data['query']['results']['quote']
close_prices = [float(q['Close']) for q in quotes]
stock = Stock(quote, close_prices)
stock.index = index
lock.acquire()
stocks.append(stock)
lock.release()
def parallel_stocks(quotes, time, max_iterations):
'''
Calculate the stock information in parallel
The way it is currently implemented, it does not keep stocks in order
of how they are called
'''
stocks = []
start_date = date.today() - timedelta(time)
start = start_date.strftime("%Y-%m-%d")
end = date.today().strftime("%Y-%m-%d")
threads = []
i = 0
for quote in quotes:
i += 1
args = [quote, max_iterations, start, end, stocks, i]
thread = threading.Thread(target=create_stock, args=args)
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
stocks.sort(key=lambda s: s.index)
return stocks
def get_info(symbols, time=30, max_iterations=5):
'''
Takes a list of symbols as input and outputs an array of
stock objects. Stock information goes back time days. Since
Yahoo API is not always reliable, allow up to max_iterations
calls to the API
'''
if len(symbols) == 0:
return []
symbols = symbols[:30]
url = yahoo_url(symbols)
data = request_json(url)
if 'error' in data:
raise Exception('Error in call to yahoo', data['error']['description'])
quotes = data['query']['results']['quote']
if (type(quotes) != list):
quotes = [quotes]
stocks = parallel_stocks(quotes, time, max_iterations)
return stocks
def get_correlation_matrix(input):
stocks = input
if type(stocks[0]) == str:
stocks = get_info(stocks)
prices = [s.recent_close_prices*1.0 for s in stocks]
return np.corrcoef(prices).round(4)