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
* Feature: Add 'columns' parameter to 'get_dataframe' and 'get_ticker_price' func (#1057)
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
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',
@@ -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
-----------------

View File

@@ -1,14 +1,14 @@
pip==24.0
pip==24.3.1
bumpversion==0.6.0
wheel==0.44.0
watchdog==5.0.3
wheel==0.45.1
watchdog==6.0.0
flake8==7.1.1
tox==4.23.2
coverage==7.6.3
coverage==7.6.8
cryptography==43.0.3
Sphinx==8.1.3
PyYAML==6.0.2
pytest==8.3.3
pytest==8.3.4
vcrpy==2.1.1
twine==5.1.1
black==24.8.0
twine==6.0.1
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):
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):
@@ -68,7 +68,7 @@ class TestTickerPrices(TestCase):
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')
@@ -98,6 +98,36 @@ class TestTickerPrices(TestCase):
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"""
@@ -149,6 +179,7 @@ class TestTickerPrices(TestCase):
endDate="2018-01-02",
frequency="1.5mins")
# tiingo/news
class TestNews(TestCase):
@@ -227,6 +258,7 @@ class TestNews(TestCase):
with self.assertRaises(RestClientError):
assert self._client.get_bulk_news(file_id="1", fmt="object")
# FUNDAMENTALS ENDPOINTS
class TestFundamentals(TestCase):

View File

@@ -114,6 +114,26 @@ class TestTiingoWithPython(TestCase):
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',

View File

@@ -6,7 +6,6 @@ import json
import os
import re
import sys
import pkg_resources
from zipfile import ZipFile
import requests
@@ -19,6 +18,8 @@ from tiingo.exceptions import (
MissingRequiredArgumentError,
)
from tiingo.__version__ import __version__ as VERSION
try:
import pandas as pd
@@ -26,8 +27,6 @@ try:
except ImportError:
pandas_is_installed = False
VERSION = pkg_resources.get_distribution("tiingo").version
# These methods enable python 2 + 3 compatibility.
def get_zipfile_from_response(response):
@@ -219,7 +218,13 @@ class TiingoClient(RestClient):
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.
@@ -231,6 +236,8 @@ class TiingoClient(RestClient):
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
"""
@@ -244,6 +251,8 @@ class TiingoClient(RestClient):
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
@@ -262,6 +271,7 @@ class TiingoClient(RestClient):
startDate=None,
endDate=None,
metric_name=None,
columns=None,
frequency="daily",
fmt="json",
):
@@ -278,6 +288,8 @@ class TiingoClient(RestClient):
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,
@@ -315,6 +327,8 @@ class TiingoClient(RestClient):
params["startDate"] = startDate
if endDate:
params["endDate"] = endDate
if columns:
params["columns"] = columns
if pandas_is_installed:
if type(tickers) is str: