Skip to content

Commit 2ba136f

Browse files
committed
fixed yahoo->google finance
1 parent 5951003 commit 2ba136f

File tree

3 files changed

+30
-29
lines changed

3 files changed

+30
-29
lines changed

docs/book_numerical.pdf

-577 KB
Binary file not shown.

docs/book_numerical.tex

+8-11
Original file line numberDiff line numberDiff line change
@@ -1767,8 +1767,8 @@ \section*{Acknowledgments}
17671767
but Yahoo changed API and blocked them, moving to Google finance.
17681768
"""
17691769
URL_CURRENT = 'http://finance.yahoo.com/d/quotes.csv?s=%(symbol)s&f=%(columns)s'
1770-
URL_HISTORICAL = 'https://www.google.com/finance/historical?output=csv&q=%s'
1771-
'
1770+
URL_HISTORICAL = 'https://www.google.com/finance/historical?output=csv&q=%(symbol)s'
1771+
17721772
def __init__(self,symbol):
17731773
self.symbol = symbol.upper()
17741774

@@ -1805,14 +1805,9 @@ \section*{Acknowledgments}
18051805
current[row[0]] = raw_data[i]
18061806
return current
18071807

1808-
def historical(self,start=None, stop=None):
1808+
def historical(self, start=None, stop=None):
18091809
import datetime, time, urllib, math
1810-
start = start or datetime.date(1900,1,1)
1811-
stop = stop or datetime.date.today()
1812-
url = self.URL_HISTORICAL % dict(
1813-
s=self.symbol,
1814-
a=start.month-1,b=start.day,c=start.year,
1815-
d=stop.month-1,e=stop.day,f=stop.year)
1810+
url = self.URL_HISTORICAL % dict(symbol=self.symbol)
18161811
# Date,Open,High,Low,Close,Volume,Adj Close
18171812
lines = urllib.urlopen(url).readlines()
18181813
if any('CAPTCHA' in line for line in lines):
@@ -1824,6 +1819,8 @@ \section*{Acknowledgments}
18241819
raw_data.reverse()
18251820
for row in raw_data:
18261821
if row[1] == '-': continue
1822+
date = datetime.datetime.strptime(row[0],'%d-%b-%y')
1823+
if (start and date<start) or (stop and date>stop): continue
18271824
open, high, low = float(row[1]), float(row[2]), float(row[3])
18281825
close, vol = float(row[4]), float(row[5])
18291826
adjusted_close = float(row[5]) if len(row)>5 else close
@@ -1836,7 +1833,7 @@ \section*{Acknowledgments}
18361833
arithmetic_return = log_return = None
18371834
previous_adjusted_close = adjusted_close
18381835
series.append(dict(
1839-
date = datetime.datetime.strptime(row[0],'%Y-%m-%d'),
1836+
date = date,
18401837
open = open,
18411838
high = high,
18421839
low = low,
@@ -1853,7 +1850,7 @@ \section*{Acknowledgments}
18531850

18541851
@staticmethod
18551852
def download(symbol='goog',what='adjusted_close',start=None,stop=None):
1856-
return [d[what] for d in YStock(symbol).historical(start,stop)]
1853+
return [d[what] for d in YStock(symbol).historical(start, stop)]
18571854
\end{lstlisting}
18581855

18591856
Many web services return data in JSON format. JSON is slowly replacing XML as a favorite protocol for data transfer on the web. It is lighter, simpler to use, and more human readable. JSON can be thought of as serialized JavaScript. the JSON data can be converted to a Python object using a library called {\ft json}:

nlib.py

+22-18
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ class YStock:
1313
>>> h = google.historical()
1414
>>> last_adjusted_close = h[-1]['adjusted_close']
1515
>>> last_log_return = h[-1]['log_return']
16+
previous version of this code user Yahoo for historical data
17+
but Yahoo changed API and blocked them, moving to Google finance.
1618
"""
1719
URL_CURRENT = 'http://finance.yahoo.com/d/quotes.csv?s=%(symbol)s&f=%(columns)s'
18-
URL_HISTORICAL = 'http://ichart.yahoo.com/table.csv?s=%(s)s&a=%(a)s&b=%(b)s&c=%(c)s&d=%(d)s&e=%(e)s&f=%(f)s'
20+
URL_HISTORICAL = 'https://www.google.com/finance/historical?output=csv&q=%(symbol)s'
21+
1922
def __init__(self,symbol):
2023
self.symbol = symbol.upper()
2124

@@ -52,24 +55,25 @@ def current(self):
5255
current[row[0]] = raw_data[i]
5356
return current
5457

55-
def historical(self,start=None, stop=None):
58+
def historical(self, start=None, stop=None):
5659
import datetime, time, urllib, math
57-
start = start or datetime.date(1900,1,1)
58-
stop = stop or datetime.date.today()
59-
url = self.URL_HISTORICAL % dict(
60-
s=self.symbol,
61-
a=start.month-1,b=start.day,c=start.year,
62-
d=stop.month-1,e=stop.day,f=stop.year)
60+
url = self.URL_HISTORICAL % dict(symbol=self.symbol)
6361
# Date,Open,High,Low,Close,Volume,Adj Close
6462
lines = urllib.urlopen(url).readlines()
65-
raw_data = [row.split(',') for row in lines[1:] if row.count(',')==6]
63+
if any('CAPTCHA' in line for line in lines):
64+
print url
65+
raise
66+
raw_data = [row.split(',') for row in lines[1:] if 5 <= row.count(',') <= 6]
6667
previous_adjusted_close = 0
6768
series = []
6869
raw_data.reverse()
6970
for row in raw_data:
71+
if row[1] == '-': continue
72+
date = datetime.datetime.strptime(row[0],'%d-%b-%y')
73+
if (start and date<start) or (stop and date>stop): continue
7074
open, high, low = float(row[1]), float(row[2]), float(row[3])
7175
close, vol = float(row[4]), float(row[5])
72-
adjusted_close = float(row[6])
76+
adjusted_close = float(row[5]) if len(row)>5 else close
7377
adjustment = adjusted_close/close
7478
if previous_adjusted_close:
7579
arithmetic_return = adjusted_close/previous_adjusted_close-1.0
@@ -79,7 +83,7 @@ def historical(self,start=None, stop=None):
7983
arithmetic_return = log_return = None
8084
previous_adjusted_close = adjusted_close
8185
series.append(dict(
82-
date = datetime.datetime.strptime(row[0],'%Y-%m-%d'),
86+
date = date,
8387
open = open,
8488
high = high,
8589
low = low,
@@ -96,7 +100,7 @@ def historical(self,start=None, stop=None):
96100

97101
@staticmethod
98102
def download(symbol='goog',what='adjusted_close',start=None,stop=None):
99-
return [d[what] for d in YStock(symbol).historical(start,stop)]
103+
return [d[what] for d in YStock(symbol).historical(start, stop)]
100104

101105
import os
102106
import uuid
@@ -1093,7 +1097,7 @@ def eval_fitting_function(f,c,x):
10931097
weight = 1.0/points[i][2] if len(points[i])>2 else 1.0
10941098
b[i,0] = weight*float(points[i][1])
10951099
for j in xrange(A.ncols):
1096-
A[i,j] = weight*f[j](points[i][0])
1100+
A[i,j] = weight*f[j](float(points[i][0]))
10971101
c = (1.0/(A.T*A))*(A.T*b)
10981102
chi = A*c-b
10991103
chi2 = norm(chi,2)**2
@@ -1447,7 +1451,7 @@ def optimize_newton_multi(f, x, ap=1e-6, rp=1e-4, ns=20):
14471451
if k>2 and norm(x-x_old)<max(ap,norm(x)*rp): return x.flatten()
14481452
raise ArithmeticError('no convergence')
14491453

1450-
def optimize_newton_multi_imporved(f, x, ap=1e-6, rp=1e-4, ns=20, h=10.0):
1454+
def optimize_newton_multi_improved(f, x, ap=1e-6, rp=1e-4, ns=20, h=10.0):
14511455
"""
14521456
Finds the extreme of multidimensional function f near point x.
14531457
@@ -1482,7 +1486,7 @@ def g(b, data=data, f=fs, constraint=constraint):
14821486
if constraint: chi2+=constraint(b)
14831487
return chi2
14841488
if isinstance(b,(list,tuple)):
1485-
b = optimize_newton_multi_imporved(g,b,ap,rp,ns)
1489+
b = optimize_newton_multi_improved(g,b,ap,rp,ns)
14861490
else:
14871491
b = optimize_newton(g,b,ap,rp,ns)
14881492
return b, g(b,data,constraint=None)
@@ -1503,7 +1507,7 @@ def g(b,data=data,fs=fs,constraint=constraint):
15031507
if constraint:
15041508
chi += constraint(b)
15051509
return chi2
1506-
b = optimize_newton_multi_imporved(g,b,ap,rp,ns)
1510+
b = optimize_newton_multi_improved(g,b,ap,rp,ns)
15071511
a, chi2 = core(b,data,fs)
15081512
return a+b,chi2
15091513

@@ -1572,7 +1576,7 @@ def next(self):
15721576
def random(self):
15731577
return float(self.next())/self.m
15741578

1575-
class MarsenneTwister(object):
1579+
class MersenneTwister(object):
15761580
"""
15771581
based on:
15781582
Knuth 1981, The Art of Computer Programming
@@ -2590,4 +2594,4 @@ def test132():
25902594
if __name__=='__main__':
25912595
import os,doctest
25922596
if not os.path.exists('images'): os.mkdir('images')
2593-
doctest.testmod(optionflags=doctest.ELLIPSIS)
2597+
doctest.testmod(optionflags=doctest.ELLIPSIS)

0 commit comments

Comments
 (0)