mirror of
https://github.com/hydrosquall/tiingo-python.git
synced 2025-12-17 11:54:19 +01:00
Initial commit
This commit is contained in:
@@ -125,6 +125,8 @@ To receive results in ``pandas`` format, use the ``get_dataframe()`` method:
|
||||
endDate='2018-05-31')
|
||||
|
||||
|
||||
You can specify any of the end of day frequencies (daily, weekly, monthly, and annually) or any intraday frequency for both the ``get_ticker_price`` and ``get_dataframe`` methods. Weekly frequencies resample to the end of day on Friday, monthly frequencies resample to the last day of the month, and annually frequencies resample to the end of day on 12-31 of each year. The intraday frequencies are specified using an integer followed by "Min" or "Hour", for example "30Min" or "1Hour".
|
||||
|
||||
Further Docs
|
||||
--------
|
||||
|
||||
|
||||
24
tests/fixtures/intraday_price.yaml
vendored
Normal file
24
tests/fixtures/intraday_price.yaml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: null
|
||||
headers:
|
||||
Accept: ['*/*']
|
||||
Accept-Encoding: ['gzip, deflate']
|
||||
Authorization: [Token 0000000000000000000000000000000000000000]
|
||||
Connection: [keep-alive]
|
||||
Content-Type: [application/json]
|
||||
User-Agent: [tiingo-python-client 0.6.0]
|
||||
method: GET
|
||||
uri: https://api.tiingo.com/iex/GOOGL/prices?format=json&resampleFreq=30Min&startDate=2018-01-02&endDate=2018-01-02
|
||||
response:
|
||||
body: {string: '[{"date":"2018-01-02T14:30:00.000Z","open":1057.47,"high":1061.91,"low":1054.17,"close":1061.91},{"date":"2018-01-02T15:00:00.000Z","open":1061.91,"high":1067.345,"low":1061.91,"close":1066.945},{"date":"2018-01-02T15:30:00.000Z","open":1067.29,"high":1070.47,"low":1065.71,"close":1070.26},{"date":"2018-01-02T16:00:00.000Z","open":1071.355,"high":1073.775,"low":1070.235,"close":1073.26},{"date":"2018-01-02T16:30:00.000Z","open":1073.26,"high":1074.33,"low":1073.1,"close":1073.905},{"date":"2018-01-02T17:00:00.000Z","open":1073.905,"high":1073.905,"low":1072.68,"close":1073.08},{"date":"2018-01-02T17:30:00.000Z","open":1073.54,"high":1073.605,"low":1072.16,"close":1072.335},{"date":"2018-01-02T18:00:00.000Z","open":1073.0,"high":1073.86,"low":1071.89,"close":1073.86},{"date":"2018-01-02T18:30:00.000Z","open":1073.73,"high":1074.37,"low":1072.54,"close":1072.97},{"date":"2018-01-02T19:00:00.000Z","open":1073.15,"high":1074.93,"low":1072.705,"close":1072.705},{"date":"2018-01-02T19:30:00.000Z","open":1072.06,"high":1074.07,"low":1071.655,"close":1074.07},{"date":"2018-01-02T20:00:00.000Z","open":1074.55,"high":1075.08,"low":1072.78,"close":1073.83},{"date":"2018-01-02T20:30:00.000Z","open":1073.83,"high":1075.87,"low":1073.23,"close":1073.315}]'}
|
||||
headers:
|
||||
Allow: ['GET, HEAD, OPTIONS']
|
||||
Content-Length: ['1261']
|
||||
Content-Type: [application/json]
|
||||
Date: ['Wed, 04 Jul 2018 02:53:33 GMT']
|
||||
Server: [nginx/1.10.1]
|
||||
Vary: ['Accept, Cookie']
|
||||
X-Frame-Options: [SAMEORIGIN]
|
||||
status: {code: 200, message: OK}
|
||||
version: 1
|
||||
@@ -97,6 +97,15 @@ class TestTickerPrices(TestCase):
|
||||
rows = list(reader)
|
||||
assert len(rows) > 2 # more than 1 day of data
|
||||
|
||||
@vcr.use_cassette('tests/fixtures/intraday_price.yaml')
|
||||
def test_intraday_ticker_price(self):
|
||||
"""Test the EOD Prices Endpoint with data param"""
|
||||
prices = self._client.get_ticker_price("GOOGL",
|
||||
startDate="2018-01-02",
|
||||
endDate="2018-01-02",
|
||||
frequency="30Min")
|
||||
self.assertGreater(len(prices), 1)
|
||||
|
||||
@vcr.use_cassette('tests/fixtures/list_stock_tickers.yaml')
|
||||
def test_list_stock_tickers(self):
|
||||
tickers = self._client.list_stock_tickers()
|
||||
|
||||
@@ -55,6 +55,15 @@ class TestTiingoWithPython(TestCase):
|
||||
self.assertTrue(isinstance(prices, pd.Series))
|
||||
assert len(prices.index) == 10
|
||||
|
||||
@vcr.use_cassette('tests/fixtures/intraday_price.yaml')
|
||||
def test_intraday_ticker_price(self):
|
||||
"""Test the EOD Prices Endpoint with data param"""
|
||||
prices = self._client.get_dataframe("GOOGL",
|
||||
startDate="2018-01-02",
|
||||
endDate="2018-01-02",
|
||||
frequency="30Min")
|
||||
self.assertGreater(len(prices), 1)
|
||||
|
||||
def test_metric_name_column_error(self):
|
||||
with self.assertRaises(APIColumnNameError):
|
||||
self._client.get_dataframe(['GOOGL', 'AAPL'], startDate='2018-01-05',
|
||||
|
||||
@@ -55,6 +55,10 @@ class APIColumnNameError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidFrequencyError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TiingoClient(RestClient):
|
||||
"""Class for managing interactions with the Tiingo REST API
|
||||
|
||||
@@ -128,6 +132,40 @@ class TiingoClient(RestClient):
|
||||
elif fmt == 'object':
|
||||
return dict_to_object(data, "Ticker")
|
||||
|
||||
def _invalid_frequency(self, frequency):
|
||||
"""
|
||||
Check to see that frequency was specified correctly
|
||||
:param frequency (string): frequency string
|
||||
:return (boolean):
|
||||
"""
|
||||
daily_freqs = ['daily', 'weekly', 'monthly', 'annually']
|
||||
intraday_freqs = ['min', 'hour']
|
||||
|
||||
if frequency.lower() in daily_freqs:
|
||||
return False
|
||||
elif intraday_freqs[0] in frequency.lower() or \
|
||||
intraday_freqs[1] in frequency.lower():
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def _get_url(self, frequency):
|
||||
"""
|
||||
Return url based on frequency. Daily, weekly, or yearly use Tiingo
|
||||
EOD api; anything less than daily uses the iex intraday api.
|
||||
:param frequency (string): valid frequency per Tiingo api
|
||||
:return (string): url
|
||||
"""
|
||||
if self._invalid_frequency(frequency):
|
||||
etext = ("Error: {} is an invalid frequency. Check Tiingo API documentation "
|
||||
"for valid EOD or intraday frequency format.")
|
||||
raise self.InvalidFrequencyError(etext.format(frequency))
|
||||
else:
|
||||
if frequency.lower() in ['daily', 'weekly', 'monthly', 'annually']:
|
||||
return "tiingo/daily/{}/prices"
|
||||
else:
|
||||
return "iex/{}/prices"
|
||||
|
||||
def get_ticker_price(self, ticker,
|
||||
startDate=None, endDate=None,
|
||||
fmt='json', frequency='daily'):
|
||||
@@ -144,7 +182,7 @@ class TiingoClient(RestClient):
|
||||
fmt (string): 'csv' or 'json'
|
||||
frequency (string): Resample frequency
|
||||
"""
|
||||
url = "tiingo/daily/{}/prices".format(ticker)
|
||||
url = self._get_url(frequency).format(ticker)
|
||||
params = {
|
||||
'format': fmt if fmt != "object" else 'json', # conversion local
|
||||
'resampleFreq': frequency
|
||||
@@ -207,7 +245,7 @@ class TiingoClient(RestClient):
|
||||
if pandas_is_installed:
|
||||
if type(tickers) is str:
|
||||
stock = tickers
|
||||
url = "tiingo/daily/{}/prices".format(stock)
|
||||
url = self._get_url(frequency).format(stock)
|
||||
response = self._request('GET', url, params=params)
|
||||
df = pd.DataFrame(response.json())
|
||||
if metric_name is not None:
|
||||
@@ -220,7 +258,7 @@ class TiingoClient(RestClient):
|
||||
else:
|
||||
prices = pd.DataFrame()
|
||||
for stock in tickers:
|
||||
url = "tiingo/daily/{}/prices".format(stock)
|
||||
url = self._get_url(frequency).format(stock)
|
||||
response = self._request('GET', url, params=params)
|
||||
df = pd.DataFrame(response.json())
|
||||
df.index = df['date']
|
||||
|
||||
Reference in New Issue
Block a user