mirror of
https://github.com/hydrosquall/tiingo-python.git
synced 2025-12-17 20:04:19 +01:00
formatting: apply black formatter
This commit is contained in:
459
tiingo/api.py
459
tiingo/api.py
@@ -16,10 +16,12 @@ from tiingo.exceptions import (
|
||||
InstallPandasException,
|
||||
APIColumnNameError,
|
||||
InvalidFrequencyError,
|
||||
MissingRequiredArgumentError)
|
||||
MissingRequiredArgumentError,
|
||||
)
|
||||
|
||||
try:
|
||||
import pandas as pd
|
||||
|
||||
pandas_is_installed = True
|
||||
except ImportError:
|
||||
pandas_is_installed = False
|
||||
@@ -40,11 +42,13 @@ def get_zipfile_from_response(response):
|
||||
def get_buffer_from_zipfile(zipfile, filename):
|
||||
if sys.version_info < (3, 0): # python 2
|
||||
from StringIO import StringIO
|
||||
|
||||
return StringIO(zipfile.read(filename))
|
||||
else: # python 3
|
||||
# Source:
|
||||
# https://stackoverflow.com/questions/5627954/py3k-how-do-you-read-a-file-inside-a-zip-file-as-text-not-bytes
|
||||
from io import (TextIOWrapper, BytesIO)
|
||||
from io import TextIOWrapper, BytesIO
|
||||
|
||||
return TextIOWrapper(BytesIO(zipfile.read(filename)))
|
||||
|
||||
|
||||
@@ -52,16 +56,16 @@ def dict_to_object(item, object_name):
|
||||
"""Converts a python dict to a namedtuple, saving memory."""
|
||||
fields = item.keys()
|
||||
values = item.values()
|
||||
return json.loads(json.dumps(item),
|
||||
object_hook=lambda d:
|
||||
namedtuple(object_name, fields)(*values))
|
||||
return json.loads(
|
||||
json.dumps(item), object_hook=lambda d: namedtuple(object_name, fields)(*values)
|
||||
)
|
||||
|
||||
|
||||
class TiingoClient(RestClient):
|
||||
"""Class for managing interactions with the Tiingo REST API
|
||||
|
||||
Supply API Key via Environment Variable TIINGO_API_KEY
|
||||
or via the Config Object
|
||||
Supply API Key via Environment Variable TIINGO_API_KEY
|
||||
or via the Config Object
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -69,74 +73,77 @@ class TiingoClient(RestClient):
|
||||
self._base_url = "https://api.tiingo.com"
|
||||
|
||||
try:
|
||||
api_key = self._config['api_key']
|
||||
api_key = self._config["api_key"]
|
||||
except KeyError:
|
||||
api_key = os.environ.get('TIINGO_API_KEY')
|
||||
api_key = os.environ.get("TIINGO_API_KEY")
|
||||
self._api_key = api_key
|
||||
|
||||
if not(api_key):
|
||||
raise RuntimeError("Tiingo API Key not provided. Please provide"
|
||||
" via environment variable or config argument.")
|
||||
if not (api_key):
|
||||
raise RuntimeError(
|
||||
"Tiingo API Key not provided. Please provide"
|
||||
" via environment variable or config argument."
|
||||
)
|
||||
|
||||
self._headers = {
|
||||
'Authorization': "Token {}".format(api_key),
|
||||
'Content-Type': 'application/json',
|
||||
'User-Agent': 'tiingo-python-client {}'.format(VERSION)
|
||||
"Authorization": "Token {}".format(api_key),
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "tiingo-python-client {}".format(VERSION),
|
||||
}
|
||||
|
||||
self._frequency_pattern = re.compile('^[0-9]+(min|hour)$', re.IGNORECASE)
|
||||
self._frequency_pattern = re.compile("^[0-9]+(min|hour)$", re.IGNORECASE)
|
||||
|
||||
def __repr__(self):
|
||||
return '<TiingoClient(url="{}")>'.format(self._base_url)
|
||||
|
||||
def _is_eod_frequency(self,frequency):
|
||||
return frequency.lower() in ['daily', 'weekly', 'monthly', 'annually']
|
||||
def _is_eod_frequency(self, frequency):
|
||||
return frequency.lower() in ["daily", "weekly", "monthly", "annually"]
|
||||
|
||||
# TICKER PRICE ENDPOINTS
|
||||
# https://api.tiingo.com/docs/tiingo/daily
|
||||
def list_tickers(self, assetTypes=[]):
|
||||
"""Return a list of dicts of metadata tickers for all supported tickers
|
||||
of the specified asset type, as well as metadata about each ticker.
|
||||
This includes supported date range, the exchange the ticker is traded
|
||||
on, and the currency the stock is traded on.
|
||||
Tickers for unrelated products are omitted.
|
||||
https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip
|
||||
"""
|
||||
listing_file_url = "https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip"
|
||||
of the specified asset type, as well as metadata about each ticker.
|
||||
This includes supported date range, the exchange the ticker is traded
|
||||
on, and the currency the stock is traded on.
|
||||
Tickers for unrelated products are omitted.
|
||||
https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip
|
||||
"""
|
||||
listing_file_url = (
|
||||
"https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip"
|
||||
)
|
||||
response = requests.get(listing_file_url)
|
||||
zipdata = get_zipfile_from_response(response)
|
||||
raw_csv = get_buffer_from_zipfile(zipdata, 'supported_tickers.csv')
|
||||
raw_csv = get_buffer_from_zipfile(zipdata, "supported_tickers.csv")
|
||||
reader = csv.DictReader(raw_csv)
|
||||
|
||||
if not len(assetTypes):
|
||||
return [row for row in reader]
|
||||
|
||||
assetTypesSet = set(assetTypes)
|
||||
return [row for row in reader
|
||||
if row.get('assetType') in assetTypesSet]
|
||||
return [row for row in reader if row.get("assetType") in assetTypesSet]
|
||||
|
||||
def list_stock_tickers(self):
|
||||
return self.list_tickers(['Stock'])
|
||||
return self.list_tickers(["Stock"])
|
||||
|
||||
def list_etf_tickers(self):
|
||||
return self.list_tickers(['ETF'])
|
||||
return self.list_tickers(["ETF"])
|
||||
|
||||
def list_fund_tickers(self):
|
||||
return self.list_tickers(['Mutual Fund'])
|
||||
return self.list_tickers(["Mutual Fund"])
|
||||
|
||||
def get_ticker_metadata(self, ticker, fmt='json'):
|
||||
def get_ticker_metadata(self, ticker, fmt="json"):
|
||||
"""Return metadata for 1 ticker
|
||||
Use TiingoClient.list_tickers() to get available options
|
||||
Use TiingoClient.list_tickers() to get available options
|
||||
|
||||
Args:
|
||||
ticker (str) : Unique identifier for stock
|
||||
Args:
|
||||
ticker (str) : Unique identifier for stock
|
||||
"""
|
||||
url = "tiingo/daily/{}".format(ticker)
|
||||
response = self._request('GET', url)
|
||||
response = self._request("GET", url)
|
||||
data = response.json()
|
||||
if fmt == 'json':
|
||||
if fmt == "json":
|
||||
return data
|
||||
elif fmt == 'object':
|
||||
elif fmt == "object":
|
||||
return dict_to_object(data, "Ticker")
|
||||
|
||||
def _invalid_frequency(self, frequency):
|
||||
@@ -145,7 +152,9 @@ class TiingoClient(RestClient):
|
||||
:param frequency (string): frequency string
|
||||
:return (boolean):
|
||||
"""
|
||||
is_valid = self._is_eod_frequency(frequency) or re.match(self._frequency_pattern, frequency)
|
||||
is_valid = self._is_eod_frequency(frequency) or re.match(
|
||||
self._frequency_pattern, frequency
|
||||
)
|
||||
return not is_valid
|
||||
|
||||
def _get_url(self, ticker, frequency):
|
||||
@@ -157,8 +166,10 @@ class TiingoClient(RestClient):
|
||||
:return (string): url
|
||||
"""
|
||||
if self._invalid_frequency(frequency):
|
||||
etext = ("Error: {} is an invalid frequency. Check Tiingo API documentation "
|
||||
"for valid EOD or intraday frequency format.")
|
||||
etext = (
|
||||
"Error: {} is an invalid frequency. Check Tiingo API documentation "
|
||||
"for valid EOD or intraday frequency format."
|
||||
)
|
||||
raise InvalidFrequencyError(etext.format(frequency))
|
||||
else:
|
||||
if self._is_eod_frequency(frequency):
|
||||
@@ -179,19 +190,19 @@ class TiingoClient(RestClient):
|
||||
all of the available data will be returned. In the event of a list of tickers,
|
||||
this parameter is required.
|
||||
"""
|
||||
url = self._get_url(ticker, params['resampleFreq'])
|
||||
response = self._request('GET', url, params=params)
|
||||
if params['format'] == 'csv':
|
||||
url = self._get_url(ticker, params["resampleFreq"])
|
||||
response = self._request("GET", url, params=params)
|
||||
if params["format"] == "csv":
|
||||
if sys.version_info < (3, 0): # python 2
|
||||
from StringIO import StringIO
|
||||
else: # python 3
|
||||
from io import StringIO
|
||||
|
||||
df = pd.read_csv(StringIO(response.content.decode('utf-8')))
|
||||
df = pd.read_csv(StringIO(response.content.decode("utf-8")))
|
||||
else:
|
||||
df = pd.DataFrame(response.json())
|
||||
|
||||
df.set_index('date', inplace=True)
|
||||
df.set_index("date", inplace=True)
|
||||
|
||||
if metric_name is not None:
|
||||
prices = df[metric_name]
|
||||
@@ -203,40 +214,40 @@ class TiingoClient(RestClient):
|
||||
# Localize to UTC to ensure equivalence between data returned in json format and
|
||||
# csv format. Tiingo daily data requested in csv format does not include a timezone.
|
||||
if prices.index.tz is None:
|
||||
prices.index = prices.index.tz_localize('UTC')
|
||||
prices.index = prices.index.tz_localize("UTC")
|
||||
|
||||
return prices
|
||||
|
||||
def get_ticker_price(self, ticker,
|
||||
startDate=None, endDate=None,
|
||||
fmt='json', frequency='daily'):
|
||||
def get_ticker_price(
|
||||
self, ticker, startDate=None, endDate=None, fmt="json", frequency="daily"
|
||||
):
|
||||
"""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.
|
||||
|
||||
Supported tickers + Available Day Ranges are here:
|
||||
https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip
|
||||
Supported tickers + Available Day Ranges are here:
|
||||
https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip
|
||||
|
||||
Args:
|
||||
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
|
||||
fmt (string): 'csv' or 'json'
|
||||
frequency (string): Resample frequency
|
||||
Args:
|
||||
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
|
||||
fmt (string): 'csv' or 'json'
|
||||
frequency (string): Resample frequency
|
||||
"""
|
||||
url = self._get_url(ticker, frequency)
|
||||
params = {
|
||||
'format': fmt if fmt != "object" else 'json', # conversion local
|
||||
'resampleFreq': frequency
|
||||
"format": fmt if fmt != "object" else "json", # conversion local
|
||||
"resampleFreq": frequency,
|
||||
}
|
||||
|
||||
if startDate:
|
||||
params['startDate'] = startDate
|
||||
params["startDate"] = startDate
|
||||
if endDate:
|
||||
params['endDate'] = endDate
|
||||
params["endDate"] = endDate
|
||||
|
||||
# TODO: evaluate whether to stream CSV to cache on disk, or
|
||||
# load as array in memory, or just pass plain text
|
||||
response = self._request('GET', url, params=params)
|
||||
response = self._request("GET", url, params=params)
|
||||
if fmt == "json":
|
||||
return response.json()
|
||||
elif fmt == "object":
|
||||
@@ -245,241 +256,273 @@ class TiingoClient(RestClient):
|
||||
else:
|
||||
return response.content.decode("utf-8")
|
||||
|
||||
def get_dataframe(self, tickers,
|
||||
startDate=None, endDate=None, metric_name=None,
|
||||
frequency='daily', fmt='json'):
|
||||
def get_dataframe(
|
||||
self,
|
||||
tickers,
|
||||
startDate=None,
|
||||
endDate=None,
|
||||
metric_name=None,
|
||||
frequency="daily",
|
||||
fmt="json",
|
||||
):
|
||||
|
||||
""" Return a pandas.DataFrame of historical prices for one or more ticker symbols.
|
||||
"""Return a pandas.DataFrame of historical prices for one or more ticker symbols.
|
||||
|
||||
By default, return latest EOD Composite Price for a list of stock tickers.
|
||||
On average, each feed contains 3 data sources.
|
||||
By default, return latest EOD Composite Price for a list of stock tickers.
|
||||
On average, each feed contains 3 data sources.
|
||||
|
||||
Supported tickers + Available Day Ranges are here:
|
||||
https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip
|
||||
or from the TiingoClient.list_tickers() method.
|
||||
Supported tickers + Available Day Ranges are here:
|
||||
https://apimedia.tiingo.com/docs/tiingo/daily/supported_tickers.zip
|
||||
or from the TiingoClient.list_tickers() method.
|
||||
|
||||
Args:
|
||||
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.
|
||||
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,
|
||||
this parameter is required.
|
||||
frequency (string): Resample frequency (defaults to daily).
|
||||
fmt (string): 'csv' or 'json'
|
||||
Args:
|
||||
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.
|
||||
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,
|
||||
this parameter is required.
|
||||
frequency (string): Resample frequency (defaults to daily).
|
||||
fmt (string): 'csv' or 'json'
|
||||
"""
|
||||
|
||||
valid_columns = {'open', 'high', 'low', 'close', 'volume', 'adjOpen', 'adjHigh', 'adjLow',
|
||||
'adjClose', 'adjVolume', 'divCash', 'splitFactor'}
|
||||
valid_columns = {
|
||||
"open",
|
||||
"high",
|
||||
"low",
|
||||
"close",
|
||||
"volume",
|
||||
"adjOpen",
|
||||
"adjHigh",
|
||||
"adjLow",
|
||||
"adjClose",
|
||||
"adjVolume",
|
||||
"divCash",
|
||||
"splitFactor",
|
||||
}
|
||||
|
||||
if metric_name is not None and metric_name not in valid_columns:
|
||||
raise APIColumnNameError('Valid data items are: ' + str(valid_columns))
|
||||
raise APIColumnNameError("Valid data items are: " + str(valid_columns))
|
||||
|
||||
if metric_name is None and isinstance(tickers, list):
|
||||
raise MissingRequiredArgumentError("""When tickers is provided as a list, metric_name is a required argument.
|
||||
Please provide a metric_name, or call this method with one ticker at a time.""")
|
||||
raise MissingRequiredArgumentError(
|
||||
"""When tickers is provided as a list, metric_name is a required argument.
|
||||
Please provide a metric_name, or call this method with one ticker at a time."""
|
||||
)
|
||||
|
||||
params = {
|
||||
'format': fmt,
|
||||
'resampleFreq': frequency
|
||||
}
|
||||
params = {"format": fmt, "resampleFreq": frequency}
|
||||
if startDate:
|
||||
params['startDate'] = startDate
|
||||
params["startDate"] = startDate
|
||||
if endDate:
|
||||
params['endDate'] = endDate
|
||||
params["endDate"] = endDate
|
||||
|
||||
if pandas_is_installed:
|
||||
if type(tickers) is str:
|
||||
prices = self._request_pandas(
|
||||
ticker=tickers, params=params, metric_name=metric_name)
|
||||
ticker=tickers, params=params, metric_name=metric_name
|
||||
)
|
||||
else:
|
||||
prices = pd.DataFrame()
|
||||
for stock in tickers:
|
||||
ticker_series = self._request_pandas(
|
||||
ticker=stock, params=params, metric_name=metric_name)
|
||||
ticker=stock, params=params, metric_name=metric_name
|
||||
)
|
||||
ticker_series = ticker_series.rename(stock)
|
||||
prices = pd.concat([prices, ticker_series], axis=1, sort=True)
|
||||
|
||||
return prices
|
||||
|
||||
else:
|
||||
error_message = ("Pandas is not installed, but .get_ticker_price() was "
|
||||
"called with fmt=pandas. In order to install tiingo with "
|
||||
"pandas, reinstall with pandas as an optional dependency. \n"
|
||||
"Install tiingo with pandas dependency: \'pip install tiingo[pandas]\'\n"
|
||||
"Alternatively, just install pandas: pip install pandas.")
|
||||
error_message = (
|
||||
"Pandas is not installed, but .get_ticker_price() was "
|
||||
"called with fmt=pandas. In order to install tiingo with "
|
||||
"pandas, reinstall with pandas as an optional dependency. \n"
|
||||
"Install tiingo with pandas dependency: 'pip install tiingo[pandas]'\n"
|
||||
"Alternatively, just install pandas: pip install pandas."
|
||||
)
|
||||
raise InstallPandasException(error_message)
|
||||
|
||||
# NEWS FEEDS
|
||||
# tiingo/news
|
||||
def get_news(self, tickers=[], tags=[], sources=[], startDate=None,
|
||||
endDate=None, limit=100, offset=0, sortBy="publishedDate",
|
||||
onlyWithTickers=False,
|
||||
fmt='json'):
|
||||
def get_news(
|
||||
self,
|
||||
tickers=[],
|
||||
tags=[],
|
||||
sources=[],
|
||||
startDate=None,
|
||||
endDate=None,
|
||||
limit=100,
|
||||
offset=0,
|
||||
sortBy="publishedDate",
|
||||
onlyWithTickers=False,
|
||||
fmt="json",
|
||||
):
|
||||
"""Return list of news articles matching given search terms
|
||||
https://api.tiingo.com/docs/tiingo/news
|
||||
https://api.tiingo.com/docs/tiingo/news
|
||||
|
||||
# Dates are in YYYY-MM-DD Format.
|
||||
# Dates are in YYYY-MM-DD Format.
|
||||
|
||||
Args:
|
||||
tickers [string] : List of unique Stock Tickers to search
|
||||
tags [string] : List of topics tagged by Tiingo Algorithms
|
||||
sources [string]: List of base urls to include as news sources
|
||||
startDate, endDate [date]: Boundaries of news search window
|
||||
limit (int): Max results returned. Default 100, max 1000
|
||||
offset (int): Search results offset, used for paginating
|
||||
sortBy (string): "publishedDate" OR "crawlDate", descending
|
||||
onlyWithTickers (bool): If true, only links with tagged tickers will return.
|
||||
Args:
|
||||
tickers [string] : List of unique Stock Tickers to search
|
||||
tags [string] : List of topics tagged by Tiingo Algorithms
|
||||
sources [string]: List of base urls to include as news sources
|
||||
startDate, endDate [date]: Boundaries of news search window
|
||||
limit (int): Max results returned. Default 100, max 1000
|
||||
offset (int): Search results offset, used for paginating
|
||||
sortBy (string): "publishedDate" OR "crawlDate", descending
|
||||
onlyWithTickers (bool): If true, only links with tagged tickers will return.
|
||||
"""
|
||||
url = "tiingo/news"
|
||||
params = {
|
||||
'limit': limit,
|
||||
'offset': offset,
|
||||
'sortBy': sortBy,
|
||||
'tickers': tickers,
|
||||
'source': (",").join(sources) if sources else None,
|
||||
'tags': tags,
|
||||
'startDate': startDate,
|
||||
'endDate': endDate,
|
||||
'onlyWithTickers': onlyWithTickers
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"sortBy": sortBy,
|
||||
"tickers": tickers,
|
||||
"source": (",").join(sources) if sources else None,
|
||||
"tags": tags,
|
||||
"startDate": startDate,
|
||||
"endDate": endDate,
|
||||
"onlyWithTickers": onlyWithTickers,
|
||||
}
|
||||
response = self._request('GET', url, params=params)
|
||||
response = self._request("GET", url, params=params)
|
||||
data = response.json()
|
||||
if fmt == 'json':
|
||||
if fmt == "json":
|
||||
return data
|
||||
elif fmt == 'object':
|
||||
elif fmt == "object":
|
||||
return [dict_to_object(item, "NewsArticle") for item in data]
|
||||
|
||||
def get_bulk_news(self, file_id=None, fmt='json'):
|
||||
def get_bulk_news(self, file_id=None, fmt="json"):
|
||||
"""Only available to institutional clients.
|
||||
If ID is NOT provided, return array of available file_ids.
|
||||
If ID is provided, provides URL which you can use to download your
|
||||
file, as well as some metadata about that file.
|
||||
If ID is NOT provided, return array of available file_ids.
|
||||
If ID is provided, provides URL which you can use to download your
|
||||
file, as well as some metadata about that file.
|
||||
"""
|
||||
if file_id:
|
||||
url = "tiingo/news/bulk_download/{}".format(file_id)
|
||||
else:
|
||||
url = "tiingo/news/bulk_download"
|
||||
|
||||
response = self._request('GET', url)
|
||||
response = self._request("GET", url)
|
||||
data = response.json()
|
||||
if fmt == 'json':
|
||||
if fmt == "json":
|
||||
return data
|
||||
elif fmt == 'object':
|
||||
elif fmt == "object":
|
||||
return dict_to_object(data, "BulkNews")
|
||||
|
||||
# Crypto
|
||||
# tiingo/crypto
|
||||
def get_crypto_top_of_book(self, tickers=[], exchanges=[],
|
||||
includeRawExchangeData=False, convertCurrency=None):
|
||||
url = 'tiingo/crypto/top'
|
||||
params = {
|
||||
'tickers': ','.join(tickers)
|
||||
}
|
||||
def get_crypto_top_of_book(
|
||||
self,
|
||||
tickers=[],
|
||||
exchanges=[],
|
||||
includeRawExchangeData=False,
|
||||
convertCurrency=None,
|
||||
):
|
||||
url = "tiingo/crypto/top"
|
||||
params = {"tickers": ",".join(tickers)}
|
||||
|
||||
if len(exchanges):
|
||||
params['exchanges'] = ','.join(exchanges)
|
||||
params["exchanges"] = ",".join(exchanges)
|
||||
if includeRawExchangeData is True:
|
||||
params['includeRawExchangeData'] = True
|
||||
params["includeRawExchangeData"] = True
|
||||
if convertCurrency:
|
||||
params['convertCurrency'] = convertCurrency
|
||||
params["convertCurrency"] = convertCurrency
|
||||
|
||||
response = self._request('GET', url, params=params)
|
||||
response = self._request("GET", url, params=params)
|
||||
return response.json()
|
||||
|
||||
def get_crypto_price_history(self, tickers=[], baseCurrency=None,
|
||||
startDate=None, endDate=None, exchanges=[],
|
||||
consolidateBaseCurrency=False, includeRawExchangeData=False,
|
||||
resampleFreq=None, convertCurrency=None):
|
||||
url = 'tiingo/crypto/prices'
|
||||
params = {
|
||||
'tickers': ','.join(tickers)
|
||||
}
|
||||
def get_crypto_price_history(
|
||||
self,
|
||||
tickers=[],
|
||||
baseCurrency=None,
|
||||
startDate=None,
|
||||
endDate=None,
|
||||
exchanges=[],
|
||||
consolidateBaseCurrency=False,
|
||||
includeRawExchangeData=False,
|
||||
resampleFreq=None,
|
||||
convertCurrency=None,
|
||||
):
|
||||
url = "tiingo/crypto/prices"
|
||||
params = {"tickers": ",".join(tickers)}
|
||||
|
||||
if startDate:
|
||||
params['startDate'] = startDate
|
||||
params["startDate"] = startDate
|
||||
if endDate:
|
||||
params['endDate'] = endDate
|
||||
params["endDate"] = endDate
|
||||
if len(exchanges):
|
||||
params['exchanges'] = ','.join(exchanges)
|
||||
params["exchanges"] = ",".join(exchanges)
|
||||
if consolidateBaseCurrency is True:
|
||||
params['consolidateBaseCurrency'] = ','.join(consolidateBaseCurrency)
|
||||
params["consolidateBaseCurrency"] = ",".join(consolidateBaseCurrency)
|
||||
if includeRawExchangeData is True:
|
||||
params['includeRawExchangeData'] = includeRawExchangeData
|
||||
params["includeRawExchangeData"] = includeRawExchangeData
|
||||
if resampleFreq:
|
||||
params['resampleFreq'] = resampleFreq
|
||||
params["resampleFreq"] = resampleFreq
|
||||
if convertCurrency:
|
||||
params['convertCurrency'] = convertCurrency
|
||||
params["convertCurrency"] = convertCurrency
|
||||
|
||||
response = self._request('GET', url, params=params)
|
||||
response = self._request("GET", url, params=params)
|
||||
return response.json()
|
||||
|
||||
def get_crypto_metadata(self, tickers=[], fmt='json'):
|
||||
url = 'tiingo/crypto'
|
||||
def get_crypto_metadata(self, tickers=[], fmt="json"):
|
||||
url = "tiingo/crypto"
|
||||
|
||||
params = {
|
||||
'tickers': ','.join(tickers),
|
||||
'format': fmt,
|
||||
"tickers": ",".join(tickers),
|
||||
"format": fmt,
|
||||
}
|
||||
|
||||
response = self._request('GET', url, params=params)
|
||||
if fmt == 'csv':
|
||||
response = self._request("GET", url, params=params)
|
||||
if fmt == "csv":
|
||||
return response.content.decode("utf-8")
|
||||
else:
|
||||
return response.json()
|
||||
|
||||
# FUNDAMENTAL DEFINITIONS
|
||||
# tiingo/fundamentals/definitions
|
||||
def get_fundamentals_definitions(self, tickers=[], fmt='json'):
|
||||
def get_fundamentals_definitions(self, tickers=[], fmt="json"):
|
||||
"""Return definitions for fundamentals for specified tickers
|
||||
https://api.tiingo.com/documentation/fundamentals
|
||||
https://api.tiingo.com/documentation/fundamentals
|
||||
|
||||
Args:
|
||||
tickers [string] : optional, either list or string
|
||||
fmt (string): 'csv' or 'json'
|
||||
Args:
|
||||
tickers [string] : optional, either list or string
|
||||
fmt (string): 'csv' or 'json'
|
||||
"""
|
||||
url = "tiingo/fundamentals/definitions"
|
||||
params = {
|
||||
'tickers': tickers,
|
||||
'format': fmt
|
||||
}
|
||||
response = self._request('GET', url, params=params)
|
||||
if fmt == 'json':
|
||||
params = {"tickers": tickers, "format": fmt}
|
||||
response = self._request("GET", url, params=params)
|
||||
if fmt == "json":
|
||||
return response.json()
|
||||
elif fmt == 'csv':
|
||||
elif fmt == "csv":
|
||||
return response.content.decode("utf-8")
|
||||
|
||||
# FUNDAMENTAL DAILY
|
||||
# tiingo/fundamentals/<ticker>/daily
|
||||
def get_fundamentals_daily(self, ticker, fmt='json',
|
||||
startDate=None, endDate=None):
|
||||
def get_fundamentals_daily(self, ticker, fmt="json", startDate=None, endDate=None):
|
||||
"""Returns metrics which rely on daily price-updates
|
||||
https://api.tiingo.com/documentation/fundamentals
|
||||
https://api.tiingo.com/documentation/fundamentals
|
||||
|
||||
# Dates are in YYYY-MM-DD Format.
|
||||
# Dates are in YYYY-MM-DD Format.
|
||||
|
||||
Args:
|
||||
tickers [string] : List of unique Stock Tickers to search
|
||||
startDate, endDate [date]: Boundaries of search window
|
||||
fmt (string): 'csv' or 'json'
|
||||
Args:
|
||||
tickers [string] : List of unique Stock Tickers to search
|
||||
startDate, endDate [date]: Boundaries of search window
|
||||
fmt (string): 'csv' or 'json'
|
||||
"""
|
||||
url = 'tiingo/fundamentals/{}/daily'.format(ticker)
|
||||
params = {
|
||||
'startDate': startDate,
|
||||
'endDate': endDate,
|
||||
'format': fmt
|
||||
}
|
||||
response = self._request('GET', url, params=params)
|
||||
if fmt == 'json':
|
||||
url = "tiingo/fundamentals/{}/daily".format(ticker)
|
||||
params = {"startDate": startDate, "endDate": endDate, "format": fmt}
|
||||
response = self._request("GET", url, params=params)
|
||||
if fmt == "json":
|
||||
return response.json()
|
||||
elif fmt == 'csv':
|
||||
elif fmt == "csv":
|
||||
return response.content.decode("utf-8")
|
||||
|
||||
# FUNDAMENTAL STATEMENTS
|
||||
# tiingo/fundamentals/<ticker>/statements
|
||||
def get_fundamentals_statements(self, ticker, asReported=False, fmt='json',
|
||||
startDate=None, endDate=None):
|
||||
def get_fundamentals_statements(
|
||||
self, ticker, asReported=False, fmt="json", startDate=None, endDate=None
|
||||
):
|
||||
"""Returns data that is extracted from quarterly and annual statements.
|
||||
https://api.tiingo.com/documentation/fundamentals
|
||||
|
||||
@@ -494,19 +537,19 @@ class TiingoClient(RestClient):
|
||||
fmt (string): 'csv' or 'json'
|
||||
"""
|
||||
if asReported:
|
||||
asReported = 'true'
|
||||
asReported = "true"
|
||||
else:
|
||||
asReported = 'false'
|
||||
asReported = "false"
|
||||
|
||||
url = 'tiingo/fundamentals/{}/statements'.format(ticker)
|
||||
url = "tiingo/fundamentals/{}/statements".format(ticker)
|
||||
params = {
|
||||
'startDate': startDate,
|
||||
'endDate': endDate,
|
||||
'asReported': asReported,
|
||||
'format': fmt
|
||||
"startDate": startDate,
|
||||
"endDate": endDate,
|
||||
"asReported": asReported,
|
||||
"format": fmt,
|
||||
}
|
||||
response = self._request('GET', url, params=params)
|
||||
if fmt == 'json':
|
||||
response = self._request("GET", url, params=params)
|
||||
if fmt == "json":
|
||||
return response.json()
|
||||
elif fmt == 'csv':
|
||||
elif fmt == "csv":
|
||||
return response.content.decode("utf-8")
|
||||
|
||||
Reference in New Issue
Block a user