Initial commit

This commit is contained in:
Davis Thames
2018-07-03 23:09:15 -04:00
parent 476b59f28c
commit ec15ef85d6
5 changed files with 85 additions and 3 deletions

View File

@@ -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
View 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

View File

@@ -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()

View File

@@ -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',

View File

@@ -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']