Merge branch 'master' into pyup-update-tox-4.23.0-to-4.23.2

This commit is contained in:
Cameron Yick
2025-01-11 12:43:29 -05:00
committed by GitHub
8 changed files with 148 additions and 13 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

@@ -1,14 +1,14 @@
pip==24.0 pip==24.3.1
bumpversion==0.6.0 bumpversion==0.6.0
wheel==0.44.0 wheel==0.45.1
watchdog==5.0.3 watchdog==6.0.0
flake8==7.1.1 flake8==7.1.1
tox==4.23.2 tox==4.23.2
coverage==7.6.3 coverage==7.6.8
cryptography==43.0.3 cryptography==43.0.3
Sphinx==8.1.3 Sphinx==8.1.3
PyYAML==6.0.2 PyYAML==6.0.2
pytest==8.3.3 pytest==8.3.4
vcrpy==2.1.1 vcrpy==2.1.1
twine==5.1.1 twine==6.0.1
black==24.8.0 black==24.10.0

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

@@ -6,7 +6,6 @@ import json
import os import os
import re import re
import sys import sys
import pkg_resources
from zipfile import ZipFile from zipfile import ZipFile
import requests import requests
@@ -19,6 +18,8 @@ from tiingo.exceptions import (
MissingRequiredArgumentError, MissingRequiredArgumentError,
) )
from tiingo.__version__ import __version__ as VERSION
try: try:
import pandas as pd import pandas as pd
@@ -26,8 +27,6 @@ try:
except ImportError: except ImportError:
pandas_is_installed = False pandas_is_installed = False
VERSION = pkg_resources.get_distribution("tiingo").version
# These methods enable python 2 + 3 compatibility. # These methods enable python 2 + 3 compatibility.
def get_zipfile_from_response(response): def get_zipfile_from_response(response):
@@ -219,7 +218,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 +236,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 +251,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 +271,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 +288,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 +327,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: