Merge pull request #1057 from BloodyHell/patch-1

Add columns as parameter to get_dataframe
This commit is contained in:
Cameron Yick
2024-11-17 16:37:25 -05:00
committed by GitHub
7 changed files with 139 additions and 3 deletions

View File

@@ -5,6 +5,7 @@ History
-------------------------------- --------------------------------
* Dev: New config for readthedocs * Dev: New config for readthedocs
* Feature: Add 'columns' parameter to 'get_dataframe' and 'get_ticker_price' func (#1057)
0.15.6 (2024-05-25) 0.15.6 (2024-05-25)
-------------------------------- --------------------------------

View File

@@ -90,6 +90,9 @@ for each function for details.).
# Get latest prices, based on 3+ sources as JSON, sampled weekly # Get latest prices, based on 3+ sources as JSON, sampled weekly
ticker_price = client.get_ticker_price("GOOGL", frequency="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 # Get historical GOOGL prices from August 2017 as JSON, sampled daily
historical_prices = client.get_ticker_price("GOOGL", historical_prices = client.get_ticker_price("GOOGL",
fmt='json', fmt='json',
@@ -154,11 +157,22 @@ To receive results in ``pandas`` format, use the ``get_dataframe()`` method:
endDate='2018-05-31') 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`` 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 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". 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 Cryptocurrency
----------------- -----------------

View File

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

View File

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

View File

@@ -55,7 +55,7 @@ class TestTickerPrices(TestCase):
def test_ticker_metadata_as_object(self): def test_ticker_metadata_as_object(self):
metadata = self._client.get_ticker_metadata("GOOGL", fmt="object") metadata = self._client.get_ticker_metadata("GOOGL", fmt="object")
assert metadata.ticker == "GOOGL" # Access property via ATTRIBUTE 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') @vcr.use_cassette('tests/fixtures/ticker_price.yaml')
def test_ticker_price(self): def test_ticker_price(self):
@@ -68,7 +68,7 @@ class TestTickerPrices(TestCase):
def test_ticker_price(self): def test_ticker_price(self):
"""Test that weekly frequency works""" """Test that weekly frequency works"""
prices = self._client.get_ticker_price("GOOGL", startDate='2018-01-05', 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 len(prices) == 3
assert prices[0].get('adjClose') assert prices[0].get('adjClose')
@@ -98,6 +98,36 @@ class TestTickerPrices(TestCase):
rows = list(reader) rows = list(reader)
assert len(rows) > 2 # more than 1 day of data 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') @vcr.use_cassette('tests/fixtures/intraday_price.yaml')
def test_intraday_ticker_price(self): def test_intraday_ticker_price(self):
"""Test the EOD Prices Endpoint with data param""" """Test the EOD Prices Endpoint with data param"""
@@ -149,6 +179,7 @@ class TestTickerPrices(TestCase):
endDate="2018-01-02", endDate="2018-01-02",
frequency="1.5mins") frequency="1.5mins")
# tiingo/news # tiingo/news
class TestNews(TestCase): class TestNews(TestCase):
@@ -227,6 +258,7 @@ class TestNews(TestCase):
with self.assertRaises(RestClientError): with self.assertRaises(RestClientError):
assert self._client.get_bulk_news(file_id="1", fmt="object") assert self._client.get_bulk_news(file_id="1", fmt="object")
# FUNDAMENTALS ENDPOINTS # FUNDAMENTALS ENDPOINTS
class TestFundamentals(TestCase): class TestFundamentals(TestCase):

View File

@@ -114,6 +114,26 @@ class TestTiingoWithPython(TestCase):
frequency="30Min") frequency="30Min")
self.assertGreater(len(prices), 1) 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): def test_metric_name_column_error(self):
with self.assertRaises(APIColumnNameError): with self.assertRaises(APIColumnNameError):
self._client.get_dataframe(['GOOGL', 'AAPL'], startDate='2018-01-05', self._client.get_dataframe(['GOOGL', 'AAPL'], startDate='2018-01-05',

View File

@@ -219,7 +219,13 @@ class TiingoClient(RestClient):
return prices return prices
def get_ticker_price( 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. """By default, return latest EOD Composite Price for a stock ticker.
On average, each feed contains 3 data sources. On average, each feed contains 3 data sources.
@@ -231,6 +237,8 @@ class TiingoClient(RestClient):
ticker (string): Unique identifier for stock ticker ticker (string): Unique identifier for stock ticker
startDate (string): Start of ticker range in YYYY-MM-DD format startDate (string): Start of ticker range in YYYY-MM-DD format
endDate (string): End 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' fmt (string): 'csv' or 'json'
frequency (string): Resample frequency frequency (string): Resample frequency
""" """
@@ -244,6 +252,8 @@ class TiingoClient(RestClient):
params["startDate"] = startDate params["startDate"] = startDate
if endDate: if endDate:
params["endDate"] = endDate params["endDate"] = endDate
if columns:
params["columns"] = columns
# TODO: evaluate whether to stream CSV to cache on disk, or # TODO: evaluate whether to stream CSV to cache on disk, or
# load as array in memory, or just pass plain text # load as array in memory, or just pass plain text
@@ -262,6 +272,7 @@ class TiingoClient(RestClient):
startDate=None, startDate=None,
endDate=None, endDate=None,
metric_name=None, metric_name=None,
columns=None,
frequency="daily", frequency="daily",
fmt="json", fmt="json",
): ):
@@ -278,6 +289,8 @@ class TiingoClient(RestClient):
tickers (string/list): One or more unique identifiers for a stock ticker. tickers (string/list): One or more unique identifiers for a stock ticker.
startDate (string): Start of ticker range in YYYY-MM-DD format. startDate (string): Start of ticker range in YYYY-MM-DD format.
endDate (string): End 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 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 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, all of the available data will be returned. In the event of a list of tickers,
@@ -315,6 +328,8 @@ class TiingoClient(RestClient):
params["startDate"] = startDate params["startDate"] = startDate
if endDate: if endDate:
params["endDate"] = endDate params["endDate"] = endDate
if columns:
params["columns"] = columns
if pandas_is_installed: if pandas_is_installed:
if type(tickers) is str: if type(tickers) is str: