@@ -23,6 +23,94 @@ def get_tiingo_symbols():
2323 return pd .read_csv (url )
2424
2525
26+ class TiingoIEXHistoricalReader (_BaseReader ):
27+ """
28+ Historical data from Tiingo on equities, ETFs and mutual funds, with re-sampling capability.
29+ This query is limited to the last 1,000 bars based in the endDate. So the startDate is moved
30+ if it goes past the limit.
31+
32+ Parameters
33+ ----------
34+ symbols : {str, List[str]}
35+ String symbol of like of symbols
36+ start : str, (defaults to '1/1/2010')
37+ Starting date, timestamp. Parses many different kind of date
38+ representations (e.g., 'JAN-01-2010', '1/1/10', 'Jan, 1, 1980')
39+ end : str, (defaults to today)
40+ Ending date, timestamp. Same format as starting date.
41+ retry_count : int, default 3
42+ Number of times to retry query request.
43+ pause : float, default 0.1
44+ Time, in seconds, of the pause between retries.
45+ session : Session, default None
46+ requests.sessions.Session instance to be used
47+ freq : {str, None}
48+ Re-sample frequency. Format is # + (min/hour); e.g. "15min" or "4hour". If no value is provided,
49+ defaults to 5min. The minimum value is "1min". Units in minutes (min) and hours (hour) are accepted.
50+ api_key : str, optional
51+ Tiingo API key . If not provided the environmental variable
52+ TIINGO_API_KEY is read. The API key is *required*.
53+ """
54+
55+ def __init__ (self , symbols , start = None , end = None , retry_count = 3 , pause = 0.1 , timeout = 30 , session = None , freq = None ,
56+ api_key = None ):
57+ super ().__init__ (symbols , start , end , retry_count , pause , timeout , session , freq )
58+
59+ if isinstance (self .symbols , str ):
60+ self .symbols = [self .symbols ]
61+ self ._symbol = ''
62+ if api_key is None :
63+ api_key = os .getenv ('TIINGO_API_KEY' )
64+ if not api_key or not isinstance (api_key , str ):
65+ raise ValueError ('The tiingo API key must be provided either '
66+ 'through the api_key variable or through the '
67+ 'environmental variable TIINGO_API_KEY.' )
68+ self .api_key = api_key
69+ self ._concat_axis = 0
70+
71+ @property
72+ def url (self ):
73+ """API URL"""
74+ _url = 'https://api.tiingo.com/iex/{ticker}/prices'
75+ return _url .format (ticker = self ._symbol )
76+
77+ @property
78+ def params (self ):
79+ """Parameters to use in API calls"""
80+ return {'startDate' : self .start .strftime ('%Y-%m-%d' ),
81+ 'endDate' : self .end .strftime ('%Y-%m-%d' ),
82+ 'resampleFreq' : self .freq ,
83+ 'format' : 'json' }
84+
85+ def _get_crumb (self , * args ):
86+ pass
87+
88+ def _read_one_data (self , url , params ):
89+ """ read one data from specified URL """
90+ headers = {'Content-Type' : 'application/json' ,
91+ 'Authorization' : 'Token ' + self .api_key }
92+ out = self ._get_response (url , params = params , headers = headers ).json ()
93+ return self ._read_lines (out )
94+
95+ def _read_lines (self , out ):
96+ df = pd .DataFrame (out )
97+ df ['symbol' ] = self ._symbol
98+ df ['date' ] = pd .to_datetime (df ['date' ])
99+ df = df .set_index (['symbol' , 'date' ])
100+ return df
101+
102+ def read (self ):
103+ """Read data from connector"""
104+ dfs = []
105+ for symbol in self .symbols :
106+ self ._symbol = symbol
107+ try :
108+ dfs .append (self ._read_one_data (self .url , self .params ))
109+ finally :
110+ self .close ()
111+ return pd .concat (dfs , self ._concat_axis )
112+
113+
26114class TiingoDailyReader (_BaseReader ):
27115 """
28116 Historical daily data from Tiingo on equities, ETFs and mutual funds
0 commit comments