@@ -23,6 +23,94 @@ def get_tiingo_symbols():
23
23
return pd .read_csv (url )
24
24
25
25
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
+
26
114
class TiingoDailyReader (_BaseReader ):
27
115
"""
28
116
Historical daily data from Tiingo on equities, ETFs and mutual funds
0 commit comments