Skip to content

Commit

Permalink
Merge pull request #1057 from BloodyHell/patch-1
Browse files Browse the repository at this point in the history
Add columns as parameter to get_dataframe
  • Loading branch information
hydrosquall authored Nov 17, 2024
2 parents 7acab48 + 803b2a9 commit a066830
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 3 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ History
--------------------------------

* Dev: New config for readthedocs
* Feature: Add 'columns' parameter to 'get_dataframe' and 'get_ticker_price' func (#1057)

0.15.6 (2024-05-25)
--------------------------------
Expand Down
14 changes: 14 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ for each function for details.).
# Get latest prices, based on 3+ sources as JSON, sampled weekly
ticker_price = client.get_ticker_price("GOOGL", frequency="weekly")
# Get 1 min prices, including the "open", "close" and "volume" columns
ticker_price = client.get_ticker_price("GOOGL", frequency="1min", columns="open,close,volume")
# Get historical GOOGL prices from August 2017 as JSON, sampled daily
historical_prices = client.get_ticker_price("GOOGL",
fmt='json',
Expand Down Expand Up @@ -154,11 +157,22 @@ To receive results in ``pandas`` format, use the ``get_dataframe()`` method:
endDate='2018-05-31')
#Get a pd.DataFrame for a list of symbols for "close" and "volume" columns:
ticker_history = client.get_dataframe(['GOOGL', 'AAPL'],
frequency='weekly',
columns="close,volume"
startDate='2017-01-01',
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".

It's also possible to specify which columns you're interested in, for example: "open", "close", "low", "high" and "volume" (see `End of Day response docs <https://www.tiingo.com/documentation/end-of-day>`_ for future columns).


Cryptocurrency
-----------------

Expand Down
27 changes: 27 additions & 0 deletions tests/fixtures/ticker_price_with_multiple_columns.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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.5.0]
method: GET
uri: https://api.tiingo.com/tiingo/daily/GOOGL/prices?format=json&resampleFreq=daily&columns=open,high,low,close,volume
response:
body: {string: '[{"close":165.14,"date":"2024-10-22T00:00:00+00:00","high":165.77,"low":162.98,"open":162.98,"volume":16568121}]'}
headers:
Allow: ['GET, HEAD, OPTIONS']
Content-Length: ['1982']
Content-Type: [application/json]
Date: ['Wed, 23 Oct 2024 02:42:06 GMT']
Server: [nginx/1.10.1]
Vary: ['Accept, Cookie']
X-Frame-Options: [SAMEORIGIN]
status: {code: 200, message: OK}
version: 1



27 changes: 27 additions & 0 deletions tests/fixtures/ticker_price_with_volume_column.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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.5.0]
method: GET
uri: https://api.tiingo.com/tiingo/daily/GOOGL/prices?format=json&resampleFreq=daily&columns=volume
response:
body: {string: '[{"date":"2024-10-22T00:00:00+00:00","volume":16568121}]'}
headers:
Allow: ['GET, HEAD, OPTIONS']
Content-Length: ['1001']
Content-Type: [application/json]
Date: ['Wed, 23 Oct 2024 02:42:06 GMT']
Server: [nginx/1.10.1]
Vary: ['Accept, Cookie']
X-Frame-Options: [SAMEORIGIN]
status: {code: 200, message: OK}
version: 1



36 changes: 34 additions & 2 deletions tests/test_tiingo.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_ticker_metadata(self):
def test_ticker_metadata_as_object(self):
metadata = self._client.get_ticker_metadata("GOOGL", fmt="object")
assert metadata.ticker == "GOOGL" # Access property via ATTRIBUTE
assert metadata.name # (contrast with key access above
assert metadata.name # (contrast with key access above

@vcr.use_cassette('tests/fixtures/ticker_price.yaml')
def test_ticker_price(self):
Expand All @@ -68,7 +68,7 @@ def test_ticker_price(self):
def test_ticker_price(self):
"""Test that weekly frequency works"""
prices = self._client.get_ticker_price("GOOGL", startDate='2018-01-05',
endDate='2018-01-19', frequency='weekly')
endDate='2018-01-19', frequency='weekly')
assert len(prices) == 3
assert prices[0].get('adjClose')

Expand Down Expand Up @@ -98,6 +98,36 @@ def test_ticker_price_with_csv(self):
rows = list(reader)
assert len(rows) > 2 # more than 1 day of data

@vcr.use_cassette('tests/fixtures/ticker_price_with_volume_column.yaml')
def test_ticker_price_with_volume_column(self):
"""Confirm that requesting a single column works"""
prices = self._client.get_ticker_price("GOOGL",
columns="volume",
fmt='json')
assert len(prices) == 1
assert prices[0].get('date')
assert not prices[0].get('high')
assert not prices[0].get('low')
assert not prices[0].get('open')
assert not prices[0].get('close')
assert prices[0].get('volume')

@vcr.use_cassette('tests/fixtures/ticker_price_with_multiple_columns.yaml')
def test_ticker_price_with_multiple_columns(self):
"""Confirm that requesting specific columns works"""
requested_columns = "open,high,low,close,volume"
prices = self._client.get_ticker_price("GOOGL",
columns=requested_columns,
fmt='json')
assert len(prices) == 1
assert len(prices[0]) == len(requested_columns.split(',')) + 1
assert prices[0].get('date')
assert prices[0].get('high')
assert prices[0].get('low')
assert prices[0].get('open')
assert prices[0].get('close')
assert prices[0].get('volume')

@vcr.use_cassette('tests/fixtures/intraday_price.yaml')
def test_intraday_ticker_price(self):
"""Test the EOD Prices Endpoint with data param"""
Expand Down Expand Up @@ -149,6 +179,7 @@ def test_invalid_frequency_error(self):
endDate="2018-01-02",
frequency="1.5mins")


# tiingo/news
class TestNews(TestCase):

Expand Down Expand Up @@ -227,6 +258,7 @@ def test_news_bulk_as_objects(self):
with self.assertRaises(RestClientError):
assert self._client.get_bulk_news(file_id="1", fmt="object")


# FUNDAMENTALS ENDPOINTS
class TestFundamentals(TestCase):

Expand Down
20 changes: 20 additions & 0 deletions tests/test_tiingo_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ def test_intraday_ticker_price(self):
frequency="30Min")
self.assertGreater(len(prices), 1)

@vcr.use_cassette('tests/fixtures/ticker_price_with_volume_column.yaml')
def test_get_dataframe_with_volume_column(self):
"""Confirm that requesting a single column works"""
requested_column = "volume"
prices = self._client.get_dataframe("GOOGL",
columns=requested_column,
fmt='json')
assert len(prices) == 1
assert len(prices.columns) == 1

@vcr.use_cassette('tests/fixtures/ticker_price_with_multiple_columns.yaml')
def test_get_dataframe_with_multiple_columns(self):
"""Confirm that requesting specific columns works"""
requested_columns = "open,high,low,close,volume"
prices = self._client.get_dataframe("GOOGL",
columns=requested_columns,
fmt='json')
assert len(prices) == 1
assert len(prices.columns) == len(requested_columns.split(','))

def test_metric_name_column_error(self):
with self.assertRaises(APIColumnNameError):
self._client.get_dataframe(['GOOGL', 'AAPL'], startDate='2018-01-05',
Expand Down
17 changes: 16 additions & 1 deletion tiingo/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,13 @@ def _request_pandas(self, ticker, metric_name, params):
return prices

def get_ticker_price(
self, ticker, startDate=None, endDate=None, fmt="json", frequency="daily"
self,
ticker,
startDate=None,
endDate=None,
columns=None,
fmt="json",
frequency="daily",
):
"""By default, return latest EOD Composite Price for a stock ticker.
On average, each feed contains 3 data sources.
Expand All @@ -231,6 +237,8 @@ def get_ticker_price(
ticker (string): Unique identifier for stock ticker
startDate (string): Start of ticker range in YYYY-MM-DD format
endDate (string): End of ticker range in YYYY-MM-DD format
columns (string): Optional comma separated parameter specifying which columns to retrieve.
By default, 'date', 'open', 'close', 'high' and 'low' are retrieved. 'volume' is an extra option.
fmt (string): 'csv' or 'json'
frequency (string): Resample frequency
"""
Expand All @@ -244,6 +252,8 @@ def get_ticker_price(
params["startDate"] = startDate
if endDate:
params["endDate"] = endDate
if columns:
params["columns"] = columns

# TODO: evaluate whether to stream CSV to cache on disk, or
# load as array in memory, or just pass plain text
Expand All @@ -262,6 +272,7 @@ def get_dataframe(
startDate=None,
endDate=None,
metric_name=None,
columns=None,
frequency="daily",
fmt="json",
):
Expand All @@ -278,6 +289,8 @@ def get_dataframe(
tickers (string/list): One or more unique identifiers for a stock ticker.
startDate (string): Start of ticker range in YYYY-MM-DD format.
endDate (string): End of ticker range in YYYY-MM-DD format.
columns (string): Optional comma separated parameter specifying which columns to retrieve.
By default, 'date', 'open', 'close', 'high' and 'low' are retrieved. 'volume' is an extra option.
metric_name (string): Optional parameter specifying metric to be returned for each
ticker. In the event of a single ticker, this is optional and if not specified
all of the available data will be returned. In the event of a list of tickers,
Expand Down Expand Up @@ -315,6 +328,8 @@ def get_dataframe(
params["startDate"] = startDate
if endDate:
params["endDate"] = endDate
if columns:
params["columns"] = columns

if pandas_is_installed:
if type(tickers) is str:
Expand Down

0 comments on commit a066830

Please sign in to comment.