Skip to content

Commit

Permalink
Add columns param to get_ticker_price, including tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Koen werklaptop committed Oct 23, 2024
1 parent 80b40c5 commit 6b53725
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 4 deletions.
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



34 changes: 32 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,34 @@ 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 CSV endpoint 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 CSV endpoint works"""
prices = self._client.get_ticker_price("GOOGL",
columns="open,high,low,close,volume",
fmt='json')
assert len(prices) == 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 +177,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 +256,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
18 changes: 18 additions & 0 deletions tests/test_tiingo_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,24 @@ 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 CSV endpoint works"""
prices = self._client.get_dataframe("GOOGL",
columns="volume",
fmt='json')
assert len(prices) == 1
assert len(prices.columns) == 2

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

def test_metric_name_column_error(self):
with self.assertRaises(APIColumnNameError):
self._client.get_dataframe(['GOOGL', 'AAPL'], startDate='2018-01-05',
Expand Down
7 changes: 5 additions & 2 deletions tiingo/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ 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 +231,7 @@ 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): Comma separated parameter specifying which columns to retrieve (to include volume)
fmt (string): 'csv' or 'json'
frequency (string): Resample frequency
"""
Expand All @@ -244,6 +245,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 Down Expand Up @@ -279,7 +282,7 @@ 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): Comma seperated parameter specifying which columns to retrieve (to include volume)
columns (string): Comma separated parameter specifying which columns to retrieve (to include volume)
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

0 comments on commit 6b53725

Please sign in to comment.