diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml
index b809ac18..4e02728f 100644
--- a/.github/workflows/run_tests.yml
+++ b/.github/workflows/run_tests.yml
@@ -14,7 +14,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
- python-version: [3.6, 3.7, 3.8, 3.9]
+ python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout@v2
diff --git a/README.md b/README.md
index 9fafc9d8..68584e69 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,8 @@
Financial Data Extraction from Investing.com with Python
investpy is a Python package to retrieve data from [Investing.com](https://www.investing.com/), which provides data retrieval
-from up to: 39952 stocks, 82221 funds, 11403 ETFs, 2029 currency crosses, 7797 indices, 688 bonds, 66 commodities, 250 certificates,
-and 2812 cryptocurrencies.
+from up to 39952 stocks, 82221 funds, 11403 ETFs, 2029 currency crosses, 7797 indices, 688 bonds, 66 commodities, 250 certificates,
+and 4697 cryptocurrencies.
investpy allows the user to download both recent and historical data from all the financial products indexed at Investing.com.
**It includes data from all over the world**, from countries such as United States, France, India, Spain, Russia, or Germany,
@@ -51,6 +51,9 @@ some basic functionality will be sorted out with sample Python code blocks. Addi
can be found under [examples/](https://github.com/alvarobartt/investpy/tree/master/examples) directory, which
contains a collection of Jupyter Notebooks on how to use investpy and handle its data.
+:pushpin: __Note that `investpy.search_quotes` is the only function that ensures that the data is updated and aligned 1:1 with
+the data provided by Investing.com!__
+
### :chart_with_upwards_trend: Recent/Historical Data Retrieval
investpy allows the user to **download both recent and historical data from any financial product indexed**
@@ -79,7 +82,7 @@ Date
To get to know all the available recent and historical data extraction functions provided by
investpy, and also, parameter tuning, please read the docs.
-### :mag: Search Data
+### :mag: Search Live Data
**Investing.com search engine is completely integrated** with investpy, which means that any available
financial product (quote) can be easily found. The search function allows the user to tune the parameters
@@ -90,34 +93,98 @@ presented in the following piece of code:
```python
import investpy
-search_results = investpy.search_quotes(text='apple',
- products=['stocks'],
- countries=['united states'],
- n_results=10)
+search_result = investpy.search_quotes(text='apple', products=['stocks'],
+ countries=['united states'], n_results=1)
+print(search_result)
```
+```{r, engine='python', count_lines}
+{"id_": 6408, "name": "Apple Inc", "symbol": "AAPL", "country": "united states", "tag": "/equities/apple-computer-inc", "pair_type": "stocks", "exchange": "NASDAQ"}
-Retrieved search results will be a `list` of `investpy.utils.search_obj.SearchObj` class instances. To get to know
-which are the available functions and attributes of the returned search results, please read the related
+```
+
+Retrieved search results will be a `list` of `investpy.utils.search_obj.SearchObj` class instances, unless
+`n_results` is set to 1, when just a single `investpy.utils.search_obj.SearchObj` class instance will be returned.
+To get to know which are the available functions and attributes of the returned search results, please read the related
documentation at [Search Engine Documentation](https://investpy.readthedocs.io/search_api.html). So on, those
-search results let the user retrieve both recent and historical data from that concrete product, its
-information, etc., as presented in the piece of code below:
+search results let the user retrieve both recent and historical data, its information, the technical indicators,
+the default currency, etc., as presented in the pieces of code below:
+
+#### Recent Data
+
+```python
+recent_data = search_result.retrieve_recent_data()
+print(recent_data.head())
+```
+```{r, engine='python', count_lines}
+ Open High Low Close Volume Change Pct
+Date
+2021-05-13 124.58 126.15 124.26 124.97 105861000 1.79
+2021-05-14 126.25 127.89 125.85 127.45 81918000 1.98
+2021-05-17 126.82 126.93 125.17 126.27 74245000 -0.93
+2021-05-18 126.56 126.99 124.78 124.85 63343000 -1.12
+2021-05-19 123.16 124.92 122.86 124.69 92612000 -0.13
+
+```
+
+#### Historical Data
+
+```python
+historical_data = search_result.retrieve_historical_data(from_date='01/01/2019', to_date='01/01/2020')
+print(historical_data.head())
+```
+```{r, engine='python', count_lines}
+ Open High Low Close Volume Change Pct
+Date
+2020-01-02 74.06 75.15 73.80 75.09 135647008 2.28
+2020-01-03 74.29 75.14 74.13 74.36 146536000 -0.97
+2020-01-06 73.45 74.99 73.19 74.95 118579000 0.80
+2020-01-07 74.96 75.22 74.37 74.60 111511000 -0.47
+2020-01-08 74.29 76.11 74.29 75.80 132364000 1.61
+
+```
+
+#### Information
```python
- for search_result in search_results[:1]:
- print(search_result)
- search_result.retrieve_historical_data(from_date='01/01/2019', to_date='01/01/2020')
- print(search_result.data.head())
+information = search_result.retrieve_information()
+print(information)
```
```{r, engine='python', count_lines}
-{"id_": 6408, "name": "Apple Inc", "symbol": "AAPL", "country": "united states", "tag": "apple-computer-inc", "pair_type": "stocks", "exchange": "NASDAQ"}
+{'prevClose': 126.11, 'dailyRange': '126.1-127.44', 'revenue': 325410000000, 'open': 126.53, 'weekRange': '83.14-145.09', 'eps': 4.46, 'volume': 53522373, 'marketCap': 2130000000000, 'dividend': '0.88(0.70%)', 'avgVolume': 88858729, 'ratio': 28.58, 'beta': 1.2, 'oneYearReturn': '50.35%', 'sharesOutstanding': 16687631000, 'nextEarningDate': '03/08/2021'}
- Open High Low Close Volume
-Date
-2019-01-02 154.89 158.85 154.23 157.92 37039736
-2019-01-03 143.98 145.72 142.00 142.19 91312192
-2019-01-04 144.53 148.55 143.80 148.26 58607072
-2019-01-07 148.70 148.83 145.90 147.93 54777764
-2019-01-08 149.56 151.82 148.52 150.75 41025312
+```
+
+#### Currency
+
+```python
+default_currency = search_result.retrieve_currency()
+print(default_currency)
+```
+```{r, engine='python', count_lines}
+'USD'
+
+```
+
+#### Technical Indicators
+
+```python
+technical_indicators = search_result.retrieve_technical_indicators(interval='daily')
+print(technical_indicators)
+```
+```{r, engine='python', count_lines}
+ indicator signal value
+0 RSI(14) neutral 52.1610
+1 STOCH(9,6) buy 63.7110
+2 STOCHRSI(14) overbought 100.0000
+3 MACD(12,26) sell -0.6700
+4 ADX(14) neutral 21.4750
+5 Williams %R buy -20.9430
+6 CCI(14) buy 67.1057
+7 ATR(14) less_volatility 1.7871
+8 Highs/Lows(14) buy 0.4279
+9 Ultimate Oscillator sell 47.3620
+10 ROC buy 1.5150
+11 Bull/Bear Power(13) buy 1.3580
```
@@ -131,7 +198,7 @@ consider it.
As already presented previously, **historical data retrieval using investpy is really easy**. The piece of code
presented below shows how to retrieve the past years of historical data from Bitcoin (BTC).
-````python
+```python
import investpy
data = investpy.get_crypto_historical_data(crypto='bitcoin',
@@ -139,7 +206,7 @@ data = investpy.get_crypto_historical_data(crypto='bitcoin',
to_date='01/01/2019')
print(data.head())
-````
+```
```{r, engine='python', count_lines}
Open High Low Close Volume Currency
Date
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 52243b68..695cd158 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,3 @@
sphinx==2.4.4
-sphinx_rtd_theme==0.4.3
-recommonmark==0.6.0
\ No newline at end of file
+recommonmark==0.6.0
+furo==2021.4.11b34
\ No newline at end of file
diff --git a/docs/source/_info/citation.md b/docs/source/_info/citation.md
new file mode 100644
index 00000000..b25b415b
--- /dev/null
+++ b/docs/source/_info/citation.md
@@ -0,0 +1,21 @@
+## ๐ Citation
+
+When citing this repository on your scientific publications please use the following **BibTeX** citation:
+
+```bibtex
+@misc{investpy,
+ author = {Alvaro Bartolome del Canto},
+ title = {investpy - Financial Data Extraction from Investing.com with Python},
+ year = {2018-2021},
+ publisher = {GitHub},
+ journal = {GitHub Repository},
+ howpublished = {\url{https://github.com/alvarobartt/investpy}},
+}
+```
+
+When citing this repository on any other social media, please use the following citation:
+
+``investpy - Financial Data Extraction from Investing.com with Python developed by Alvaro Bartolome del Canto``
+
+You should also mention the source from where the data is retrieved, Investing.com; even though it's already
+included in the package short description title.
diff --git a/docs/source/_info/contact_information.md b/docs/source/_info/contact_information.md
new file mode 100644
index 00000000..d410337d
--- /dev/null
+++ b/docs/source/_info/contact_information.md
@@ -0,0 +1,10 @@
+## ๐จโ๐ป Contact Information
+
+You can contact me at any of my social network profiles:
+
+- ๐ผ LinkedIn: https://linkedin.com/in/alvarobartt
+- ๐ฆ Twitter: https://twitter.com/alvarobartt
+- ๐ GitHub: https://github.com/alvarobartt
+
+Or via email at alvarobartt@yahoo.com, even though this last one is not recommended
+as mentioned in the FAQs.
diff --git a/docs/source/_info/disclaimer.md b/docs/source/_info/disclaimer.md
index d5d9bd32..43bfda26 100644
--- a/docs/source/_info/disclaimer.md
+++ b/docs/source/_info/disclaimer.md
@@ -1,7 +1,8 @@
-# Disclaimer
+## โ ๏ธ Disclaimer
-This Python Package has been made for research purposes in order to fit a needs that Investing.com does not cover,
-so this package works like an Application Programming Interface (API) of Investing.com developed in an altruistic way.
+This Python package has been made for **research purposes** to fit the needs that Investing.com does not cover,
+so this package works like an Application Programming Interface (API) of Investing.com developed in an **altruistic way**.
-Conclude that this package is not related in any way with Investing.com or any dependant company, the only requirement
-for developing this package was to mention the source where data is retrieved.
\ No newline at end of file
+Conclude that **investpy is not affiliated in any way to Investing.com or any dependant company**, the only
+requirement specified by Investing.com to develop this package was to "mention the source where data is
+retrieved from".
diff --git a/docs/source/_info/discussions.md b/docs/source/_info/discussions.md
new file mode 100644
index 00000000..69123a42
--- /dev/null
+++ b/docs/source/_info/discussions.md
@@ -0,0 +1,39 @@
+# โ Discussions (Q&A, AMA)
+
+GitHub recently released a new feature named __GitHub Discussions__ (still in beta). GitHub Discussions is a
+collaborative communication forum for the community around an open source project.
+
+Check the investpy GitHub Discussions page at [Discussions](https://github.com/alvarobartt/investpy/discussions),
+and feel free to ask me (ar any developer) anything, share updates, have open-ended conversations, and follow along
+on decisions affecting the community's way of working.
+
+:pushpin: __Note__. Usually I don't answer emails asking me questions about investpy, as we currently have the
+GitHub Discussions tab, and I encourage you to use it. GitHub Discussions is the easiest way to contact me about
+investpy, so that I don't answer the same stuff more than once via email, as anyone can see the opened/answered
+discussions.
+
+Also, in this section some Frequent Asked Questions are answered, so please read this section before posting a
+question or openning an issue since duplicates will not be solved or will be referenced to this section. Also,
+if you think that there are more possible FAQs, consider openning an issue in GitHub so to notify it, since if we
+all contribute this section can be clear enough so to ease question answering.
+
+## Where can I find the reference of a function and its usage?
+
+Currently the `docs/` are still missing a lot of information, but they can be clear enough so that users can get to know which functions can be used and how. If you feel that any functionallity or feature is not clear enough, please let me know in the issues tab, so that I can explain it properly for newcomers, so that answers are more general and help more users than just the one asking it. Docs can be found at: [Documentation](https://investpy.readthedocs.io/)
+
+## What do I do if the financial product I am looking for is not indexed in investpy?
+
+As it is known, investpy gathers and retrieves data from Investing.com which is a website that contains a lot of financial information. Since investpy relies on Investing.com data, some of it may not be available in Investing, which will mean that it will not be available in investpy either. Anyways, it can be an investpy problem while retrieving data, so on, there is a search function (`investpy.search_quotes(text, products, countries, n_results)`) that can be used for searching financial products that are available in Investing.com but they can not be retrieved using investpy main functions.
+
+## I am having problems while installing the package.
+
+If you followed the [Installation Guide](https://github.com/alvarobartt/investpy/blob/master/README.md#Installation), you should be able to use investpy without having any problem, anyways, if you are stuck on it, open an issue at investpy issues tab so to let the developers know which is your problem in order to solve it as soon as possible. If you were not able to complete the installation, please check that you are running at least Python 3.6 and that you are installing the latest version available, if you are still having problems, open an issue.
+
+## How do I contribute to investpy?
+
+As this is an open-source project it is **open to contributions, bug reports, bug fixes, documentation improvements,
+enhancements, and ideas**. There is an open tab of [issues](https://github.com/alvarobartt/investpy/issues) where
+anyone can open new issues if needed or navigate through them to solve them or contribute to its solving.
+Remember that issues are not threads to describe multiple problems, this does not mean that issues can not
+be discussed, but so to keep structured project management, the same issue should not describe different
+problems, just the main one and some nested/related errors that may be found.
diff --git a/docs/source/_info/faq.md b/docs/source/_info/faq.md
deleted file mode 100644
index edf1197b..00000000
--- a/docs/source/_info/faq.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Frequent Asked Questions - FAQs
-
-In this section the Frequent Asked Questions are answered, so please read this section before posting a question or openning an issue since duplicates will not be solved or will be referenced to this section. Also, if you think that there are more possible FAQs, consider openning an issue in GitHub so to notify it, since if we all contribute this section can be clear enough so to ease question answering.
-
-## Where can I find the reference of a function and its usage?
-
-Currently the `docs/` are still missing a lot of information, but they can be clear enough so that users can get to know which functions can be used and how. If you feel that any functionallity or feature is not clear enough, please let me know in the issues tab, so that I can explain it properly for newcomers, so that answers are more general and help more users than just the one asking it. Docs can be found at: [Documentation](https://investpy.readthedocs.io/)
-
-## What do I do if the financial product I am looking for is not indexed in investpy?
-
-As it is known, investpy gathers and retrieves data from Investing.com which is a website that contains a lot of financial information. Since investpy relies on Investing.com data, some of it may not be available in Investing, which will mean that it will not be available in investpy either. Anyways, it can be an investpy problem while retrieving data, so on, there is a search function (`investpy.search_quotes(text, products, countries, n_results)`) that can be used for searching financial products that are available in Investing.com but they can not be retrieved using investpy main functions.
-
-## I am having problems while installing the package.
-
-If you followed the [Installation Guide](https://github.com/alvarobartt/investpy/blob/master/README.md#Installation), you should be able to use investpy without having any problem, anyways, if you are stuck on it, open an issue at investpy issues tab so to let the developers know which is your problem in order to solve it as soon as possible. If you were not able to complete the installation, please check that you are running Python 3.5 at least and that you are installing the latest version available, if you are still having problems, open an issue.
-
-## How do I contribute to investpy?
-
-Currently I am not admitting any Pull Request since investpy is under development, and so to keep a clean structure, I will be developing new functionalities until code is clean enough to let newcome contributors help. Anyways, the most effective tool you have in order to contribute to investpy are **issues** where you can give me new ideas or some functionallity you would like to see implemented in investpy. You can also use issues in order to report bugs or problems so to help investpy's development and consistency.
-
-## How do I reference investpy?
-
-Since investpy is an open source Python package, whenever you use it, would be nice from you to mention or comment where does the data comes from. This way, investpy can be spread among more users which will consequently improve package usage since more users can contribute to it due to the increasing reach to newcome developers. A sample reference is presented below:
-
-`investpy - a Python package for Financial Data Extraction from Investing.com developed by รlvaro Bartolomรฉ del Canto, alvarobartt @ GitHub`
diff --git a/docs/source/_info/funds.rst b/docs/source/_info/funds.rst
deleted file mode 100644
index 0a386f82..00000000
--- a/docs/source/_info/funds.rst
+++ /dev/null
@@ -1,166 +0,0 @@
-Funds
-=====
-
-A fund is a pool of money that is allocated for a specific purpose. A fund can be established for any purpose
-whatsoever, whether it is a city government setting aside money to build a new civic center, a college setting
-aside money to award a scholarship, or an insurance company setting aside money to pay its customersโ claims.
-
-A fund is a pool of money set aside for a specific purpose, those pools can are often invested and professionally
-managed and some common types of funds include pension funds, insurance funds, foundations, and endowments.
-
-Individuals, businesses, and governments all use funds to set aside money. Individuals might establish an emergency
-fund or rainy-day fund to pay for unforeseen expenses or a trust fund to set aside money for a specific person.
-
-Source: *Investopedia*
-
-Getting Started
----------------
-
-To get started using `investpy `_ you first need to install it as described on
-:ref:`installation-label`. Once you have it installed you can proceed to use it in order to retrieve data from
-funds, after importing the package as it follows:
-
-.. code-block:: python
-
- import investpy
-
-Listing
-^^^^^^^
-
-`investpy `_ offers some listing functions that allow the user to get the general
-information of the indexed funds on `Investing.com `_ as that information is already
-stored on CSV files generated automatically on the package installation.
-
-The user can either retrieve the whole :obj:`pandas.DataFrame` containing all the information stored on the CSV file, a
-:obj:`list` containing just the names of the funds, which are the input parameters for the data retrieval functions; or
-as a :obj:`dict` with all the available fields of information from the funds.
-
-Also there is a param called ``country`` which by default is None, which means that the fund listing to be retrieved
-will include all the available countries (indexed in Investing.com); on the contrary, if the param ``country`` is an
-available country, the returned fund information will be filtered by country.
-
-.. tip::
-
- To get a listing of all the available countries you can use the function ``investpy.get_fund_countries()`` which
- will return a :obj:`list` containing all the available country names which have funds as indexed on Investing.com.
-
-
-.. code-block:: python
-
- # Retrieve all available funds information as a pandas.DataFrame
- funds_df = investpy.get_funds(country=None)
- # Retrieve a listing of all the available fund names
- funds_list = investpy.get_funds_list(country=None)
- # Retrieve a dictionary with all the funds and all of their information fields
- funds_dict = investpy.get_funds_dict(country=None)
-
-
-.. note::
-
- The funds :obj:`pandas.DataFrame` contains internal package information that is useless for users, but it is provided
- anyways.
-
-Since the data retrieval functions need both the fund name and the country from where that fund is, there is a function
-to do so in order to let the user know which are the available countries and, so on, the available funds in those
-countries. The functions presented below: `investpy.get_funds`, `investpy.get_funds_list` and `investpy.get_funds_dict`
-have one optional parameter which is the country name so to retrieve just the :obj:`pandas.DataFrame`, :obj:`list` or
-:obj:`dict` from all the available funds from the introduced country, respectively.
-
-Anyways, before applying that filter, the use of the function `investpy.get_fund_countries` is proposed in order to
-retrieve all the available countries which have funds.
-
-.. code-block:: python
-
- countries = investpy.get_fund_countries()
-
- # Check if a country is either or not in the list & then get all the available funds from that country
- if 'spain' in countries:
- funds = investpy.get_funds_list(country='spain')
-
-So on, every country listed on the previous listing can be used for filtering funds. Note that the country param is
-needed in data retrieval functions since more than one fund can share the same name but not in the same country.
-
-Fund Search
-^^^^^^^^^^^
-
-Before proceeding with the data retrieval functions an additional function is presented, since sometimes the user does
-not have all the information for the fund to retrieve information from, so on, there is a function which allows the user
-to search for funds with the specified value for the specified column/field. This function will return a `pandas.DataFrame`
-with all the results found if they were found, if not, a `RuntimeError` will be raised.
-
-Since the returned object is a `pandas.DataFrame` in the following example both the function usage and further data
-handling is presented in order to let the user know hos to use the results of the search on the data retrieval functions
-in order to make it more easy to use. Note that you can either select the value you are searching from the
-
-.. code-block:: python
-
- search_result = investpy.search_funds(by='name', value='bbva')
-
- # Get both name and country via pandas.DataFrame index
- index = 0
- name = search_result.loc[index, 'name']
- country = search_result.loc[index, 'country']
-
- # Get both name and country via unique field such as isin
- isin = 'ES0113211835'
- name = search_result.loc[(search_result['isin'].str == isin).idxmax(), 'name']
- country = search_result.loc[(search_result['isin'].str == isin).idxmax(), 'country']
-
- # Or get it manually via printing the resulting pandas.DataFrame
- print(search_results)
-
-
-Recent & Historical Data
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The main functions of `investpy `_ are focused on historical data extraction, and in
-this concrete case, fund historical data retrieval functions will be explained and sorted out. As the main functionality
-of the package is to retrieve data from Investing.com and format it so to access it via Python functions, some functions
-have been developed in order to retrieve both recent and historical data.
-
-As to explain its usage an example is proposed to explain how does historical data retrieval functions work::
-
- # Retrieves last month's data of 'Bankia Cauto Pp', which is a fund from 'Spain', as a pandas.DataFrame
- df = investpy.get_fund_recent_data(fund='Bankia Cauto Pp', country='spain')
-
- # Retrieves historical data of 'Bankia Cauto Pp', which is a fund from 'Spain', on the specified date range as a pandas.DataFrame
- df = investpy.get_fund_historical_data(fund='Bankia Cauto Pp', country='spain', from_date='01/01/2018', to_date='01/01/2019')
-
-Both functions need some parameters, even though some of them are *optional*, which means that the function
-does not need the user to specify them as they already have a default value.
-
-Both parameters ``fund`` and ``country`` are mandatory, since they are the ones that specify which information should be
-retrieved from Investing.com. Take into consideration that both parameters should match, which means that the name of
-the fund should be a fund from the specified country, so if the introduced fund is not found on the specified country,
-an error will be raised.
-
-When retrieving recent data from a fund, we can additionally specify if we want the output as a json object or not, by
-setting the parameter ``as_json`` as either True or False, respectively. We can also set the ``order`` we want the
-returned object to have based on dates, where ascending goes from the very first date retrieved until now, and
-descending goes the other way.
-
-Furthermore, when it comes to historical data retrieval, we also need to specify both ``from_date`` and ``to_date``
-values, as they are mandatory. Both date values are :obj:`str` formatted as *dd/mm/yyyy*.
-
-.. tip::
-
- If you are not familiar with funds you can either retrieve a :obj:`list` of the ones available as provided by
- investpy or check the listing in `Investing.com Funds `_.
-
-Fund Information
-^^^^^^^^^^^^^^^^
-
-As an extra feature, via `investpy `_ you can retrieve information insights for the
-specified fund on the specified country. This information is the one related to the introduced fund as indexed by
-Investing.com which will give the user a wider sight on that concrete fund since values such as risk, rating or category
-are provided by Investing.com and, so on, by investpy.
-
-Its usage is pretty simple since just the `fund` and the `country` are mandatory parameters, but there is also an
-additional parameter which is `as_json` that can be either True or False whether the information wants to be returned as
-a :obj:`pandas.DataFrame` or a :obj:`json`.
-
-.. code-block:: python
-
- # Retrieve information from the introduced fund in the specified country
- data = investpy.get_fund_information(fund='Bankia Cauto Pp', country='spain')
-
diff --git a/docs/source/_info/information.rst b/docs/source/_info/information.rst
deleted file mode 100644
index b32c27a8..00000000
--- a/docs/source/_info/information.rst
+++ /dev/null
@@ -1,19 +0,0 @@
-Additional Information
-======================
-
-As this is an open source project it is open to contributions, bug reports, bug fixes, documentation improvements,
-enhancements and ideas. On Github you can find an open tab of `issues `_
-where you can contribute by opening new issues if needed or contribute to its solving.
-
-Additionally, you can triage issues on `investpy Code Triage `_ where
-you can both open and solve issues so the package can grow and improve faster as the issues solve relevant bugs,
-problems or needs of the package.
-
-Feel free to contact package administrator via `email `_.
-
-
-.. note::
- For further information or any question feel free to contact me via `email `_ You can also
- check my `Medium Publication `_,
- where I upload posts related to Data Science and to `investpy `_ basics on
- Web Scraping.
\ No newline at end of file
diff --git a/docs/source/_info/installation.md b/docs/source/_info/installation.md
new file mode 100644
index 00000000..40293599
--- /dev/null
+++ b/docs/source/_info/installation.md
@@ -0,0 +1,16 @@
+## ๐ ๏ธ Installation
+
+To get this package working you will need to **install it via pip** (with a Python 3.6 version or higher) on the terminal by typing:
+
+```
+$ pip install investpy
+```
+
+Additionally, **if you want to use the latest investpy version instead of the stable one, you can install it from source** with the following command:
+
+```
+$ pip install git+https://github.com/alvarobartt/investpy.git@master
+```
+
+**The master branch ensures the user that the most updated version will always be working and fully operative** so as not to wait until the
+the stable release comes out (which eventually may take some time depending on the number of issues to solve).
\ No newline at end of file
diff --git a/docs/source/_info/installation.rst b/docs/source/_info/installation.rst
deleted file mode 100644
index 61b50205..00000000
--- a/docs/source/_info/installation.rst
+++ /dev/null
@@ -1,54 +0,0 @@
-.. _installation-label:
-
-Installation
-============
-
-.. note::
-
- After installing the package you are now available to use it! As investpy's latest release is 1.0.6 the installation is
- optimized for it. If you try installing another investpy release, some features may not work.
-
-First Installation
-------------------
-
-In order to get this package working you will need to install it on its last version. To install the package on either way
-you will need to have a Python 3.x version installed and pip or conda, so you can install Python packages from PyPI and from Anaconda
-Cloud, respectively. So, to install the latest release of `investpy `_, you can either do it:
-
-* via Python Package Indexer (PyPI)::
-
- $ python -m pip install investpy
-
-* via Anaconda Cloud::
-
- $ conda install investpy
-
-* from GitHub via PyPI::
-
- $ python -m pip install https://github.com/alvarobartt/investpy/archive/master.zip
-
-
-Update Package
---------------
-
-If you already had `investpy `_ installed and you want to update it you can do it:
-
-* via PyPI::
-
- $ python -m pip install --upgrade investpy
-
-* via Anaconda Cloud::
-
- $ conda update investpy
-
-* from GitHub via PyPi::
-
- $ python -m pip install --upgrade https://github.com/alvarobartt/investpy/archive/master.zip
-
-All the dependencies are already listed on the setup file of the package, but to sum them up, when installing
-`investpy `_, it will install the following dependencies:
-
-* `pandas 0.25.1 `_
-* `requests 2.22.0 `_
-* `lxml 4.4.1 `_
-* `unidecode 1.1.1 `_
diff --git a/docs/source/_info/introduction.md b/docs/source/_info/introduction.md
new file mode 100644
index 00000000..9f8b1544
--- /dev/null
+++ b/docs/source/_info/introduction.md
@@ -0,0 +1,27 @@
+## ๐ Introduction
+
+investpy is a Python package to retrieve data from [Investing.com](https://www.investing.com/), which provides data retrieval
+from up to 39952 stocks, 82221 funds, 11403 ETFs, 2029 currency crosses, 7797 indices, 688 bonds, 66 commodities, 250 certificates,
+and 4697 cryptocurrencies.
+
+investpy allows the user to download both recent and historical data from all the financial products indexed at Investing.com.
+**It includes data from all over the world**, from countries such as United States, France, India, Spain, Russia, or Germany,
+amongst many others.
+
+investpy seeks to be one of the most complete Python packages when it comes to financial data extraction to stop relying
+on public/private APIs since investpy is **FREE** and has **NO LIMITATIONS**. These are some of the features that currently lead
+investpy to be one of the most consistent packages when it comes to financial data retrieval.
+
+---
+
+### ๐ฆ Data Source
+
+[Investing.com](https://www.investing.com/) is the main data source from which investpy retrieves the data. Investing.com is a
+global financial portal and Internet brand owned by Fusion Media Ltd. which provides news, analysis, streaming quotes,
+charts, technical data and financial tools about the global financial markets.
+
+---
+
+### ๐ป Getting Started
+
+TODO
diff --git a/docs/source/_info/introduction.rst b/docs/source/_info/introduction.rst
deleted file mode 100644
index 80083a2c..00000000
--- a/docs/source/_info/introduction.rst
+++ /dev/null
@@ -1,61 +0,0 @@
-Introduction
-============
-
-investpy is a Python package developed in order to retrieve all the available historical data from stocks/stocks,
-funds and ETFs from Investing.com. As Investing.com does not have any API to retrieve historical data, the main goal
-of this package is to allow users retrieve information from all the available financial products.
-
-investpy came to life due to the need of covering the existing shortcomings in terms of real time data retrieval from
-stocks of the companies that make up the Spanish Stock Market, until the date there was no other package that provided
-a data extraction model for stocks from the Spanish Stock Market.
-
-As time passed by, a decision was made on how investpy could be improved, and as the package was expected to have a high
-scalability and thus cover all the data possibilities offered by Investing.com to the public, investpy is now trying to
-expand the data it retrieves to make it more useful.
-
-Along this document some relevant features of `investpy `_ are going to be
-sorted out and its functions are going to be explained in order to clarify its use.
-
-Getting Started
----------------
-
-.. note::
- In order to get started using `investpy `_ you will need to have it installed, so
- if you do not have it already, check :ref:`installation-label`.
-
-Once you have `investpy `_ installed, you can now proceed to use the package. The
-first step is importing it at the top of your Python file as::
-
- import investpy
-
-Currently the main functions of `investpy `_ support historical data retrieval
-of stocks, funds and ETFs from all around the world (as indexed in Investing.com). Additionally to
-historical data retrieval, investpy also offers additional data retrieval related to the indexed financial products.
-
-In order to clarify this concepts, some investpy functions are going to be presented, even though all of them
-are going to be properly explained and sorted out on their respective appendix in the documentation or in the API
-Reference. For example, a block of code in order to get to test investpy usage is presented::
-
- import investpy
-
-
- # Retrieve all the available stocks as a Python list
- stocks = investpy.get_stocks_list()
-
- # Retrieve the recent historical data (past month) of a stock as a pandas.DataFrame on ascending date order
- df = investpy.get_stock_recent_data(stock='bbva', country='spain', as_json=False, order='ascending')
-
- # Retrieve the company profile of the introduced stock on english
- profile = investpy.get_stock_company_profile(stock='bbva', country='spain', language='english')
-
-
-Data Source
------------
-
-`Investing.com `_ is the main data source from which investpy retrieves the data. Investing.com is a
-global financial portal and Internet brand owned by Fusion Media Ltd. which provides news, analysis, streaming quotes,
-charts, technical data and financial tools about the global financial markets.
-
-So as, the decision of choosing Investing.com as the data source is based on its reliability and also because it is one of
-the few web pages that provide detailed data from spanish markets, as it was the main focus when determining to
-develop the package as explained previously.
\ No newline at end of file
diff --git a/docs/source/_info/models.rst b/docs/source/_info/models.rst
deleted file mode 100644
index 4cd55400..00000000
--- a/docs/source/_info/models.rst
+++ /dev/null
@@ -1,36 +0,0 @@
-Models
-======
-
-Data Model
-----------
-
-As the retrieved historical data is common to every financial product that investpy extracts data from, only a model
-class has been created in order to store the day-a-day historical data.
-
-So in we define a model in where every value corresponds to each value of the OHLC (Open-High-Low-Close) nomenclature
-(except on stocks, that it also includes the volume) and it looks like::
-
- def __init__(self, date_, open_, high_, low_, close_, volume_, currency_):
- self.date = date_
- self.open = open_
- self.high = high_
- self.low = low_
- self.close = close_
- self.volume = volume_
- self.currency_ = currency_
-
-
-As their names indicate, OHLC values refer to opening, highest, lowest and closing values of the market on a trading
-day, respectively. And the volume value refers to the number of shares traded in a security day.
-
-
-.. note::
-
- The Data model is not usable as it is just a class used for the inner package, transparent to the user. It is used
- in order to categorize each retrieved value from Investing.com and then to define its structure and, so on, the
- structure that either the resulting pandas.DataFrame or JSON file will be based on.
-
-Search Model
-------------
-
-TODO
\ No newline at end of file
diff --git a/docs/source/_info/related_projects.md b/docs/source/_info/related_projects.md
new file mode 100644
index 00000000..5822e165
--- /dev/null
+++ b/docs/source/_info/related_projects.md
@@ -0,0 +1,13 @@
+## ๐๏ธ Related projects
+
+Since investpy is intended to retrieve data from different financial products as indexed in Investing.com,
+the **development of some support modules which implement an additional functionality based on investpy data**,
+is presented. Note that **anyone can contribute to this section** by creating any package, module, or utility that
+uses investpy. So on, the ones already created are going to be presented, since they are intended to be used
+combined with investpy:
+
+- [pyrtfolio](https://github.com/alvarobartt/pyrtfolio/): is a Python package to generate stock portfolios.
+- [trendet](https://github.com/alvarobartt/trendet/): is a Python package for trend detection on stock time-series data.
+
+If you developed an interesting/useful project based on investpy data, please open an issue to let me know to
+include it in this section.
diff --git a/docs/source/_info/stocks.rst b/docs/source/_info/stocks.rst
deleted file mode 100644
index bf86eade..00000000
--- a/docs/source/_info/stocks.rst
+++ /dev/null
@@ -1,114 +0,0 @@
-Stocks/Equities
-===============
-
-A **stock** (also known as "shares" or "equities") is a type of security that signifies proportionate ownership in the
-issuing corporation. This entitles the stockholder to that proportion of the corporation's assets and earnings.
-
-Stocks are bought and sold predominantly on stock exchanges, though there can be private sales as well, and are the
-foundation of nearly every portfolio. These transactions have to conform to government regulations which are meant to
-protect investors from fraudulent practices. Historically, they have outperformed most other investments over the long
-run. These investments can be purchased from most online stock brokers.
-
-Source: *Investopedia*
-
-Getting Started
----------------
-
-To get started using `investpy `_ you first need to install it as described on
-:ref:`installation-label`. Once you have it installed you can proceed to use it in order to retrieve data from
-stocks, after importing the package as it follows:
-
-.. code-block:: python
-
- import investpy
-
-Listing
-^^^^^^^
-
-`investpy `_ offers some listing functions that allow the user to get the general
-information of the indexed stocks on `Investing.com `_ as that information is already
-stored on CSV files generated automatically on the package installation.
-
-We can either retrieve the whole :obj:`pandas.DataFrame` containing all the information stored on the CSV file or a
-:obj:`list` containing just the symbols of the stocks, which are the input parameters for the data retrieval functions.
-
-Also there is a param called ``country`` which by default is None, which means that the stock listing to be retrieved
-will include all the available countries (indexed in Investing.com); on the contrary, if the param ``country`` is an
-available country, the returned stock information will be filtered by country.
-
-.. tip::
-
- To get a listing of all the available countries you can use the function ``investpy.get_stock_countries()`` which
- will return a :obj:`list` containing all the available country names which have stocks as indexed on Investing.com.
-
-
-.. code-block:: python
-
- # Retrieve all available stocks information as a pandas.DataFrame
- stocks_df = investpy.get_stocks(country=None)
- # Retrieve a listing of all the available stock symbols
- stocks_list = investpy.get_stocks_list(country=None)
-
-Recent & Historical Data
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-The main functions of `investpy `_ are focused on historical data extraction,
-stocks in this case. As the main functionality of the package is to retrieve data from Investing.com, so on,
-some functions have been developed in order to retrieve both recent and historical data.
-
-As to explain its usage an example is proposed to present historical data retrieval functions::
-
- # Retrieves the recent data of BBVA (last month) a spanish stock, as a pandas.DataFrame on ascending order
- df = investpy.get_stock_recent_data(stock='bbva', country='spain', as_json=False, order='ascending')
-
- # Retrieves the historical data of BBVA, a spanish stock, on the specified date range as a pandas.DataFrame on ascending order
- df = investpy.get_stock_historical_data(stock='bbva', country='spain', from_date='01/01/2018', to_date='01/01/2019', as_json=False, order='ascending')
-
-As we already saw, both functions take some parameters, but some of them are *optional*, which means that the function
-does not need the user to specify them as they already have a default value.
-
-Both parameters ``stock`` and ``country`` are mandatory, since they are the ones that specify which information should be
-retrieved from Investing.com. Consider that both parameters should match, which means that the symbols of the stock should
-be an stock from the specified country, if the stock is not found on the specified country, an error will be raised.
-
-When retrieving recent data from an stock, we can additionally specify if we want the output as a json object or not, by
-setting the parameter ``as_json`` as either True or False, respectively. We can also set the ``order`` we want the
-returned object to have based on dates, where ascending goes from the very first date retrieved until now, and
-descending goes the other way.
-
-Furthermore, when it comes to historical data retrieval, we also need to specify both ``from_date`` and ``to_date``
-values, as they are mandatory. Both date values are :obj:`str` formatted as *dd/mm/yyyy*.
-
-.. tip::
-
- If you are not familiar with stocks you can either retrieve a listing of the ones
- available or check the one presented in `Investing.com Equities `_.
-
-Company Profile
-^^^^^^^^^^^^^^^
-
-As an extra feature, via `investpy `_ you can retrieve the company profile from a
-company in order to either classify or analyse them based on the information these companies publicly provide, as it
-is a self-made description of the company.
-
-.. code-block:: python
-
- investpy.get_stock_company_profile(stock='bbva', country='spain', language='english')
-
-As explained before, when it comes to data retrieval, both ``stock`` and ``country`` parameters are mandatory, and
-should match; as the default value for the ``language`` of the retrieved company profile is *english* (as `Investing.com `_
-provides company profiles written in english), but besides that, the function
-also retrieves the company profile on *spanish* from `Bolsa de Madrid `_,
-which is the additional resource used along this package.
-
-.. warning::
-
- This function is just available for spanish stocks, since `investpy `_ was
- first created just for Spanish Stocks, Funds and ETFs retrieval. Future coverage for world stocks company
- profiles is intended, but currently just the spanish ones are available.
-
-Samples
--------
-
-As the generated dataset has been uploaded to `Kaggle `_
-some kernels with samples on retrieved data usage have been created by the community.
\ No newline at end of file
diff --git a/docs/source/_info/usage.md b/docs/source/_info/usage.md
new file mode 100644
index 00000000..e6a98aff
--- /dev/null
+++ b/docs/source/_info/usage.md
@@ -0,0 +1,172 @@
+## ๐ป Usage
+
+Even though some investpy usage examples are presented on the [docs](https://investpy.readthedocs.io/usage.html),
+some basic functionality will be sorted out with sample Python code blocks. Additionally, more usage examples
+can be found under [examples/](https://github.com/alvarobartt/investpy/tree/master/examples) directory, which
+contains a collection of Jupyter Notebooks on how to use investpy and handle its data.
+
+๐ __Note that `investpy.search_quotes` is the only function that ensures that the data is updated and aligned 1:1 with
+the data provided by Investing.com!__
+
+### ๐ Recent/Historical Data Retrieval
+
+investpy allows the user to **download both recent and historical data from any financial product indexed**
+(stocks, funds, ETFs, currency crosses, certificates, bonds, commodities, indices, and cryptos). In
+the example presented below, the historical data from the past years of a stock is retrieved.
+
+```python
+import investpy
+
+df = investpy.get_stock_historical_data(stock='AAPL',
+ country='United States',
+ from_date='01/01/2010',
+ to_date='01/01/2020')
+print(df.head())
+```
+```
+ Open High Low Close Volume Currency
+Date
+2010-01-04 30.49 30.64 30.34 30.57 123432176 USD
+2010-01-05 30.66 30.80 30.46 30.63 150476160 USD
+2010-01-06 30.63 30.75 30.11 30.14 138039728 USD
+2010-01-07 30.25 30.29 29.86 30.08 119282440 USD
+2010-01-08 30.04 30.29 29.87 30.28 111969192 USD
+```
+
+To get to know all the available recent and historical data extraction functions provided by
+investpy, and also, parameter tuning, please read the docs.
+
+### ๐ Search Live Data
+
+**Investing.com search engine is completely integrated** with investpy, which means that any available
+financial product (quote) can be easily found. The search function allows the user to tune the parameters
+to adjust the search results to their needs, where both product types and countries from where the
+products are, can be specified. **All the search functionality can be easily used**, for example, as
+presented in the following piece of code:
+
+```python
+import investpy
+
+search_result = investpy.search_quotes(text='apple', products=['stocks'],
+ countries=['united states'], n_results=1)
+print(search_result)
+```
+```
+{"id_": 6408, "name": "Apple Inc", "symbol": "AAPL", "country": "united states", "tag": "/equities/apple-computer-inc", "pair_type": "stocks", "exchange": "NASDAQ"}
+
+```
+
+Retrieved search results will be a `list` of `investpy.utils.search_obj.SearchObj` class instances, unless
+`n_results` is set to 1, when just a single `investpy.utils.search_obj.SearchObj` class instance will be returned.
+To get to know which are the available functions and attributes of the returned search results, please read the related
+documentation at [Search Engine Documentation](https://investpy.readthedocs.io/search_api.html). So on, those
+search results let the user retrieve both recent and historical data, its information, the technical indicators,
+the default currency, etc., as presented in the pieces of code below:
+
+#### โพ Recent Data
+
+```python
+recent_data = search_result.retrieve_recent_data()
+print(recent_data.head())
+```
+```
+ Open High Low Close Volume Change Pct
+Date
+2021-05-13 124.58 126.15 124.26 124.97 105861000 1.79
+2021-05-14 126.25 127.89 125.85 127.45 81918000 1.98
+2021-05-17 126.82 126.93 125.17 126.27 74245000 -0.93
+2021-05-18 126.56 126.99 124.78 124.85 63343000 -1.12
+2021-05-19 123.16 124.92 122.86 124.69 92612000 -0.13
+
+```
+
+#### โพ Historical Data
+
+```python
+historical_data = search_result.retrieve_historical_data(from_date='01/01/2019', to_date='01/01/2020')
+print(historical_data.head())
+```
+```
+ Open High Low Close Volume Change Pct
+Date
+2020-01-02 74.06 75.15 73.80 75.09 135647008 2.28
+2020-01-03 74.29 75.14 74.13 74.36 146536000 -0.97
+2020-01-06 73.45 74.99 73.19 74.95 118579000 0.80
+2020-01-07 74.96 75.22 74.37 74.60 111511000 -0.47
+2020-01-08 74.29 76.11 74.29 75.80 132364000 1.61
+
+```
+
+#### โพ Information
+
+```python
+information = search_result.retrieve_information()
+print(information)
+```
+```json
+{"prevClose": 126.11, "dailyRange": "126.1-127.44", "revenue": 325410000000, "open": 126.53, "weekRange": "83.14-145.09", "eps": 4.46, "volume": 53522373, "marketCap": 2130000000000, "dividend": "0.88(0.70%)", "avgVolume": 88858729, "ratio": 28.58, "beta": 1.2, "oneYearReturn": "50.35%", "sharesOutstanding": 16687631000, "nextEarningDate": "03/08/2021"}
+
+```
+
+#### โพ Currency
+
+```python
+default_currency = search_result.retrieve_currency()
+print(default_currency)
+```
+```
+'USD'
+
+```
+
+#### โพ Technical Indicators
+
+```python
+technical_indicators = search_result.retrieve_technical_indicators(interval="daily")
+print(technical_indicators)
+```
+```
+ indicator signal value
+0 RSI(14) neutral 52.1610
+1 STOCH(9,6) buy 63.7110
+2 STOCHRSI(14) overbought 100.0000
+3 MACD(12,26) sell -0.6700
+4 ADX(14) neutral 21.4750
+5 Williams %R buy -20.9430
+6 CCI(14) buy 67.1057
+7 ATR(14) less_volatility 1.7871
+8 Highs/Lows(14) buy 0.4279
+9 Ultimate Oscillator sell 47.3620
+10 ROC buy 1.5150
+11 Bull/Bear Power(13) buy 1.3580
+
+```
+
+### ๐ธ Crypto Currencies Data Retrieval
+
+Cryptocurrencies support has recently been included, to let the user retrieve data and information from any
+available crypto at Investing.com. Please note that some cryptocurrencies do not have available data indexed
+at Investing.com so that it can not be retrieved using investpy either, even though they are just a few,
+consider it.
+
+As already presented previously, **historical data retrieval using investpy is really easy**. The piece of code
+presented below shows how to retrieve the past years of historical data from Bitcoin (BTC).
+
+```python
+import investpy
+
+data = investpy.get_crypto_historical_data(crypto='bitcoin',
+ from_date='01/01/2014',
+ to_date='01/01/2019')
+
+print(data.head())
+```
+```
+ Open High Low Close Volume Currency
+Date
+2014-01-01 805.9 829.9 771.0 815.9 10757 USD
+2014-01-02 815.9 886.2 810.5 856.9 12812 USD
+2014-01-03 856.9 888.2 839.4 884.3 9709 USD
+2014-01-04 884.3 932.2 848.3 924.7 14239 USD
+2014-01-05 924.7 1029.9 911.4 1014.7 21374 USD
+```
diff --git a/docs/source/_info/usage.rst b/docs/source/_info/usage.rst
deleted file mode 100644
index b05139b5..00000000
--- a/docs/source/_info/usage.rst
+++ /dev/null
@@ -1,250 +0,0 @@
-Usage
-=====
-
-Along this document, the main `investpy `_ functions are going to be presented. So on, this is a tutorial
-on how to use **investpy** to retrieve data from the financial products available, such as: stocks, funds, ETFs, indices and currency crosses,
-retrieved from Investing.com.
-
-Recent/Historical Data Retrieval
---------------------------------
-
-The main functionallity of **investpy** is to retrieve historical data from the indexed financial products. So both recent and historical data
-retrieval functions have been developed in order to retrieve data from the last month or from a concrete period of time, respectively.
-
-Stock Data Retrieval
-^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_stock_recent_data(stock='bbva',
- country='spain')
- print(df.head())
-
- Open High Low Close Volume Currency
- Date
- 2019-08-13 4.263 4.395 4.230 4.353 27250000 EUR
- 2019-08-14 4.322 4.325 4.215 4.244 36890000 EUR
- 2019-08-15 4.281 4.298 4.187 4.234 21340000 EUR
- 2019-08-16 4.234 4.375 4.208 4.365 46080000 EUR
- 2019-08-19 4.396 4.425 4.269 4.269 18950000 EUR
-
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_stock_historical_data(stock='AAPL',
- country='United States',
- from_date='01/01/2010',
- to_date='01/01/2020')
- print(df.head())
-
- Open High Low Close Volume Currency
- Date
- 2010-01-04 30.49 30.64 30.34 30.57 123432176 USD
- 2010-01-05 30.66 30.80 30.46 30.63 150476160 USD
- 2010-01-06 30.63 30.75 30.11 30.14 138039728 USD
- 2010-01-07 30.25 30.29 29.86 30.08 119282440 USD
- 2010-01-08 30.04 30.29 29.87 30.28 111969192 USD
-
-Fund Data Retrieval
-^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_fund_recent_data(fund='bbva plan multiactivo moderado pp',
- country='spain')
- print(df.head())
-
- Open High Low Close Currency
- Date
- 2019-08-13 1.110 1.110 1.110 1.110 EUR
- 2019-08-16 1.109 1.109 1.109 1.109 EUR
- 2019-08-19 1.114 1.114 1.114 1.114 EUR
- 2019-08-20 1.112 1.112 1.112 1.112 EUR
- 2019-08-21 1.115 1.115 1.115 1.115 EUR
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_fund_historical_data(fund='bbva plan multiactivo moderado pp',
- country='spain',
- from_date='01/01/2010',
- to_date='01/01/2019')
- print(df.head())
-
- Open High Low Close Currency
- Date
- 2018-02-15 1.105 1.105 1.105 1.105 EUR
- 2018-02-16 1.113 1.113 1.113 1.113 EUR
- 2018-02-17 1.113 1.113 1.113 1.113 EUR
- 2018-02-18 1.113 1.113 1.113 1.113 EUR
- 2018-02-19 1.111 1.111 1.111 1.111 EUR
-
-ETF Data Retrieval
-^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_etf_recent_data(etf='bbva accion dj eurostoxx 50',
- country='spain')
- print(df.head())
-
- Open High Low Close Currency
- Date
- 2019-08-13 33.115 33.780 32.985 33.585 EUR
- 2019-08-14 33.335 33.335 32.880 32.905 EUR
- 2019-08-15 32.790 32.925 32.455 32.845 EUR
- 2019-08-16 33.115 33.200 33.115 33.305 EUR
- 2019-08-19 33.605 33.735 33.490 33.685 EUR
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_etf_historical_data(etf='bbva accion dj eurostoxx 50',
- country='spain',
- from_date='01/01/2018',
- to_date='01/01/2019')
- print(df.head())
-
- Open High Low Close Currency
- Date
- 2011-12-07 23.70 23.70 23.70 23.62 EUR
- 2011-12-08 23.53 23.60 23.15 23.04 EUR
- 2011-12-09 23.36 23.60 23.36 23.62 EUR
- 2011-12-12 23.15 23.26 23.00 22.88 EUR
- 2011-12-13 22.88 22.88 22.88 22.80 EUR
-
-Index Data Retrieval
-^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_index_recent_data(index='ibex 35',
- country='spain')
- print(df.head())
-
- Open High Low Close Volume Currency
- Date
- 2019-08-26 12604.7 12646.3 12510.4 12621.3 4770000 EUR
- 2019-08-27 12618.3 12723.3 12593.6 12683.8 8230000 EUR
- 2019-08-28 12657.2 12697.2 12585.1 12642.5 7300000 EUR
- 2019-08-29 12637.2 12806.6 12633.8 12806.6 5650000 EUR
- 2019-08-30 12767.6 12905.9 12756.9 12821.6 6040000 EUR
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_index_historical_data(index='ibex 35',
- country='spain',
- from_date='01/01/2018',
- to_date='01/01/2019')
- print(df.head())
-
- Open High Low Close Volume Currency
- Date
- 2018-01-02 15128.2 15136.7 14996.6 15096.8 10340000 EUR
- 2018-01-03 15145.0 15186.9 15091.9 15106.9 12800000 EUR
- 2018-01-04 15105.5 15368.7 15103.7 15368.7 17070000 EUR
- 2018-01-05 15353.9 15407.5 15348.6 15398.9 11180000 EUR
- 2018-01-08 15437.1 15448.7 15344.0 15373.3 12890000 EUR
-
-Currency Crosses Data Retrieval
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_currency_cross_recent_data(currency_cross='EUR/USD')
- print(df.head())
-
- Open High Low Close Volume Currency
- Date
- 2019-08-27 1.1101 1.1116 1.1084 1.1091 0 USD
- 2019-08-28 1.1090 1.1099 1.1072 1.1078 0 USD
- 2019-08-29 1.1078 1.1093 1.1042 1.1057 0 USD
- 2019-08-30 1.1058 1.1062 1.0963 1.0991 0 USD
- 2019-09-02 1.0990 1.1000 1.0958 1.0968 0 USD
-
-.. code-block:: python
-
- import investpy
-
- df = investpy.get_currency_cross_historical_data(currency_cross='EUR/USD',
- from_date='01/01/2018',
- to_date='01/01/2019')
- print(df.head())
-
- Open High Low Close Volume Currency
- Date
- 2018-01-01 1.2003 1.2014 1.1995 1.2010 0 USD
- 2018-01-02 1.2013 1.2084 1.2003 1.2059 0 USD
- 2018-01-03 1.2058 1.2070 1.2001 1.2014 0 USD
- 2018-01-04 1.2015 1.2090 1.2004 1.2068 0 USD
- 2018-01-05 1.2068 1.2085 1.2021 1.2030 0 USD
-
-Additional Data
----------------
-
-As Investing.com provides more data besides the historical one, some of that additional data can be fetched via investpy.
-Currently, as the package is under-development, some additional functions have been created in order to retrieve more data
-as indexed in Investing.com.
-
-Stock Company Profile Retrieval
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- company_profile = investpy.get_stock_company_profile(stock='bbva',
- country='spain')
- print(company_profile)
-
- {
- "url": "https://www.investing.com/equities/bbva-company-profile",
- "description": "Banco Bilbao Vizcaya Argentaria, S.A. (BBVA) is a diversified financial company engaged in retail banking ..."
- }
-
-Fund Information Retrieval
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-.. code-block:: python
-
- import investpy
-
- fund_information = investpy.get_fund_information(fund='bbva plan multiactivo moderado pp',
- country='spain',
- as_json=True)
- print(fund_information)
-
- {
- 'Fund Name': 'Bbva Plan Multiactivo Moderado Pp',
- 'Rating': 4,
- '1-Year Change': '-1,19%',
- 'Previous Close': '1.103',
- 'Risk Rating': 1,
- 'TTM Yield': '0%',
- 'ROE': '14,02%',
- 'Issuer': 'BBVA Pensiones EGFP',
- 'Turnover': None,
- 'ROA': '4,97%',
- 'Inception Date': '16/10/2012',
- 'Total Assets': 1670000000,
- 'Expenses': None,
- 'Min Investment': 30,
- 'Market Cap': 34820000000,
- 'Category': 'Mixtos Euros Moderados PP'
- }
\ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
index ff57c33a..9a92c481 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -14,15 +14,14 @@
# import sys
# sys.path.insert(0, os.path.abspath('.'))
-
# -- Project information -----------------------------------------------------
project = 'investpy'
-copyright = '2020, Alvaro Bartolome del Canto'
+copyright = '2021, Alvaro Bartolome del Canto'
author = 'Alvaro Bartolome del Canto'
# The full version, including alpha/beta/rc tags
-release = '1.0.6'
+release = '1.0.7'
# -- General configuration ---------------------------------------------------
@@ -48,7 +47,6 @@
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
-#
source_suffix = ['.rst', '.md']
# source_suffix = '.rst'
@@ -60,7 +58,7 @@
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
-language = None
+language = 'en'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
@@ -68,23 +66,24 @@
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'friendly'
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-import sphinx_rtd_theme
-html_theme = 'sphinx_rtd_theme'
+html_theme = 'furo'
+html_title = "investpy"
# Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
+# html_theme_path = []
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-#
-# html_theme_options = {}
+html_theme_options = {
+ "announcement": "investpy v1.0.7 has just been released! ๐ฅ",
+}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 929dd303..3b43873e 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -1,23 +1,22 @@
Welcome to investpy's documentation!
====================================
-.. image:: https://raw.githubusercontent.com/alvarobartt/investpy/master/docs/_static/logo.png
+.. image:: _static/logo.png
:align: center
.. toctree::
:maxdepth: 3
:caption: Contents:
- _info/introduction.rst
- _info/installation.rst
- _info/usage.rst
- _info/models.rst
- _info/stocks.rst
- _info/funds.rst
- api.rst
- _info/information.md
- _info/faq.md
+ _info/introduction.md
+ _info/installation.md
+ _info/usage.md
+ _info/related_projects.md
+ _info/contact_information.md
+ _info/citation.md
+ _info/discussions.md
_info/disclaimer.md
+ api.rst
Indices and tables
diff --git a/investpy/__init__.py b/investpy/__init__.py
index 051b14b7..5c6eef68 100644
--- a/investpy/__init__.py
+++ b/investpy/__init__.py
@@ -2,7 +2,7 @@
# See LICENSE for details.
__author__ = 'Alvaro Bartolome @ alvarobartt in GitHub'
-__version__ = '1.0.6'
+__version__ = '1.0.7'
from .stocks import get_stocks, get_stocks_list, get_stocks_dict, get_stock_countries, get_stock_recent_data, \
get_stock_historical_data, get_stock_company_profile, get_stock_dividends, get_stock_information, get_stocks_overview, \
@@ -35,7 +35,8 @@
get_certificate_recent_data, get_certificate_historical_data, get_certificate_information, get_certificates_overview, \
search_certificates
-from .search import search_quotes, search_events
+from .search import search_quotes
+# from .search import search_events
from .news import economic_calendar
diff --git a/investpy/search.py b/investpy/search.py
index 81866cf4..b6204320 100644
--- a/investpy/search.py
+++ b/investpy/search.py
@@ -5,27 +5,33 @@
from unidecode import unidecode
-from .utils import constant as cst
from .utils.search_obj import SearchObj
from .utils.extra import random_user_agent
+from .utils.constant import PRODUCT_FILTERS, COUNTRY_FILTERS, PAIR_FILTERS, FLAG_FILTERS
def search_quotes(text, products=None, countries=None, n_results=None):
"""
This function will use the Investing.com search engine so to retrieve the search results of the
introduced text. This function will create a :obj:`list` of :obj:`investpy.utils.search_obj.SearchObj`
- class instances which will contain the search results so that they can be easily accessed and so
+ class instances, unless `n_results` is set to 1, where just a single :obj:`investpy.utils.search_obj.SearchObj`
+ will be returned.
+
+ Those class instances will contain the search results so that they can be easily accessed and so
to ease the data retrieval process since it can be done calling the methods `self.retrieve_recent_data()`
or `self.retrieve_historical_data(from_date, to_date)` from each class instance, which will fill the historical
- data attribute, `self.data`. The information of the financial product can also be retrieved using the
- function `self.retrieve_information()`, that will also dump the information in the attribute `self.info`.
+ data attribute, `self.data`. Also the information of the financial product can be retrieved using the
+ function `self.retrieve_information()`, that will also dump the information in the attribute `self.information`;
+ the technical indicators can be retrieved using `self.retrieve_technical_indicators()` dumped in the attribute
+ `self.technical_indicators`; the default currency using `self.retrieve_currecy()` dumped in the attribute
+ `self.default_currency`.
Args:
text (:obj:`str`): text to search in Investing.com among all its indexed data.
products (:obj:`list` of :obj:`str`, optional):
list with the product type filter/s to be applied to search result quotes so that they match
the filters. Possible products are: `indices`, `stocks`, `etfs`, `funds`, `commodities`, `currencies`,
- `crypto`, `bonds`, `certificates` and `fxfutures`, by default this parameter is set to `None` which
+ `cryptos`, `bonds`, `certificates` and `fxfutures`, by default this parameter is set to `None` which
means that no filter will be applied, and all product type quotes will be retrieved.
countries (:obj:`list` of :obj:`str`, optional):
list with the country name filter/s to be applied to search result quotes so that they match
@@ -72,14 +78,11 @@ class instances which will contain the search results so that they can be easily
except:
raise ValueError("ERR#0130: the introduced products filter must be a list of str in order to be valid.")
- condition = set(products).issubset(cst.PRODUCT_FILTERS.keys())
+ condition = set(products).issubset(PRODUCT_FILTERS.keys())
if condition is False:
- # TODO: instead of printing the possible filters, reference the docs
- raise ValueError('ERR#0095: products filtering parameter possible values are: \"' + ', '.join(cst.PRODUCT_FILTERS.keys()) + '\".')
+ raise ValueError('ERR#0095: products filtering parameter possible values are: \"' + ', '.join(PRODUCT_FILTERS.keys()) + '\".')
- products = [cst.PRODUCT_FILTERS[product] for product in products]
- else:
- products = list(cst.PRODUCT_FILTERS.values())
+ products = [PRODUCT_FILTERS[product] for product in products]
if countries:
try:
@@ -87,14 +90,11 @@ class instances which will contain the search results so that they can be easily
except:
raise ValueError("ERR#0131: the introduced countries filter must be a list of str in order to be valid.")
- condition = set(countries).issubset(cst.COUNTRY_FILTERS.keys())
+ condition = set(countries).issubset(COUNTRY_FILTERS.keys())
if condition is False:
- # TODO: instead of printing the possible filters, reference the docs
- raise ValueError('ERR#0129: countries filtering parameter possible values are: \"' + ', '.join(cst.COUNTRY_FILTERS.keys()) + '\".')
+ raise ValueError('ERR#0129: countries filtering parameter possible values are: \"' + ', '.join(COUNTRY_FILTERS.keys()) + '\".')
- countries = [cst.COUNTRY_FILTERS[country] for country in countries]
- else:
- countries = list(cst.COUNTRY_FILTERS.values())
+ countries = [COUNTRY_FILTERS[country] for country in countries]
params = {
'search_text': text,
@@ -104,7 +104,7 @@ class instances which will contain the search results so that they can be easily
'offset': 0
}
- head = {
+ headers = {
"User-Agent": random_user_agent(),
"X-Requested-With": "XMLHttpRequest",
"Accept": "text/html",
@@ -118,11 +118,13 @@ class instances which will contain the search results so that they can be easily
total_results = None
+ user_limit = True if n_results is not None else False
+
while True:
- req = requests.post(url, headers=head, data=params)
+ req = requests.post(url, headers=headers, data=params)
if req.status_code != 200:
- raise ConnectionError("ERR#0015: error " + str(req.status_code) + ", try again later.")
+ raise ConnectionError(f"ERR#0015: error {req.status_code}, try again later.")
data = req.json()
@@ -137,24 +139,26 @@ class instances which will contain the search results so that they can be easily
for quote in data['quotes']:
country, pair_type = quote['flag'], quote['pair_type']
-
+
if countries is not None:
- if quote['flag'] in countries:
- country = cst.FLAG_FILTERS[quote['flag']]
- else:
+ if quote['flag'] not in countries:
continue
if products is not None:
- if quote['pair_type'] in products:
- pair_type = cst.PAIR_FILTERS[quote['pair_type']]
- else:
+ if quote['pair_type'] not in products:
continue
+
+ pair_type = PAIR_FILTERS[quote['pair_type']]
+
+ country = None
+ if pair_type not in ['cryptos', 'commodities']:
+ country = FLAG_FILTERS[quote['flag']] if quote['flag'] in FLAG_FILTERS else quote['flag']
search_obj = SearchObj(id_=quote['pairId'], name=quote['name'], symbol=quote['symbol'],
country=country, tag=quote['link'],
pair_type=pair_type, exchange=quote['exchange'])
- if n_results == 1: return search_obj
+ if n_results == 1 and user_limit: return search_obj
if search_obj not in search_results: search_results.append(search_obj)
@@ -162,6 +166,9 @@ class instances which will contain the search results so that they can be easily
if len(search_results) >= n_results or len(search_results) >= total_results or params['offset'] >= total_results:
break
+
+ if len(search_results) < 1:
+ raise RuntimeError("ERR#0093: no results found on Investing.com for the introduced query.")
return search_results[:n_results]
@@ -232,18 +239,17 @@ def search_events(text, importances=None, countries=None, n_results=None):
country, pair_type = quote['flag'], quote['pair_type']
if importances is not None:
- if quote['pair_type'] in importances:
- print("TODO")
- ## pair_type = cst.PAIR_FILTERS[quote['pair_type']]
- else:
+ if quote['pair_type'] not in importances:
continue
if countries is not None:
- if quote['flag'] in countries:
- country = cst.FLAG_FILTERS[quote['flag']]
- else:
+ if quote['flag'] not in countries:
continue
+ print("TODO")
+ ## pair_type = PAIR_FILTERS[quote['pair_type']]
+ ## country = FLAG_FILTERS[quote['flag']]
+
search_event = SearchObj(id_=quote['pairId'], name=quote['name'], symbol=quote['symbol'],
country=country, tag=quote['link'],
pair_type=pair_type, exchange=quote['exchange'])
@@ -257,4 +263,7 @@ def search_events(text, importances=None, countries=None, n_results=None):
if len(search_results) >= n_results or len(search_results) >= total_results or params['offset'] >= total_results:
break
+ if len(search_results) < 1:
+ raise RuntimeError("ERR#0093: no results found on Investing.com for the introduced query.")
+
return search_results[:n_results]
diff --git a/investpy/utils/constant.py b/investpy/utils/constant.py
index 4eb1a205..a70a9642 100644
--- a/investpy/utils/constant.py
+++ b/investpy/utils/constant.py
@@ -1,6 +1,68 @@
# Copyright 2018-2021 Alvaro Bartolome, alvarobartt @ GitHub
# See LICENSE for details.
+# To be removed once Investing.com aligns financial products information
+OUTDATED2UPDATED = {
+ 'Prev. Close': 'prevClose',
+ "Day's Range": 'dailyRange',
+ 'ROI (TTM)': 'roiTtm',
+ 'Revenue': 'revenue',
+ 'Open': 'open',
+ 'Price': 'price',
+ 'Price Open': 'priceOpen',
+ 'Price Range': 'priceRange',
+ 'Coupon': 'coupon',
+ 'Coupon Frequency': 'couponFreq',
+ 'Next Coupon Date': 'nextCouponDate',
+ '52 wk Range': 'weekRange',
+ 'EPS': 'eps',
+ 'Volume': 'volume',
+ 'Market Cap': 'marketCap',
+ 'Dividend (Yield)': 'dividend',
+ 'Dividend Yield': 'dividend',
+ 'Average Vol. (3m)': 'avgVolume',
+ 'P/E Ratio': 'ratio',
+ 'Beta': 'beta',
+ 'Month': 'month',
+ 'Duration': 'duration',
+ '1-Year Change': 'oneYearReturn',
+ 'Maturity Date': 'maturityDate',
+ 'Shares Outstanding': 'sharesOutstanding',
+ 'Next Earnings Date': 'nextEarningDate',
+ 'Dividends (TTM)': 'dividednsTtm',
+ 'Total Assets': 'totalAssets',
+ 'Asset Class': 'assetClass',
+ 'Tick Size': 'tickSize',
+ 'Contract Size': 'contractSize',
+ 'Tick Value': 'tickValue',
+ 'Settlement': 'settlement',
+ 'Base Symbol': 'baseSymbol',
+ 'Settlement Day': 'settlementDay',
+ 'Settlement Type': 'settlementType',
+ 'Point Value': 'pointValue',
+ 'Last Rollover Day': 'lastRolloverDay',
+ 'Months': 'months',
+ 'Bid': 'bid',
+ 'Ask': 'ask',
+ 'Rating': 'rating',
+ 'Risk Rating': 'riskRating',
+ 'Issuer': 'issuer',
+ 'Inception Date': 'inceptionDate',
+ 'Min. Investment': 'minInvestment',
+ 'TTM Yield': 'ttmYield',
+ 'Yield': 'yield',
+ 'Turnover': 'turnover',
+ 'ROE': 'roe',
+ 'ROA': 'roa',
+ 'Type': 'type',
+ 'Expenses': 'expenses',
+ 'Category': 'category',
+ 'Leverage': 'leverage',
+ 'Strike Price': 'strikePrice',
+ 'Issue Amount': 'issueAmount',
+ 'Issue Date': 'issueDate'
+}
+
FINANCIAL_SUMMARY_TYPES = {
'income_statement': 0,
'balance_sheet': 1,
@@ -8,33 +70,33 @@
}
FINANCIAL_SUMMARY_PERIODS = {
- "annual": "Annual",
- "quarterly": "Interim"
+ 'annual': 'Annual',
+ 'quarterly': 'Interim'
}
PRODUCT_FILTERS = {
- 'indices': 'indice',
- 'stocks': 'equities',
- 'etfs': 'etf',
- 'funds': 'fund',
- 'commodities': 'commodity',
- 'currencies': 'currency',
- 'cryptos': 'crypto',
- 'bonds': 'bond',
- 'certificates': 'certificate',
+ 'indices': 'indice',
+ 'stocks': 'equities',
+ 'etfs': 'etf',
+ 'funds': 'fund',
+ 'commodities': 'commodity',
+ 'currencies': 'currency',
+ 'cryptos': 'crypto',
+ 'bonds': 'bond',
+ 'certificates': 'certificate',
'fxfutures': 'fxfuture'
}
PAIR_FILTERS = {
- 'indice': 'indices',
- 'equities': 'stocks',
- 'etf': 'etfs',
- 'fund': 'funds',
- 'commodity': 'commodities',
- 'currency': 'currencies',
- 'crypto': 'cryptos',
- 'bond': 'bonds',
- 'certificate': 'certificates',
+ 'indice': 'indices',
+ 'equities': 'stocks',
+ 'etf': 'etfs',
+ 'fund': 'funds',
+ 'commodity': 'commodities',
+ 'currency': 'currencies',
+ 'crypto': 'cryptos',
+ 'bond': 'bonds',
+ 'certificate': 'certificates',
'fxfuture': 'fxfutures'
}
@@ -166,6 +228,13 @@
'monthly': 'month'
}
+# https://www.investing.com/funds/vanguard-500-index-admiral-technical
+FUNDS_INTERVAL_FILTERS = {
+ 'daily': 60*60*24,
+ 'weekly': 'week',
+ 'monthly': 'month'
+}
+
USER_AGENTS = [
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 GTB5",
"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; ko; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2",
diff --git a/investpy/utils/search_obj.py b/investpy/utils/search_obj.py
index fbc97565..28d45d64 100644
--- a/investpy/utils/search_obj.py
+++ b/investpy/utils/search_obj.py
@@ -12,6 +12,7 @@
from .data import Data
from .extra import random_user_agent
+from .constant import INTERVAL_FILTERS, FUNDS_INTERVAL_FILTERS, OUTDATED2UPDATED
class SearchObj(object):
@@ -100,15 +101,15 @@ def retrieve_historical_data(self, from_date, to_date):
`investpy.search_quotes(text, products, countries, n_results)` function search results to build the request
that it is going to be sent to Investing.com so to retrieve and parse the data.
+ Args:
+ from_date (:obj:`str`): date from which data will be retrieved, specified in dd/mm/yyyy format.
+ to_date (:obj:`str`): date until data will be retrieved, specified in dd/mm/yyyy format.
+
Returns:
:obj:`pandas.DataFrame` - data:
This method retrieves the historical data from the current class instance of a financial product
from Investing.com. This method both stores retrieved data in self.data attribute of the class
instance and it also returns it as a normal function will do.
-
- Args:
- from_date (:obj:`str`): date from which data will be retrieved, specified in dd/mm/yyyy format.
- to_date (:obj:`str`): date until data will be retrieved, specified in dd/mm/yyyy format.
Raises:
ValueError: raised if any of the introduced parameters was not valid or errored.
@@ -152,7 +153,7 @@ def retrieve_historical_data(self, from_date, to_date):
continue
if len(self.data) < 1:
- raise RuntimeError("ERR#0004: data retrieval error while scraping.")
+ raise IndexError("ERR#0033: information unavailable or not found.")
else:
headers, params = self._prepare_historical_request(header=header,
from_date=from_date.strftime('%m/%d/%Y'),
@@ -174,7 +175,7 @@ def retrieve_information(self):
Returns:
:obj:`dict` - info:
This method retrieves the information from the current class instance of a financial product
- from Investing.com. This method both stores retrieved information in self.info attribute of the class
+ from Investing.com. This method both stores retrieved information in self.information attribute of the class
instance and it also returns it as a normal function will do.
Raises:
@@ -198,44 +199,56 @@ def retrieve_information(self):
if req.status_code != 200:
raise ConnectionError(f"ERR#0015: error {req.status_code}, try again later.")
- root_ = fromstring(req.text)
- path_ = root_.xpath("//div[contains(@class, 'overviewDataTable')]/div")
+ # Just change this list once the update is included for all the other products
+ updated_for = ['stocks']
+ outdated_for = ['etfs', 'commodities', 'currencies', 'funds', 'bonds', 'cryptos', 'certificates', 'indices', 'fxfutures']
- info = dict()
+ root_ = fromstring(req.text)
+ updated_path = root_.xpath("//dl[@data-test='key-info']/div")
+ outdated_path = root_.xpath("//div[contains(@class, 'overviewDataTable')]/div")
- if not path_:
+ if not updated_path and not outdated_path:
raise RuntimeError("ERR#0004: data retrieval error while scraping.")
-
+
+ path_, investing_updated = (updated_path, True) if updated_path else (outdated_path, False)
+
+ self.information = dict()
+
for elements_ in path_:
- element = elements_.xpath(".//span[@class='float_lang_base_1']")[0]
- title = element.text_content().strip()
- if title == "Day's Range":
- title = 'Todays Range'
+ if investing_updated:
+ element = elements_.xpath(".//dd")[0]
+ title = element.get('data-test')
+ else:
+ element = elements_.xpath(".//span[@class='float_lang_base_1']")[0]
+ title = element.text_content().strip()
+ title = OUTDATED2UPDATED[title]
+ element = element.getnext()
try:
- value = float(element.getnext().text_content().replace(',', ''))
+ value = float(element.text_content().replace(',', ''))
if isinstance(value, float):
if value.is_integer() is True: value = int(value)
- info[title] = value if value != 'N/A' else None
+ self.information[title] = value if value != 'N/A' else None
continue
except:
pass
try:
- text = element.getnext().text_content().strip()
- text = datetime.strptime(text, "%m/%d/%Y").strftime("%d/%m/%Y")
- info[title] = text if text != 'N/A' else None
+ text = element.text_content().strip()
+ in_format = "%b %d, %Y" if investing_updated else "%m/%d/%Y"
+ text = datetime.strptime(text, in_format).strftime("%d/%m/%Y")
+ self.information[title] = text if text != 'N/A' else None
continue
except:
pass
try:
- text = element.getnext().text_content().strip()
+ text = element.text_content().strip()
if text.__contains__('1 = '):
text = text.replace('1 = ', '')
- info[title] = text if text != 'N/A' else None
+ self.information[title] = text if text != 'N/A' else None
continue
except:
pass
try:
- value = element.getnext().text_content().strip()
+ value = element.text_content().strip()
if value.__contains__('K'):
value = float(value.replace('K', '').replace(',', '')) * 1e3
elif value.__contains__('M'):
@@ -246,13 +259,141 @@ def retrieve_information(self):
value = float(value.replace('T', '').replace(',', '')) * 1e12
if isinstance(value, float):
if value.is_integer() is True: value = int(value)
- info[title] = value if value != 'N/A' else None
+ self.information[title] = value if value != 'N/A' else None
continue
except:
pass
- self.info = info
- return self.info
+ return self.information
+
+ def retrieve_technical_indicators(self, interval='daily'):
+ """Class method used to retrieve the technical indicators from the class instance of any financial product.
+
+ This method retrieves the technical indicators from Investing.com for the financial product of the current
+ class instance, to later put in into the `SearchObj.technical_indicators` attribute. This method uses the
+ previously retrieved data from the `investpy.search_quotes(text, products, countries, n_results)`
+ function search results to build the request that it is going to be sent to Investing.com so to retrieve and
+ parse the technical indicators, since the product id is required.
+
+ Args:
+ interval (:obj:`str`, optional):
+ time interval of the technical indicators' calculations, available values are: `5mins`, `15mins`,
+ `30mins`, `1hour`, `5hours`, `daily`, `weekly` and `monthly`. Note that for funds just the intervals:
+ `daily`, `weekly` and `monthly` are available.
+
+ Returns:
+ :obj:`pd.DataFrame` - technical_indicators:
+ This method retrieves the technical indicators from the current class instance of a financial product
+ from Investing.com. This method not just stores retrieved technical indicators table into self.technical_indicators
+ but it also returns it as a normal function will do.
+
+ Raises:
+ ValueError: raised if any of the input parameters is not valid.
+ ConnectionError: raised if connection to Investing.com could not be established.
+ RuntimeError: raised if there was any problem while retrieving the data from Investing.com.
+
+ """
+
+ if self.pair_type in []:
+ raise ValueError(f"Investing.com does not provide technical indicators for {self.pair_type}.")
+
+ if self.pair_type != 'funds' and interval not in INTERVAL_FILTERS:
+ raise ValueError(f"Investing.com just provides the following intervals for {self.pair_type}' technical " \
+ f"indicators: {', '.join(list(INTERVAL_FILTERS.keys()))}")
+
+ if self.pair_type == 'funds' and interval not in FUNDS_INTERVAL_FILTERS:
+ raise ValueError("Investing.com just provides the following intervals for funds' technical " \
+ f"indicators: {', '.join(list(FUNDS_INTERVAL_FILTERS.keys()))}")
+
+ params = {
+ 'pairID': self.id_,
+ 'period': INTERVAL_FILTERS[interval],
+ 'viewType': 'normal'
+ }
+
+ headers = {
+ "User-Agent": random_user_agent(),
+ "X-Requested-With": "XMLHttpRequest",
+ "Accept": "text/html",
+ "Accept-Encoding": "gzip, deflate",
+ "Connection": "keep-alive",
+ }
+
+ url = "https://www.investing.com/instruments/Service/GetTechincalData"
+
+ req = requests.post(url, headers=headers, data=params)
+
+ if req.status_code != 200:
+ raise ConnectionError(f"ERR#0015: error {req.status_code}, try again later.")
+
+ root_ = fromstring(req.text)
+ table_ = root_.xpath(".//table[contains(@class, 'technicalIndicatorsTbl')]/tbody/tr")
+
+ if not table_:
+ raise RuntimeError("ERR#0004: data retrieval error while scraping.")
+
+ self.technical_indicators = pd.DataFrame()
+
+ for row in table_:
+ for value in row.xpath("td"):
+ if value.get('class').__contains__('symbol'):
+ self.technical_indicators = self.technical_indicators.append({
+ 'indicator': value.text_content().strip(),
+ 'value': float(value.getnext().text_content().strip()),
+ 'signal': (value.getnext().getnext().text_content().strip().lower()).replace(' ', '_')
+ }, ignore_index=True)
+
+ return self.technical_indicators
+
+ def retrieve_currency(self):
+ """Class method used to retrieve the default currency from the class instance of any financial product.
+
+ This method retrieves the default currency from Investing.com of the financial product of the current class
+ instance. This method uses the data previously retrieved from the `investpy.search_quotes(text, products, countries, n_results)`
+ function search results to build the request that it is going to be sent to Investing.com so to retrieve and
+ parse the information, since the product tag is required.
+
+ Returns:
+ :obj:`str` - default_currency:
+ This method retrieves the default currency from the current class instance of a financial product
+ from Investing.com.
+
+ Raises:
+ ConnectionError: raised if connection to Investing.com could not be established.
+ RuntimeError: raised if there was any problem while retrieving the data from Investing.com.
+
+ """
+
+ url = f"https://www.investing.com{self.tag}"
+
+ headers = {
+ "User-Agent": random_user_agent(),
+ "X-Requested-With": "XMLHttpRequest",
+ "Accept": "text/html",
+ "Accept-Encoding": "gzip, deflate",
+ "Connection": "keep-alive",
+ }
+
+ req = requests.get(url, headers=headers)
+
+ if req.status_code != 200:
+ raise ConnectionError(f"ERR#0015: error {req.status_code}, try again later.")
+
+ # Just change this list once the update is included for all the other products
+ updated_for = ['stocks']
+ outdated_for = ['etfs', 'commodities', 'currencies', 'funds', 'bonds', 'cryptos', 'certificates', 'indices', 'fxfutures']
+
+ root_ = fromstring(req.text)
+ updated_path = root_.xpath("//div[contains(@class, 'instrument-metadata_currency')]/span")
+ outdated_path = root_.xpath("//div[@id='quotes_summary_current_data']/div/div/div[contains(@class, 'bottom')]/span[@class='bold']")
+
+ if not updated_path and not outdated_path:
+ raise RuntimeError("ERR#0004: data retrieval error while scraping.")
+
+ path_, investing_updated = (updated_path, True) if updated_path else (outdated_path, False)
+
+ self.default_currency = path_[-1].text_content().strip()
+ return self.default_currency
def _prepare_request(self, header):
headers = {
@@ -322,10 +463,8 @@ def _calculate_intervals(self, from_date, to_date):
return intervals
def _data_retrieval(self, product, headers, params):
- if product in ['stocks', 'etfs', 'indices', 'fxfutures', 'cryptos']:
- has_volume = True
- else:
- has_volume = False
+ has_volume = True if product in ['stocks', 'etfs', 'indices', 'cryptos', 'commodities', 'fxfutures'] else False
+ has_change_pct = True # Every financial product has it
url = "https://www.investing.com/instruments/HistoricalDataAjax"
@@ -346,8 +485,8 @@ def _data_retrieval(self, product, headers, params):
info = []
for nested_ in elements_.xpath(".//td"):
- val = nested_.get('data-real-value')
- if val is None and nested_.text_content() == 'No results found':
+ val = nested_.get('data-real-value') if nested_.get('data-real-value') is not None else nested_.text_content()
+ if val == 'No results found':
raise IndexError("ERR#0033: information unavailable or not found.")
info.append(val)
@@ -359,7 +498,12 @@ def _data_retrieval(self, product, headers, params):
'Close': float(info[1].replace(',', ''))
}
- if has_volume is True: result['Volume'] = int(info[5])
+ if has_volume and has_change_pct:
+ result['Volume'] = int(info[5])
+ result['Change Pct'] = float(info[6].replace(',', '').replace('%', ''))
+
+ if not has_volume and has_change_pct:
+ result['Change Pct'] = float(info[5].replace(',', '').replace('%', ''))
results.append(result)
diff --git a/setup.py b/setup.py
index fc991a99..b6dfe3fd 100644
--- a/setup.py
+++ b/setup.py
@@ -20,10 +20,10 @@ def requirements(filename):
setup(
name='investpy',
- version='1.0.6',
+ version='1.0.7',
packages=find_packages(),
url='https://investpy.readthedocs.io/',
- download_url='https://github.com/alvarobartt/investpy/archive/1.0.6.tar.gz',
+ download_url='https://github.com/alvarobartt/investpy/archive/1.0.7.tar.gz',
license='MIT License',
author='Alvaro Bartolome',
author_email='alvarobdc@yahoo.com',
diff --git a/tests/test_investpy.py b/tests/test_investpy.py
index f1ae45b2..edc2bf49 100644
--- a/tests/test_investpy.py
+++ b/tests/test_investpy.py
@@ -1316,9 +1316,23 @@ def test_investpy_search():
print(result)
assert result.retrieve_recent_data() is not None
+
for date in dates:
assert result.retrieve_historical_data(from_date=date['from_date'], to_date=date['to_date']) is not None
+ assert result.retrieve_currency() is not None
+ assert result.retrieve_technical_indicators() is not None
+
+ financial_products = [
+ ('stocks', 'apple'), ('etfs', 'apple'), ('commodities', 'apple'), ('currencies', 'usd'), ('funds', 'apple'),
+ ('bonds', 'apple'), ('cryptos', 'bitcoin'), ('certificates', 'apple'), ('indices', 'apple'), ('fxfutures', 'usd')
+ ]
+
+ for product_type, product_name in financial_products:
+ search_result = investpy.search_quotes(text=product_name, products=[product_type], n_results=1)
+
+ assert search_result.retrieve_information() is not None
+
def test_investpy_news():
"""
@@ -1386,19 +1400,3 @@ def test_investpy_technical():
country=param['country'],
product_type=param['product_type'],
interval=param['interval'])
-
-
-if __name__ == '__main__':
- test_investpy()
- test_investpy_stocks()
- test_investpy_funds()
- test_investpy_etfs()
- test_investpy_indices()
- test_investpy_currency_crosses()
- test_investpy_bonds()
- test_investpy_commodities()
- test_investpy_cryptos()
- test_investpy_certificates()
- test_investpy_search()
- test_investpy_news()
- test_investpy_technical()
diff --git a/tests/test_investpy_errors.py b/tests/test_investpy_errors.py
index 0646142d..0d0b2f41 100644
--- a/tests/test_investpy_errors.py
+++ b/tests/test_investpy_errors.py
@@ -1101,7 +1101,7 @@ def test_funds_errors():
investpy.search_funds(by=param['by'], value=param['value'])
except:
pass
-
+
def test_etfs_errors():
"""
@@ -3897,6 +3897,12 @@ def test_search_errors():
'products': None,
'countries': ['error'],
'n_results': 10
+ },
+ {
+ 'text': 'bbva',
+ 'products': None,
+ 'countries': None,
+ 'n_results': 10
}
]
@@ -3922,13 +3928,20 @@ def test_search_errors():
},
]
- for result in results:
+ for result in results[:1]:
for date in dates:
try:
result.retrieve_historical_data(from_date=date['from_date'], to_date=date['to_date'])
except:
continue
- break
+
+ intervals = ['non_existing', '1min']
+ for interval in intervals:
+ try:
+ result.pair_type = 'funds'
+ result.retrieve_technical_indicators(interval=interval)
+ except:
+ continue
except:
pass
@@ -4175,18 +4188,3 @@ def test_technical_errors():
interval=param['interval'])
except:
pass
-
-
-if __name__ == '__main__':
- test_stocks_errors()
- test_funds_errors()
- test_etfs_errors()
- test_indices_errors()
- test_currency_crosses_errors()
- test_bonds_errors()
- test_commodities_errors()
- test_crypto_errors()
- test_certificate_errors()
- test_search_errors()
- test_technical_errors()
- test_news_errors()