From a38e512ab872c9158f47d53de18271abd7873e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Hern=C3=A1ndez=20Calabr=C3=A9s?= Date: Thu, 15 Jul 2021 17:10:39 +0200 Subject: [PATCH 1/4] WIP: adding support for extracting etf information by etf symbol --- investpy/etfs.py | 68 ++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/investpy/etfs.py b/investpy/etfs.py index 4c0fb9e..52f0c49 100644 --- a/investpy/etfs.py +++ b/investpy/etfs.py @@ -157,15 +157,17 @@ def get_etf_countries(): return etf_countries_as_list() -def get_etf_recent_data(etf, country, stock_exchange=None, as_json=False, order='ascending', interval='Daily'): +def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_json=False, order='ascending', interval='Daily'): """ This function retrieves recent historical data from the introduced `etf` from Investing via Web Scraping. The resulting data can it either be stored in a :obj:`pandas.DataFrame` or in a :obj:`json` file, with `ascending` or `descending` order. Args: - etf (:obj:`str`): name of the etf to retrieve recent historical data from. + etf (:obj:`str`): name or symbol of the etf to retrieve recent historical data from. country (:obj:`str`): name of the country from where the etf is. + is_symbol (:obj:`bool`, optional): + determine wether the etf is searched by its name or by its symbol. as_json (:obj:`bool`, optional): optional argument to determine the format of the output data (:obj:`pandas.DataFrame` or :obj:`json`). order (:obj:`str`, optional): @@ -271,16 +273,18 @@ def get_etf_recent_data(etf, country, stock_exchange=None, as_json=False, order= if country not in get_etf_countries(): raise RuntimeError("ERR#0034: country " + country + " not found, check if it is correct.") + etfs = etfs[etfs['country'].str.lower() == country] + etf = unidecode(etf.strip().lower()) - def_exchange = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] - - etfs = etfs[etfs['country'].str.lower() == country] + name_access = 'symbol' if is_symbol else 'name' - if etf not in list(etfs['name'].apply(unidecode).str.lower()): + def_exchange = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] + + if etf not in list(etfs[name_access].apply(unidecode).str.lower()): raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - etfs = etfs[etfs['name'].apply(unidecode).str.lower() == etf] + etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] if def_exchange['country'] != country: warnings.warn( @@ -296,7 +300,7 @@ def get_etf_recent_data(etf, country, stock_exchange=None, as_json=False, order= etf_exchange = etfs.loc[(etfs['stock_exchange'].str.lower() == stock_exchange.lower()).idxmax(), 'stock_exchange'] else: - found_etfs = etfs[etfs['name'].apply(unidecode).str.lower() == etf] + found_etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] if len(found_etfs) > 1: warnings.warn( @@ -307,7 +311,7 @@ def get_etf_recent_data(etf, country, stock_exchange=None, as_json=False, order= del found_etfs - etf_exchange = etfs.loc[(etfs['name'].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] + etf_exchange = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] else: if stock_exchange: if stock_exchange.lower() not in etfs['stock_exchange'].str.lower(): @@ -325,11 +329,11 @@ def get_etf_recent_data(etf, country, stock_exchange=None, as_json=False, order= else: etf_exchange = def_exchange['stock_exchange'] - symbol = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] - id_ = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] - name = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'name'] + symbol = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] + id_ = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] + name = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), name_access] - etf_currency = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] + etf_currency = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] header = symbol + ' Historical Data' @@ -407,17 +411,19 @@ def get_etf_recent_data(etf, country, stock_exchange=None, as_json=False, order= raise RuntimeError("ERR#0004: data retrieval error while scraping.") -def get_etf_historical_data(etf, country, from_date, to_date, stock_exchange=None, as_json=False, order='ascending', interval='Daily'): +def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, stock_exchange=None, as_json=False, order='ascending', interval='Daily'): """ This function retrieves historical data from the introduced `etf` from Investing.com via Web Scraping on the introduced date range. The resulting data can it either be stored in a :obj:`pandas.DataFrame` or in a :obj:`json` object with `ascending` or `descending` order. Args: - etf (:obj:`str`): name of the etf to retrieve recent historical data from. + etf (:obj:`str`): name or symbol of the etf to retrieve recent historical data from. country (:obj:`str`): name of the country from where the etf is. from_date (:obj:`str`): date as `str` formatted as `dd/mm/yyyy`, from where data is going to be retrieved. to_date (:obj:`str`): date as `str` formatted as `dd/mm/yyyy`, until where data is going to be retrieved. + is_symbol (:obj:`bool`, optional): + determine wether the etf is searched by its name or by its symbol. as_json (:obj:`bool`, optional): to determine the format of the output data (:obj:`pandas.DataFrame` or :obj:`json`). order (:obj:`str`, optional): @@ -574,14 +580,16 @@ def get_etf_historical_data(etf, country, from_date, to_date, stock_exchange=Non etf = unidecode(etf.strip().lower()) - def_exchange = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] + name_access = 'symbol' if is_symbol else 'name' + + def_exchange = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] etfs = etfs[etfs['country'].str.lower() == country] - if etf not in list(etfs['name'].apply(unidecode).str.lower()): + if etf not in list(etfs[name_access].apply(unidecode).str.lower()): raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - etfs = etfs[etfs['name'].apply(unidecode).str.lower() == etf] + etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] if def_exchange['country'] != country: warnings.warn( @@ -597,7 +605,7 @@ def get_etf_historical_data(etf, country, from_date, to_date, stock_exchange=Non etf_exchange = etfs.loc[(etfs['stock_exchange'].str.lower() == stock_exchange.lower()).idxmax(), 'stock_exchange'] else: - found_etfs = etfs[etfs['name'].apply(unidecode).str.lower() == etf] + found_etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] if len(found_etfs) > 1: warnings.warn( @@ -608,7 +616,7 @@ def get_etf_historical_data(etf, country, from_date, to_date, stock_exchange=Non del found_etfs - etf_exchange = etfs.loc[(etfs['name'].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] + etf_exchange = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] else: if stock_exchange: if stock_exchange.lower() not in etfs['stock_exchange'].str.lower(): @@ -626,11 +634,11 @@ def get_etf_historical_data(etf, country, from_date, to_date, stock_exchange=Non else: etf_exchange = def_exchange['stock_exchange'] - symbol = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] - id_ = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] - name = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'name'] + symbol = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] + id_ = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] + name = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), name_access] - etf_currency = etfs.loc[((etfs['name'].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] + etf_currency = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] final = list() @@ -733,15 +741,17 @@ def get_etf_historical_data(etf, country, from_date, to_date, stock_exchange=Non return pd.concat(final) -def get_etf_information(etf, country, as_json=False): +def get_etf_information(etf, country, is_symbol=False, as_json=False): """ This function retrieves fundamental financial information from the specified ETF. The retrieved information from the ETF can be valuable as it is additional information that can be used combined with OHLC values, so to determine financial insights from the company which holds the specified ETF. Args: - etf (:obj:`str`): name of the ETF to retrieve recent historical data from. + etf (:obj:`str`): name or symbol of the ETF to retrieve recent historical data from. country (:obj:`str`): name of the country from where the ETF is. + is_symbol (:obj:`bool`, optional): + determine wether the etf is searched by its name or by its symbol. as_json (:obj:`bool`, optional): optional argument to determine the format of the output data (:obj:`dict` or :obj:`json`). @@ -818,8 +828,10 @@ def get_etf_information(etf, country, as_json=False): if etf not in list(etfs['name'].apply(unidecode).str.lower()): raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - name = etfs.loc[(etfs['name'].apply(unidecode).str.lower() == etf).idxmax(), 'name'] - tag = etfs.loc[(etfs['name'].apply(unidecode).str.lower() == etf).idxmax(), 'tag'] + name_access = 'symbol' if is_symbol else 'name' + + name = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), name_access] + tag = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), 'tag'] url = "https://www.investing.com/etfs/" + tag From 5e1ebb442b2d475b1f91352f09c66a34a2ab270c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Hern=C3=A1ndez=20Calabr=C3=A9s?= Date: Fri, 16 Jul 2021 10:31:13 +0200 Subject: [PATCH 2/4] Added tests for the search etfs by symbol feature --- investpy/etfs.py | 50 ++++++++------- tests/test_investpy.py | 54 +++++++++++++++- tests/test_investpy_errors.py | 112 +++++++++++++++++++++++++++++++++- 3 files changed, 189 insertions(+), 27 deletions(-) diff --git a/investpy/etfs.py b/investpy/etfs.py index 52f0c49..9e40060 100644 --- a/investpy/etfs.py +++ b/investpy/etfs.py @@ -168,6 +168,8 @@ def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_j country (:obj:`str`): name of the country from where the etf is. is_symbol (:obj:`bool`, optional): determine wether the etf is searched by its name or by its symbol. + stock_exchange (:obj:`str`, optional): + optional argument to filter the results by the stock exchange field. as_json (:obj:`bool`, optional): optional argument to determine the format of the output data (:obj:`pandas.DataFrame` or :obj:`json`). order (:obj:`str`, optional): @@ -277,14 +279,14 @@ def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_j etf = unidecode(etf.strip().lower()) - name_access = 'symbol' if is_symbol else 'name' + search_field = 'symbol' if is_symbol else 'name' - def_exchange = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] + def_exchange = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] - if etf not in list(etfs[name_access].apply(unidecode).str.lower()): + if etf not in list(etfs[search_field].apply(unidecode).str.lower()): raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] + etfs = etfs[etfs[search_field].apply(unidecode).str.lower() == etf] if def_exchange['country'] != country: warnings.warn( @@ -300,7 +302,7 @@ def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_j etf_exchange = etfs.loc[(etfs['stock_exchange'].str.lower() == stock_exchange.lower()).idxmax(), 'stock_exchange'] else: - found_etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] + found_etfs = etfs[etfs[search_field].apply(unidecode).str.lower() == etf] if len(found_etfs) > 1: warnings.warn( @@ -311,7 +313,7 @@ def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_j del found_etfs - etf_exchange = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] + etf_exchange = etfs.loc[(etfs[search_field].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] else: if stock_exchange: if stock_exchange.lower() not in etfs['stock_exchange'].str.lower(): @@ -329,11 +331,11 @@ def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_j else: etf_exchange = def_exchange['stock_exchange'] - symbol = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] - id_ = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] - name = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), name_access] + symbol = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] + id_ = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] + name = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), search_field] - etf_currency = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] + etf_currency = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] header = symbol + ' Historical Data' @@ -424,6 +426,8 @@ def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, s to_date (:obj:`str`): date as `str` formatted as `dd/mm/yyyy`, until where data is going to be retrieved. is_symbol (:obj:`bool`, optional): determine wether the etf is searched by its name or by its symbol. + stock_exchange (:obj:`str`, optional): + optional argument to filter the results by the stock exchange field. as_json (:obj:`bool`, optional): to determine the format of the output data (:obj:`pandas.DataFrame` or :obj:`json`). order (:obj:`str`, optional): @@ -580,16 +584,16 @@ def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, s etf = unidecode(etf.strip().lower()) - name_access = 'symbol' if is_symbol else 'name' + search_field = 'symbol' if is_symbol else 'name' - def_exchange = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] + def_exchange = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['def_stock_exchange'] == True)).idxmax()] etfs = etfs[etfs['country'].str.lower() == country] - if etf not in list(etfs[name_access].apply(unidecode).str.lower()): + if etf not in list(etfs[search_field].apply(unidecode).str.lower()): raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] + etfs = etfs[etfs[search_field].apply(unidecode).str.lower() == etf] if def_exchange['country'] != country: warnings.warn( @@ -605,7 +609,7 @@ def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, s etf_exchange = etfs.loc[(etfs['stock_exchange'].str.lower() == stock_exchange.lower()).idxmax(), 'stock_exchange'] else: - found_etfs = etfs[etfs[name_access].apply(unidecode).str.lower() == etf] + found_etfs = etfs[etfs[search_field].apply(unidecode).str.lower() == etf] if len(found_etfs) > 1: warnings.warn( @@ -616,7 +620,7 @@ def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, s del found_etfs - etf_exchange = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] + etf_exchange = etfs.loc[(etfs[search_field].apply(unidecode).str.lower() == etf).idxmax(), 'stock_exchange'] else: if stock_exchange: if stock_exchange.lower() not in etfs['stock_exchange'].str.lower(): @@ -634,11 +638,11 @@ def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, s else: etf_exchange = def_exchange['stock_exchange'] - symbol = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] - id_ = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] - name = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), name_access] + symbol = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'symbol'] + id_ = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'id'] + name = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), search_field] - etf_currency = etfs.loc[((etfs[name_access].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] + etf_currency = etfs.loc[((etfs[search_field].apply(unidecode).str.lower() == etf) & (etfs['stock_exchange'].str.lower() == etf_exchange.lower())).idxmax(), 'currency'] final = list() @@ -828,10 +832,10 @@ def get_etf_information(etf, country, is_symbol=False, as_json=False): if etf not in list(etfs['name'].apply(unidecode).str.lower()): raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - name_access = 'symbol' if is_symbol else 'name' + search_field = 'symbol' if is_symbol else 'name' - name = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), name_access] - tag = etfs.loc[(etfs[name_access].apply(unidecode).str.lower() == etf).idxmax(), 'tag'] + name = etfs.loc[(etfs[search_field].apply(unidecode).str.lower() == etf).idxmax(), search_field] + tag = etfs.loc[(etfs[search_field].apply(unidecode).str.lower() == etf).idxmax(), 'tag'] url = "https://www.investing.com/etfs/" + tag diff --git a/tests/test_investpy.py b/tests/test_investpy.py index edc2bf4..f6ddb77 100644 --- a/tests/test_investpy.py +++ b/tests/test_investpy.py @@ -402,32 +402,66 @@ def test_investpy_etfs(): params = [ { + 'etf': 'bbva accion dj eurostoxx 50', + 'is_symbol': False, + 'as_json': True, + 'order': 'ascending', + }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'is_symbol': False, + 'as_json': False, + 'order': 'ascending', + }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'is_symbol': False, + 'as_json': True, + 'order': 'descending', + }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'is_symbol': False, + 'as_json': False, + 'order': 'descending', + }, + { + 'etf': 'bbvae', + 'is_symbol': True, 'as_json': True, 'order': 'ascending', }, { + 'etf': 'bbvae', + 'is_symbol': True, 'as_json': False, 'order': 'ascending', }, { + 'etf': 'bbvae', + 'is_symbol': True, 'as_json': True, 'order': 'descending', }, { + 'etf': 'bbvae', + 'is_symbol': True, 'as_json': False, 'order': 'descending', }, ] for param in params: - investpy.get_etf_recent_data(etf='bbva accion dj eurostoxx 50', + investpy.get_etf_recent_data(etf=param['etf'], country='spain', + is_symbol=param['is_symbol'], as_json=param['as_json'], order=param['order'], interval='Daily') - investpy.get_etf_historical_data(etf='bbva accion dj eurostoxx 50', + investpy.get_etf_historical_data(etf=param['etf'], country='spain', + is_symbol=param['is_symbol'], from_date='01/01/2010', to_date='01/01/2019', as_json=param['as_json'], @@ -437,18 +471,32 @@ def test_investpy_etfs(): params = [ { 'etf': 'bbva accion dj eurostoxx 50', + 'is_symbol': False, 'country': 'spain', 'as_json': False }, { 'etf': 'bbva accion dj eurostoxx 50', + 'is_symbol': False, + 'country': 'spain', + 'as_json': True + }, + { + 'etf': 'bbvae', + 'is_symbol': True, + 'country': 'spain', + 'as_json': False + }, + { + 'etf': 'bbvae', + 'is_symbol': True, 'country': 'spain', 'as_json': True } ] for param in params: - investpy.get_etf_information(etf=param['etf'], country=param['country'], as_json=param['as_json']) + investpy.get_etf_information(etf=param['etf'], is_symbol=param['is_symbol'], country=param['country'], as_json=param['as_json']) params = [ { diff --git a/tests/test_investpy_errors.py b/tests/test_investpy_errors.py index 0d0b2f4..0d9db9c 100644 --- a/tests/test_investpy_errors.py +++ b/tests/test_investpy_errors.py @@ -1163,6 +1163,7 @@ def test_etfs_errors(): { 'etf': None, 'country': 'spain', + 'is_symbol': False, 'as_json': False, 'order': 'ascending', 'interval': 'Daily' @@ -1170,6 +1171,7 @@ def test_etfs_errors(): { 'etf': ['error'], 'country': 'spain', + 'is_symbol': False, 'as_json': False, 'order': 'ascending', 'interval': 'Daily' @@ -1177,6 +1179,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': None, + 'is_symbol': False, 'as_json': False, 'order': 'ascending', 'interval': 'Daily' @@ -1184,6 +1187,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'error', + 'is_symbol': False, 'as_json': False, 'order': 'ascending', 'interval': 'Daily' @@ -1191,6 +1195,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'netherlands', + 'is_symbol': False, 'as_json': False, 'order': 'ascending', 'interval': 'Daily' @@ -1198,6 +1203,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': ['error'], + 'is_symbol': False, 'as_json': False, 'order': 'ascending', 'interval': 'Daily' @@ -1205,6 +1211,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'as_json': 'error', 'order': 'ascending', 'interval': 'Daily' @@ -1212,6 +1219,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'as_json': True, 'order': 'error', 'interval': 'Daily' @@ -1219,6 +1227,7 @@ def test_etfs_errors(): { 'etf': 'error', 'country': 'spain', + 'is_symbol': False, 'as_json': True, 'order': 'ascending', 'interval': 'Daily' @@ -1226,6 +1235,7 @@ def test_etfs_errors(): { 'etf': ['error'], 'country': 'spain', + 'is_symbol': False, 'as_json': True, 'order': 'ascending', 'interval': 'Daily' @@ -1233,6 +1243,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'as_json': True, 'order': 'ascending', 'interval': None @@ -1240,6 +1251,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'as_json': True, 'order': 'ascending', 'interval': ['error'] @@ -1247,16 +1259,42 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'as_json': True, 'order': 'ascending', 'interval': 'error' }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'country': 'spain', + 'is_symbol': True, + 'as_json': True, + 'order': 'ascending', + 'interval': 'Daily' + }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'country': 'spain', + 'is_symbol': 'error', + 'as_json': True, + 'order': 'ascending', + 'interval': 'Daily' + }, + { + 'etf': 'bbvae', + 'country': 'spain', + 'is_symbol': False, + 'as_json': True, + 'order': 'ascending', + 'interval': 'Daily' + }, ] for param in params: try: investpy.get_etf_recent_data(etf=param['etf'], country=param['country'], + is_symbol=param['is_symbol'], as_json=param['as_json'], order=param['order'], interval=param['interval']) @@ -1267,6 +1305,7 @@ def test_etfs_errors(): { 'etf': None, 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1276,6 +1315,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'error', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1285,6 +1325,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'netherlands', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1294,6 +1335,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': None, + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1303,6 +1345,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': ['error'], + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1312,6 +1355,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': 'error', @@ -1321,6 +1365,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1330,6 +1375,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': 'error', 'to_date': '01/01/2019', 'as_json': False, @@ -1339,6 +1385,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2019', 'to_date': 'error', 'as_json': False, @@ -1348,6 +1395,7 @@ def test_etfs_errors(): { 'etf': 'error', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1357,6 +1405,7 @@ def test_etfs_errors(): { 'etf': ['error'], 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2018', 'to_date': '01/01/2019', 'as_json': False, @@ -1366,6 +1415,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/1998', 'to_date': '01/01/2019', 'as_json': False, @@ -1375,6 +1425,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2019', 'to_date': '01/01/1998', 'as_json': False, @@ -1384,6 +1435,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/1900', 'to_date': '01/01/1950', 'as_json': False, @@ -1393,6 +1445,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2019', 'to_date': '01/03/2019', 'as_json': True, @@ -1402,6 +1455,7 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2019', 'to_date': '01/03/2019', 'as_json': True, @@ -1411,18 +1465,50 @@ def test_etfs_errors(): { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'from_date': '01/01/2019', 'to_date': '01/03/2019', 'as_json': True, 'order': 'ascending', 'interval': 'error' }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'country': 'spain', + 'is_symbol': True, + 'from_date': '01/01/2019', + 'to_date': '01/03/2019', + 'as_json': True, + 'order': 'ascending', + 'interval': 'Daily' + }, + { + 'etf': 'bbvae', + 'country': 'spain', + 'is_symbol': False, + 'from_date': '01/01/2019', + 'to_date': '01/03/2019', + 'as_json': True, + 'order': 'ascending', + 'interval': 'Daily' + }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'country': 'spain', + 'is_symbol': 'error', + 'from_date': '01/01/2019', + 'to_date': '01/03/2019', + 'as_json': True, + 'order': 'ascending', + 'interval': 'Daily' + }, ] for param in params: try: investpy.get_etf_historical_data(etf=param['etf'], country=param['country'], + is_symbol=param['is_symbol'], from_date=param['from_date'], to_date=param['to_date'], as_json=param['as_json'], @@ -1435,38 +1521,62 @@ def test_etfs_errors(): { 'etf': None, 'country': 'spain', + 'is_symbol': False, 'as_json': False }, { 'etf': ['error'], 'country': 'spain', + 'is_symbol': False, 'as_json': False }, { 'etf': 'bbva accion dj eurostoxx 50', 'country': None, + 'is_symbol': False, 'as_json': False }, { 'etf': 'bbva accion dj eurostoxx 50', 'country': ['error'], + 'is_symbol': False, 'as_json': False }, { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'spain', + 'is_symbol': False, 'as_json': None }, { 'etf': 'bbva accion dj eurostoxx 50', 'country': 'error', + 'is_symbol': False, + 'as_json': False + }, + { + 'etf': 'bbva accion dj eurostoxx 50', + 'country': 'spain', + 'is_symbol': True, + 'as_json': False + }, + { + 'etf': 'bbvae', + 'country': 'spain', + 'is_symbol': False, + 'as_json': False + }, + { + 'etf': 'bbvae', + 'country': 'spain', + 'is_symbol': 'error', 'as_json': False }, ] for param in params: try: - investpy.get_etf_information(etf=param['etf'], country=param['country'], as_json=param['as_json']) + investpy.get_etf_information(etf=param['etf'], country=param['country'], is_symbol=param['is_symbol'], as_json=param['as_json']) except: pass From 5cef1499993df7c30c80123ba922a1c7529f8cec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Hern=C3=A1ndez=20Calabr=C3=A9s?= Date: Fri, 16 Jul 2021 10:56:34 +0200 Subject: [PATCH 3/4] Added error checking for etf search by symbol --- investpy/etfs.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/investpy/etfs.py b/investpy/etfs.py index 9e40060..d2266a9 100644 --- a/investpy/etfs.py +++ b/investpy/etfs.py @@ -240,6 +240,9 @@ def get_etf_recent_data(etf, country, is_symbol=False, stock_exchange=None, as_j if country is not None and not isinstance(country, str): raise ValueError("ERR#0025: specified country value not valid.") + if not isinstance(is_symbol, bool): + raise ValueError("ERR#0139: is_symbol argument can just be True or False (default), bool type.") + if stock_exchange is not None and not isinstance(stock_exchange, str): raise ValueError("ERR#0125: specified stock_exchange value is not valid, it should be a str.") @@ -498,6 +501,9 @@ def get_etf_historical_data(etf, country, from_date, to_date, is_symbol=False, s if country is not None and not isinstance(country, str): raise ValueError("ERR#0025: specified country value not valid.") + if not isinstance(is_symbol, bool): + raise ValueError("ERR#0139: is_symbol argument can just be True or False (default), bool type.") + if stock_exchange is not None and not isinstance(stock_exchange, str): raise ValueError("ERR#0125: specified stock_exchange value is not valid, it should be a str.") @@ -807,6 +813,9 @@ def get_etf_information(etf, country, is_symbol=False, as_json=False): if country is not None and not isinstance(country, str): raise ValueError("ERR#0025: specified country value not valid.") + if not isinstance(is_symbol, bool): + raise ValueError("ERR#0139: is_symbol argument can just be True or False (default), bool type.") + if not isinstance(as_json, bool): raise ValueError("ERR#0002: as_json argument can just be True or False, bool type.") From 02fe85e48c48e75df8f713355198dfc025efe85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20Hern=C3=A1ndez=20Calabr=C3=A9s?= Date: Fri, 16 Jul 2021 11:31:41 +0200 Subject: [PATCH 4/4] Minor buf fixed on etf retrieval with symbol --- investpy/etfs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/investpy/etfs.py b/investpy/etfs.py index d2266a9..2301715 100644 --- a/investpy/etfs.py +++ b/investpy/etfs.py @@ -838,11 +838,11 @@ def get_etf_information(etf, country, is_symbol=False, as_json=False): etf = unidecode(etf.strip().lower()) - if etf not in list(etfs['name'].apply(unidecode).str.lower()): - raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") - search_field = 'symbol' if is_symbol else 'name' + if etf not in list(etfs[search_field].apply(unidecode).str.lower()): + raise RuntimeError("ERR#0019: etf " + etf + " not found, check if it is correct.") + name = etfs.loc[(etfs[search_field].apply(unidecode).str.lower() == etf).idxmax(), search_field] tag = etfs.loc[(etfs[search_field].apply(unidecode).str.lower() == etf).idxmax(), 'tag']