Comments (8)
Hi @2xmm , thanks for filing this and organizing this proposal based on our discussions in this recent PR.
I think adding these two new methods you propose (get_daily_data
and get_iex_data
) without the connotations of dataframe
makes sense. Given the multiple factors performance improvement with csv
format compared to JSON, I think that opting for CSV format by default is well worthwhile.
If it turns out people have a strong need for the JSON format's timezone offsets for intraday data, they can still use the non-convenience mechanism (i.e. get_ticker_price
) to request JSON format. Using CSV as the first-class network exchange format is a good simplicity <> comprehensiveness trade given the purpose of these _data
methods is to provide good defaults for people wanting to get into doing data analysis quickly. We can talk to @tiingo at a later date to see if they may consider including timezone offsets in CSV format with the inclusion of a URL parameter in future releases.
from tiingo-python.
Sounds good to me, personally. I finally have a few moments to start looking into this code a bit more and see where I can help with the project.
from tiingo-python.
@GenusGeoff Feel free to work on this if you are interested.
from tiingo-python.
@2xmm This looks like it's already implemented in the most recent code with the switch "fmt='csv'". Great work to @hydrosquall or to whomever took this one up.
from tiingo-python.
Hi @GenusGeoff ! @2xmm generously implemented the "fmt = 'csv'"
option in get_dataframe
in #524 .
I think the change request described in this issue is specifically for adding 2 new methods to the library, get_daily_data
and get_iex_data
.
from tiingo-python.
Please forgive my lack of understanding on the pull/fork/merge type thing. I've included some changes to api.py below. They're extremely rough but they do what is requested. Comments and all might need to be cleaned up a bit, though.
It's a simple fix that just borrows much of the code from the existing get_dataframe() function.
`####################### BEGIN Modifications (GenusGeoff)
### Add get_daily_data and get_iex_data
###
### The suffix _data is more appropriate in this case because if a metric_name is passed then the method returns a
### pandas.Series not a pandas.DataFrame.
###
# Get Daily Data
def get_daily_data(self, tickers,
startDate=None, endDate=None, metric_name=None,
frequency='daily', fmt='csv'):
""" Returns historical prices for one or more ticker symbols.
By default, return latest EOD Composite Adjusted Closing 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.
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'}
if metric_name is not None and metric_name not in 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.""")
params = {
'format': fmt,
'resampleFreq': frequency
}
if startDate:
params['startDate'] = startDate
if 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)
else:
prices = pd.DataFrame()
for stock in tickers:
ticker_series = self._request_pandas(
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.")
raise InstallPandasException(error_message)
## Get IEX Data
def get_iex_data(self, tickers,
startDate=None, endDate=None, metric_name=None,
frequency='1hour', fmt='csv'):
""" 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.
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'
"""
valid_columns = {'open', 'high', 'low', 'close', 'volume'}
if metric_name is not None and metric_name not in 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.""")
params = {
'format': fmt,
'resampleFreq': frequency
}
if startDate:
params['startDate'] = startDate
if 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)
else:
prices = pd.DataFrame()
for stock in tickers:
ticker_series = self._request_pandas(
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.")
raise InstallPandasException(error_message)
### End of Modifications (GenusGeoff)`
from tiingo-python.
This is a bit more to add the IEX afterHours quotes to this code. BTW--Apparently, Tiingo requires True and False to be lowercase in the request which is incompatible with Python. A possible workaround might be to create a literal variable, e.g. true, false = (True, False); but I've no idea what unintended consequences might arise.
`## Get IEX Data
def get_iex_data(self, tickers,
startDate=None, endDate=None, metric_name=None, afterHours='false',
frequency='1hour', fmt='csv'):
""" 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.
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.
afterHours (boolean): Optional parameter that selects whether to include extended hours quotes NOTE: MUST BE LOWERCASE
AND THEREFORE ENCAPSULTED, e.g. 'true' or 'false'
frequency (string): Resample frequency (defaults to daily).
fmt (string): 'csv' or 'json'
"""
valid_columns = {'open', 'high', 'low', 'close', 'volume'}
if metric_name is not None and metric_name not in 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.""")
params = {
'format': fmt,
'resampleFreq': frequency,
'afterHours': afterHours
}
if startDate:
params['startDate'] = startDate
if 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)
else:
prices = pd.DataFrame()
for stock in tickers:
ticker_series = self._request_pandas(
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.")
raise InstallPandasException(error_message)
`
from tiingo-python.
Hi @GenusGeoff,
Glad you were able to make a contribution to this project. It's a great exercise to work through submitting a pull request and you can find out how to do so in the CONTRIBUTING.rst
file in the root directory of this project. If you have any issues submitting the request feel free to comment here and I'll help you out.
from tiingo-python.
Related Issues (20)
- [documentation] Update README with usage examples for crypto endpoint HOT 4
- [Enhancement] Add option to request data in csv format in get_dataframe method HOT 3
- [Enhancement] Add afterHours parameter to IEX intraday requests HOT 4
- [Enhancement] tngoLast added to IEX Intraday Quotes Acceptable Fields HOT 1
- get_dataframe throws KeyError 'date' when one or more tickers has no data to return in the timeframe HOT 4
- Feature request - get_last_price(tickers) HOT 2
- get_news() fails when no sources are specified. HOT 2
- [Deprecation WARNING] Collections HOT 2
- [Enhancement/Bug Fix] Tiingo Backend Uses JSON Which Conflicts With Python Boolean Calls HOT 5
- [platform] End support for Python 2 + Python 3.5 HOT 2
- Index Data? HOT 2
- CCU empty volume? HOT 1
- Intraday code gets confused by daylight savings timezone cutover HOT 2
- (api) per-minute data not available for SSE and SZSE HOT 3
- Ticker data wrong values and jumps using `get_dataframe()` HOT 1
- [build] Remove pytest-runner from setup configuration requirements
- Multiple tags using Tiingo News API HOT 1
- About Tiingo News HOT 1
- cannot import name 'TiingoClient' from 'tiingo' HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tiingo-python.