mirror of
https://github.com/hydrosquall/tiingo-python.git
synced 2025-12-18 12:24:18 +01:00
Merge branch 'master' into pyup-update-tox-4.23.0-to-4.23.2
This commit is contained in:
@@ -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)
|
||||
--------------------------------
|
||||
|
||||
14
README.rst
14
README.rst
@@ -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
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
27
tests/fixtures/ticker_price_with_multiple_columns.yaml
vendored
Normal file
27
tests/fixtures/ticker_price_with_multiple_columns.yaml
vendored
Normal 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
|
||||
|
||||
|
||||
|
||||
27
tests/fixtures/ticker_price_with_volume_column.yaml
vendored
Normal file
27
tests/fixtures/ticker_price_with_volume_column.yaml
vendored
Normal 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
|
||||
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user