summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-05-05 12:33:28 +0000
committerCoprDistGit <infra@openeuler.org>2023-05-05 12:33:28 +0000
commit333c3e066030a5a3c9e70846a56cd41c12e91da6 (patch)
tree9e750d78c5389d5f8d562c257d10e7f6cb028b60
parent09666d9822f3f5138ff30543deaf8d46b15a96fe (diff)
automatic import of python-degiro-connectoropeneuler20.03
-rw-r--r--.gitignore1
-rw-r--r--python-degiro-connector.spec5787
-rw-r--r--sources1
3 files changed, 5789 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..a54d503 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/degiro_connector-2.0.23.tar.gz
diff --git a/python-degiro-connector.spec b/python-degiro-connector.spec
new file mode 100644
index 0000000..5e441f2
--- /dev/null
+++ b/python-degiro-connector.spec
@@ -0,0 +1,5787 @@
+%global _empty_manifest_terminate_build 0
+Name: python-degiro-connector
+Version: 2.0.23
+Release: 1
+Summary: This is yet another library to access Degiro's API.
+License: BSD-3-Clause
+URL: https://github.com/chavithra/degiro-connector
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/59/28/98380ff9e3b8e873e7693a13276f0e3a694333dbd0dd7e19535f1c642301/degiro_connector-2.0.23.tar.gz
+BuildArch: noarch
+
+Requires: python3-grpcio
+Requires: python3-onetimepass
+Requires: python3-pandas
+Requires: python3-protobuf
+Requires: python3-requests
+Requires: python3-wrapt
+
+%description
+# 1. **Degiro Connector**
+
+This is yet another library to access Degiro's API.
+
+Notes :
+- Migration scripts are available :
+```bash
+python -m degiro_connector.migration.from_0_1_3_to_1_0_0
+python -m degiro_connector.migration.from_1_0_4_to_1_0_5
+python -m degiro_connector.migration.from_1_0_10_to_2_0_0
+python -m degiro_connector.migration.from_2_0_2_to_2_0_3
+```
+- `GRPC` services are available to let you consume this library through other languages like Javascript, Java, Go, C++, Rust, etc :
+```bash
+python -m examples.quotecast.relay_server
+python -m examples.trading.relay_server
+
+```
+
+## 1.1. Which features ?
+Here are the features you can access through this library :
+
+|**Endpoint**|**Feature(s)**|
+|:-|:-|
+|AccountCashReport|Export cash movements in a specific format : CSV, HTML, PDF or XLS.|
+|AccountInfo|Retrieve a table containing : "clientId" and Currencies.|
+|AccountOverview|Retrieve all the cash movements between two dates.|
+|Agenda|Crucial events regarding products : Dividend, Economic, Earnings, Holiday, IPO or Split.|
+|Bonds<br>ETFs<br>Funds<br>Futures<br>Leverageds<br>Lookup<br>Options<br>Stocks<br>Warrants|Search list of products according their name, type and other criterias. <br> For instance all the stocks from NASDAQ 100.|
+|Chart|Retrieve chart data.|
+|ClientDetails|Retrieve a table containing : "clientId", "intAccount" and other account information.|
+|CompanyProfile|Retrieve a company's profile using its ISIN code.|
+|CompanyRatios|Retrieve a company's ratios using its ISIN code.|
+|Config|Retrieve a table containing : "clientId" and URLs which are constitutive of Degiro's API.|
+|EstimatesSummaries|Retrieve a company's estimates summaries using its ISIN code.|
+|FavouritesList|Add/Delete/Retrieve favourites lists.|
+|FavouritesListProducts|Add/Update favourites lists content.|
+|FinancialStatements|Retrieve a company's financial statements using its ISIN code.|
+|LatestNews|Retrieve latest news about all the companies.|
+|LoginQuotecast|Establish a connection for quotecast operations.|
+|LoginTrading|Establish a connection for trading operations.|
+|LogoutTrading|Destroy previously established connection for trading operations.|
+|NewsByCompany|Retrieve news related to a specific company.|
+|Order|Create, update, delete an Order.|
+|OrderHistory|Retrieve all Orders created between two dates.|
+|Orders|List pending Orders.|
+|Portfolio|List products in your Portfolio.|
+|ProductsConfig|Retrieve a table containing : useful parameters to filter products.|
+|ProductsInfo|Search for products using their ids.|
+|Quotecasts|Fetch real-time data on financial products. <br> For instance the real-time stock Price.|
+|TopNewsPreview|Retrieve some news preview about all the companies.|
+|TotalPorfolio|Retrieve aggregated information about your assets.|
+|TransactionsHistory|Retrieve all Transactions created between two dates.|
+
+## 1.2. How to install ?
+
+```bash
+pip install degiro-connector
+```
+
+## 1.3. How to upgrade ?
+
+```bash
+pip install --no-cache-dir --upgrade degiro-connector
+```
+
+## 1.4. How to uninstall ?
+
+```bash
+pip uninstall degiro-connector
+```
+
+## 1.5. Table of contents
+- [1. **Degiro Connector**](#1-degiro-connector)
+ * [1.1. Which features ?](#11-which-features-)
+ * [1.2. How to install ?](#12-how-to-install-)
+ * [1.3. How to upgrade ?](#13-how-to-upgrade-)
+ * [1.4. How to uninstall ?](#14-how-to-uninstall-)
+ * [1.5. Table of contents](#15-table-of-contents)
+- [2. Real-time data](#2-real-time-data)
+ * [2.1. What are the workflows ?](#21-what-are-the-workflows-)
+ * [2.2. What are the credentials ?](#22-what-are-the-credentials-)
+ * [2.3. How to find your : user_token ?](#23-how-to-find-your--user_token-)
+ * [2.4. How to login ?](#24-how-to-login-)
+ * [2.5. Is there a timeout ?](#25-is-there-a-timeout-)
+ * [2.6. How to subscribe to a data-stream ?](#26-how-to-subscribe-to-a-data-stream-)
+ * [2.7. How to unsubscribe to a data-stream ?](#27-how-to-unsubscribe-to-a-data-stream-)
+ * [2.8. How to fetch the data ?](#28-how-to-fetch-the-data-)
+ * [2.9. How to use this data ?](#29-how-to-use-this-data-)
+ * [2.10. Which are the available data types ?](#210-which-are-the-available-data-types-)
+ * [2.11. What is a Ticker ?](#211-what-is-a-ticker-)
+ * [2.12. What is inside the Dictionary ?](#212-what-is-inside-the-dictionary-)
+ * [2.13. What is inside the DataFrame ?](#213-what-is-inside-the-dataframe-)
+ * [2.14. How to get chart data ?](#214-how-to-get-chart-data-)
+ * [2.15. How to find a : vwd_id ?](#215-how-to-find-a--vwd_id-)
+- [3. Trading connection](#3-trading-connection)
+ * [3.1. How to login ?](#31-how-to-login-)
+ * [3.2. How to logout ?](#32-how-to-logout-)
+ * [3.3. What are the credentials ?](#33-what-are-the-credentials-)
+ * [3.4. How to find your : int_account ?](#34-how-to-find-your--int_account-)
+ * [3.5. How to use 2FA ?](#35-how-to-use-2fa-)
+ * [3.6. How to find your : totp_secret_key ?](#36-how-to-find-your--totp_secret_key-)
+ * [3.7. How to find your : one_time_password ?](#37-how-to-find-your--one_time_password-)
+ * [3.8. Is there a timeout ?](#38-is-there-a-timeout-)
+ * [3.9. How to manage : TimeoutError ?](#39-how-to-manage--TimeoutError-)
+- [4. Order](#4-order)
+ * [4.1. How to create an Order ?](#41-how-to-create-an-order-)
+ * [4.1.1. Check Order](#411-check-order)
+ * [4.1.2. Confirm Order](#412-confirm-order)
+ * [4.2. How to update an Order ?](#42-how-to-update-an-order-)
+ * [4.3. How to delete an Order ?](#43-how-to-delete-an-order-)
+- [5. Portfolio](#5-portfolio)
+ * [5.1. How to retrieve pending Orders ?](#51-how-to-retrieve-pending-orders-)
+ * [5.2. How to get the Portfolio ?](#52-how-to-get-the-portfolio-)
+ * [5.3. How to get the TotalPortfolio ?](#53-how-to-get-the-totalportfolio-)
+ * [5.4. How to retrieve the OrdersHistory ?](#54-how-to-retrieve-the-ordershistory-)
+ * [5.5. How to retrieve the TransactionsHistory ?](#55-how-to-retrieve-the-transactionshistory-)
+- [6. Account](#6-account)
+ * [6.1. How to retrieve the table : Config ?](#61-how-to-retrieve-the-table--config-)
+ * [6.2. How to retrieve the table : ClientDetails ?](#62-how-to-retrieve-the-table--clientdetails-)
+ * [6.3. How to retrieve the table : AccountInfo ?](#63-how-to-retrieve-the-table--accountinfo-)
+ * [6.4. How to get the table : AccountOverview ?](#64-how-to-get-the-table--accountoverview-)
+ * [6.5. How to export the table : CashAccountReport ?](#65-how-to-export-the-table--cashaccountreport-)
+ * [6.6. How to export the table : PositionReport ?](#66-how-to-export-the-table--positionreport-)
+- [7. Products](#7-products)
+ * [7.1. How to get the table : ProductsConfig ?](#71-how-to-get-the-table--productsconfig-)
+ * [7.2. How to get my favourite products ?](#72-how-to-get-my-favourite-products-)
+ * [7.3. How to lookup products (search by name) ?](#73-how-to-lookup-products-search-by-name-)
+ * [7.4. How to search bonds ?](#74-how-to-search-bonds-)
+ * [7.5. How to search etfs ?](#75-how-to-search-etfs-)
+ * [7.6. How to search funds ?](#76-how-to-search-funds-)
+ * [7.7. How to search futures ?](#77-how-to-search-futures-)
+ * [7.8. How to search leverageds ?](#78-how-to-search-leverageds-)
+ * [7.9. How to search options ?](#79-how-to-search-options-)
+ * [7.10. How to search stocks ?](#710-how-to-search-stocks-)
+ * [7.11. How to search warrants ?](#711-how-to-search-warrants-)
+ * [7.12. How to search products from ids ?](#712-how-to-search-products-from-ids-)
+ * [7.13. How to create a favourite list ?](#713-how-to-create-a-favourite-list-)
+ * [7.14. How to delete a favourite list ?](#714-how-to-delete-a-favourite-list-)
+ * [7.15. How to put favourite list products ?](#715-how-to-put-favourite-list-products-)
+ * [7.16. How to delete favourite list products ?](#716-how-to-delete-favourite-list-products-)
+- [8. Companies](#8-companies)
+ * [8.1. How to get : CompanyProfile ?](#81-how-to-get--companyprofile-)
+ * [8.2. How to get : CompanyRatios ?](#82-how-to-get--companyratios-)
+ * [8.3. How to get : FinancialStatements ?](#83-how-to-get--financialstatements-)
+ * [8.4. How to get : LatestNews ?](#84-how-to-get--latestnews-)
+ * [8.5. How to get : TopNewsPreview ?](#85-how-to-get--topnewspreview-)
+ * [8.6. How to get : NewsByCompany ?](#86-how-to-get--newsbycompany-)
+ * [8.7. How to get : Agenda ?](#87-how-to-get--agenda-)
+ * [8.8. How to get : EstimatesSummaries ?](#88-how-to-get--estimatessummaries-)
+- [9. Contributing](#9-contributing)
+- [10. License](#10-license)
+
+# 2. Real-time data
+
+It is possible to fetch a stream of data in real-time from Degiro's API.
+
+For instance if one needs the following data from the "AAPL" stock :
+* LastDate
+* LastTime
+* LastPrice
+* LastVolume
+
+You can use this library to retrieve updates like this :
+
+ LastDate LastTime LastPrice LastVolume
+ 2020-11-13 22:00:00 119.26 4697040
+
+For a list of available metrics, see the example in [section 2.6](#26-how-to-subscribe-to-a-data-stream-).
+
+## 2.1. What are the workflows ?
+
+This is the workflow for consuming real-time data-stream :
+
+ A. Find your "user_token".
+ B. Setup the API object with your "user_token".
+ C. Connect.
+ D. Subscribe to data-stream.
+ E. Fetch data-stream.
+
+This is the worflow for consuming charts :
+
+ A. Find your "user_token".
+ B. Setup the API object with your "user_token".
+ C. Fetch charts.
+
+All the details of these steps are explained in the rest of this section.
+
+## 2.2. What are the credentials ?
+
+The only credential you need in order to fetch real-time data and charts is the :
+* user_token
+
+Beware, these two identifiers are not the same thing :
+* user_token : used to fetch real-time data and charts.
+* int_account : used for some trading operations.
+
+## 2.3. How to find your : user_token ?
+You can find your "user_token" inside one of these tables :
+* "Config" : attribute "clientId"
+* "ClientDetails" : attribute "id"
+
+See sections related to ["Config"](#61-how-to-retrieve-the-table--config-) and ["ClientDetails"](#62-how-to-retrieve-the-table--clientdetails-) tables.
+
+## 2.4. How to login ?
+
+In order to fetch data you need to establish a connection.
+
+You can use the following code to connect :
+
+```python
+# SETUP QUOTECAST API
+quotecast_api = API(user_token=YOUR_USER_TOKEN)
+
+# CONNECTION
+quotecast_api.connect()
+```
+
+## 2.5. Is there a timeout ?
+
+Connection timeout is around 15 seconds.
+
+Which means a connection will cease to work after this timeout.
+
+This timeout is reset each time you use this connection to :
+* Subscribe to a metric (for instance a stock Price)
+* Fetch the data-stream
+
+So if you use it nonstop (in a loop) you won't need to reconnect.
+
+## 2.6. How to subscribe to a data-stream ?
+
+To subscribe to a data-stream you need to setup a Request message.
+
+A Request has the following parameters :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|subscriptions|MessageMap|List of products and metrics to subscribe to.|
+|unsubscriptions|MessageMap|List of products and metrics to unsubscribe to.|
+
+Here is an example of a request :
+```python
+request = Quotecast.Request()
+request.subscriptions['360015751'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+request.subscriptions['AAPL.BATS,E'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+```
+
+In this example these are the `vwd_id` of the products from which you want `Real-time data` :
+- 360015751
+- AAPL.BATS,E
+
+See the [section](#215-how-to-find-a--vwd_id-) related to `vwd_id` for more information.
+
+Once you have built this Request object you can send it to Degiro's API like this :
+```python
+quotecast_api.subscribe(request=request)
+```
+
+For more comprehensive examples :
+[realtime_poller.py](examples/quotecast/realtime_poller.py) /
+[realtime_one_shot.py](examples/quotecast/realtime_one_shot.py)
+
+## 2.7. How to unsubscribe to a data-stream ?
+
+To remove metrics from the data-stream you need to setup a Request message.
+
+If you try to unsubscribe to a metric to which you didn't subscribed previously it will most likely have no impact.
+
+A Request has the following parameters :
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|subscriptions|MessageMap|List of products and metrics to subscribe to.|
+|unsubscriptions|MessageMap|List of products and metrics to unsubscribe to.|
+
+Here is an example of a request :
+```python
+request = Quotecast.Request()
+request.unsubscriptions['360015751'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+request.unsubscriptions['AAPL.BATS,E'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+```
+
+Once you have built this Request object you can send it to Degiro's API like this :
+```python
+quotecast_api.subscribe(request=request)
+```
+
+For more comprehensive examples :
+[realtime_poller.py](examples/quotecast/realtime_poller.py) /
+[realtime_one_shot.py](examples/quotecast/realtime_one_shot.py)
+
+## 2.8. How to fetch the data ?
+
+You can use the following code :
+```python
+quotecast = quotecast_api.fetch_data()
+```
+
+For a more comprehensive example :
+[realtime_poller.py](examples/quotecast/realtime_poller.py)
+
+## 2.9. How to use this data ?
+
+Received data is a `Quotecast` object with the following properties :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|json_data|dict|Dictionary representation of what Degiro's API has sent.|
+|metadata|Metadata|Containing the "response_datetime" and "request_duration".|
+
+Here is how to access these properties :
+```python
+json_data = quotecast.json_data
+response_datetime = quotecast.metadata.response_datetime
+request_duration= quotecast.metadata.request_duration
+```
+Notes:
+* The API sometimes might return an empty Quotecast object.
+* The API often returns a subset of the requested metrics, e.g. only `'LastPrice'`. Please take this into account when appending consecutive data responses.
+
+## 2.10. Which are the available data types ?
+
+This library provides the tools to convert Degiro's JSON data into something more programmer-friendly.
+
+Here is the list of available data types :
+
+|**Type**|**Description**|
+|:-|:-|
+|Ticker|Protobuf message (for GRPC).|
+|Dictionaries|Standard Python Dictionaries : **dict**.|
+|DataFrame|DataFrame from the library Pandas.|
+
+Here is how to build each type :
+
+```python
+# UPDATE PARSER
+quotecast_parser.put_quotecast(quotecast=quotecast)
+
+# BUILD TICKER
+ticker = quotecast_parser.ticker
+
+# BUILD DICT
+ticker_dict = quotecast_parser.ticker_dict
+
+# BUILD PANDAS.DATAFRAME
+ticker_df = quotecast_parser.ticker_df
+```
+
+## 2.11. What is a Ticker ?
+
+The generated Ticker contains :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|metadata|Metadata|Containing the "response_datetime" and "request_duration".|
+|products|MessageMap|Dictionary like object containing the metrics group by "vwd_id".|
+|product_list|RepeatedScalarFieldContainer|List of available "vwd_id".|
+
+Here are some operations available :
+
+```python
+product = '360015751'
+metric_name = 'LastPrice'
+
+# ACCESS SPECIFIC PRODUCT
+product = ticker.products[product]
+
+# ACCESS SPECIFIC METRIC
+metric = product[metric_name]
+
+# LOOP OVER PRODUCTS
+for product in ticker.products:
+ product = ticker.products[product]
+
+# LOOP OVER METRICS
+for metric_name in product.metrics:
+ metric = product.metrics[metric_name]
+```
+
+A Ticker is a custom Protocol Buffer Message built for this library.
+
+It can be transmitted over GRPC framework.
+
+## 2.12. What is inside the Dictionary ?
+
+The dictionary representation of a ticker contains the metrics grouped by "vwd_id" (product id), with :
+* keys : vwd_id
+* values : another dictionary with the metrics concerning this specific product.
+
+Example - Dictionary :
+
+```python
+{
+ '360114899': {
+ 'vwd_id': 360114899,
+ 'response_datetime': '2020-11-08 12:00:27',
+ 'request_duration': 1.0224891666870117,
+ 'LastDate': '2020-11-06',
+ 'LastTime': '17:36:17',
+ 'LastPrice': '70.0',
+ 'LastVolume': '100'
+ },
+ '360015751': {
+ 'vwd_id': 360015751,
+ 'response_datetime': '2020-11-08 12:00:27',
+ 'request_duration': 1.0224891666870117,
+ 'LastDate': '2020-11-06',
+ 'LastTime': '17:36:17',
+ 'LastPrice': '22.99',
+ 'LastVolume': '470'
+ }
+}
+```
+
+## 2.13. What is inside the DataFrame ?
+
+In addition to whatever metrics you have chosen to subscribe to (see the example in [section 2.6](#26-how-to-subscribe-to-a-data-stream-)), the DataFrame will contain the following columns :
+|**Column**|**Description**|
+|:-|:-|
+|vwd_id|Product identifier, for instance "AAPL.BATS,E" for APPLE stock.|
+|response_datetime|Datetime at which the data was received.|
+|request_duration|Duration of the request used to fetch the data.|
+
+Example - DataFrame :
+
+ vwd_id response_datetime request_duration LastDate LastTime LastPrice LastVolume
+ 0 360114899 2020-11-08 12:00:27 1.022489 2020-11-06 17:39:57 70.0 100
+ 1 360015751 2020-11-08 12:00:27 1.022489 2020-11-06 17:36:17 22.99 470
+
+## 2.14. How to get chart data ?
+You can fetch an object containing the same data than in Degiro's website graph.
+
+For that you need to prepare a Chart.Request object.
+
+Here is a table with the available attributes for Chart.Request.
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|requestid|str|It sends you back whatever string you put here, you can set it to : "1".|
+|resolution|Chart.Resolution|Resolution of the chart like : Chart.Resolution.PT1M.|
+|culture|str|Country code like : "en-US" or "fr-FR".|
+|period|Chart.Period|Period of the chart, like : Chart.Period.P1D.|
+|series|repeated string|Data to get like : ['issueid:36014897', 'price:issueid:360148977'].|
+|tz|str|Timezone like : "Europe/Paris"|
+
+Example of code :
+
+```python
+request = Chart.Request()
+request.culture = "fr-FR"
+request.period = Chart.Interval.PT1H
+request.requestid = "1"
+request.resolution = Chart.Interval.P1D
+# request.series.append("issueid:360148977")
+# request.series.append("price:issueid:360148977")
+request.series.append("ohlc:issueid:360148977")
+# request.series.append("volume:issueid:360148977")
+# request.series.append("vwdkey:AAPL.BATS,E")
+# request.series.append("price:vwdkey:AAPL.BATS,E")
+# request.series.append("ohlc:vwdkey:AAPL.BATS,E")
+# request.series.append("volume:vwdkey:AAPL.BATS,E")
+request.tz = "Europe/Paris"
+
+# FETCH DATA
+chart = quotecast_api.get_chart(
+ request=request,
+ override={
+ "resolution": "P1D",
+ "period": "P1W",
+ },
+ raw=True,
+)
+```
+
+The `issueid` parameter is the `vwd_id` of the product from which you want the `Chart` data.
+
+See the section related to `vwd_id` for more information.
+
+All the options for the enumerations are available in this file :
+[quotecast.proto](protos/degiro_connector/quotecast/models/quotecast.proto)
+
+For a more comprehensive examples :
+ - [chart.py](examples/quotecast/chart.py)
+ - [chart_format.py](examples/quotecast/chart_format.py)
+
+## 2.15. How to find a : vwd_id ?
+
+In operations related to `Quotecast`, Degiro uses the `vwd_id` to identify a product.
+
+Which means that if you want a `Chart` or `Real-time data` for a specific product : you first need to find this product's `vwd_id`.
+
+This two identifiers are not the same :
+
+|**Identifier**|**API name(s)**|**Description**|
+|:-|:-|:-|
+|id|str|Id used identify a product in `Trading` related endpoints.|
+|vwd_id|issueid <br /> vwdId <br /> vwdIdSecondary <br />|Id used identify a product in `Quotecast` (`Chart` and `Real-time data`) related endpoint.|
+
+Here are some methods you can use to fetch a product's `vwd_id` :
+- `product_search`
+- `get_products_info`
+
+The method `product_search` let you use the name or other attributes of a product to fetch it's `vwd_id`.
+
+The method `get_products_info` let you use a product's `id` to fetch it's `vwd_id`.
+
+
+# 3. Trading connection
+
+This library is divided into two modules :
+- quotecast : to consume real-time financial data.
+- trading : to manage your Degiro's account.
+
+The module **quotecast** is described in the section related to real-time data.
+
+The rest of this document will only refer to the module : **trading**.
+
+## 3.1. How to login ?
+In order to use the module **trading.api** you need to establish a connection.
+
+Check the section related to **int_account** to understand how to get yours.
+
+Here is how to connect :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username = YOUR_USERNAME,
+ password = YOUR_PASSWORD,
+ int_account = YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+For a more comprehensive example :
+[connection.py](examples/trading/connection.py)
+
+## 3.2. How to logout ?
+
+Once you no longer need to use the API you can destroy your connection.
+
+You can use the following code to disconnect :
+
+```python
+# DESTROY CONNECTION
+trading_api.logout()
+```
+
+For a more comprehensive example :
+[logout.py](examples/trading/logout.py)
+
+## 3.3. What are the credentials ?
+
+Some credentials are required to use Degiro's trading API.
+
+Here are these credentials :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|username|str|Username used to log into Degiro's website.|
+|password|str|Password used to log into Degiro's website.|
+|int_account|int|OPTIONAL : unique identifier of the account : used by Degiro's server.|
+|totp_secret_key|str|OPTIONAL : used for Two-factor Authentication (2FA).|
+|one_time_password|str|OPTIONAL : used for Two-factor Authentication (2FA).|
+
+Check the section related to **int_account** to understand how to get yours.
+
+Check the section related to **2FA** if you want to know more about these two parameters :
+- **totp_secret_key**
+- **one_time_password**
+
+## 3.4. How to find your : int_account ?
+
+To get your **int_acccount** you can run this example :
+[client_details_table.py](examples/trading/client_details_table.py)
+
+See section related to **ClientDetails** table for more details.
+
+This **int_acccount** is required to do most of the trading operations available in this connector.
+
+Here are some operations for which your **int_acccount** is not required :
+- Connection
+- Fetch table : ClientDetails
+- Fetch table : Config
+
+Beware, these two identifiers are not the same thing :
+- user_token : used to fetch real-time data and charts.
+- int_account : used for some trading operations.
+
+## 3.5. How to use 2FA ?
+
+First I will briefly explain what is : **Two-Factor Authentication (2FA)**.
+
+I recommend to skip a few paragraphs if you already know what is **2FA**.
+
+In a standard connection you are providing two parameters:
+- username
+- password
+
+If you use **Two-Factor Authentication (2FA)** you need an extra parameter:
+- one_time_password
+
+This **one_time_password** has a validity of 30 secondes and is generated using a **totp_secret_key** code.
+
+Usually you use an app like **‎Google Authenticator** to store this **totp_secret_key** and generate the **one_time_password**.
+
+The **totp_secret_key** is stored inside the QRCode which is displayed when you enable 2FA on Degiro's website
+
+To use **2FA** with this library you have two solutions.
+
+**SOLUTION 1**
+
+Provide your **totp_secret_key** : the library will use it to generate a new **one_time_password** at each connection.
+
+So you won't have to type your **one_time_password** manually at each connection.
+
+This is the proper way.
+
+See the section about **totp_secret_key** to understand how to get yours.
+
+Here is an example of connection with the **totp_secret_key** :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username=YOUR_USERNAME,
+ password=YOUR_PASSWORD,
+ int_account=YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+ totp_secret_key=YOUR_2FA_SECRET_KEY, # ONLY IF 2FA IS ENABLED
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+A complete example here :
+[connection_2fa.py](examples/trading/connection_2fa.py)
+
+**SOLUTION 2**
+
+Provide a new **one_time_password** at each connection.
+
+Here is an example of connection with the **one_time_password** :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username=YOUR_USERNAME,
+ password=YOUR_PASSWORD,
+ int_account=YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+ one_time_password=YOUR_2FA_OTP, # ONLY IF 2FA IS ENABLED
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+A complete example here :
+[connection_otp.py](examples/trading/connection_otp.py)
+
+## 3.6. How to find your : totp_secret_key ?
+
+The parameter **totp_secret_key** is only required if you have enabled `2FA` on Degiro's website.
+
+When you try to activate `2FA` on Degiro's website, it displays a `QRCode`.
+
+This `QRCode` changes at each activation.
+
+A `QRCode` is a picture which can be converted into a text.
+
+You can download this `QRCode` and use a tool to extract the text from it.
+
+This extracted text will look like this :
+
+ otpauth://totp/DEGIRO:YOUR_USERNAME?algorithm=SHA1&issuer=DEGIRO&secret=YOUR_TOPT_SECRET_KEY&digits=6&period=30
+
+Has you can guess the "totp_secret_key" is in this part :
+
+ secret=YOUR_TOPT_SECRET_KEY
+
+Here is an example of script that extracts the text from a `QRCode` :
+[qrcode.py](examples/trading/qrcode.py)
+
+## 3.7. How to find your : one_time_password ?
+
+The parameter **one_time_password** is the password you type when you log in the website using **2FA**.
+
+Usually you get it through an app like **Google Authenticator**.
+
+It is preferable to use the parameter **totp_secret_key** instead of **one_time_password**.
+
+## 3.8. Is there a timeout ?
+A connection for trading operations has a timeout of 30 minutes.
+It's [defined](https://github.com/Chavithra/degiro-connector/blob/main/degiro_connector/core/constants/timeouts.py#L2) in seconds as constant `timeouts.TRADING_TIMEOUT`.
+
+The timeout period is started when the [`TradingAPI.connect()`](#31-how-to-login-) results successfully.
+
+Every time an operation is made to this `TradingAPI` connection, the timeout for this connection will be reset.
+
+If a `TradingAPI` connection is left unused during the timeout period, the connection will expire.
+Every consecutive function call to the `TraderAPI` will then throw a `TimeoutError` exception.
+
+A connection timeout might occur when your trading strategy only performs a few trades per day, e.g. once per hour.
+So when finally a buy opportuntiy occurs, [`check_order()`](#411-check-order):
+```python
+# FETCH CHECKING_RESPONSE
+checking_response = trading_api.check_order(order=order)
+```
+
+Will fail with `TimeoutError`:
+```
+TimeoutError: Connection has probably expired.
+```
+
+## 3.9. How to manage : TimeoutError ?
+
+**HANDLE EXCEPTION**
+
+It's recommended to catch the `TimeoutError` on every function call to the `TradingAPI`.
+
+When it's detected, it's sufficient to call [`connect()`](#31-how-to-login-) again, followed by repeating the original call that threw the exception.
+Example for the [`check_order()`](#411-check-order) call:
+
+```python
+try:
+ checking_response = trading_api.check_order(order=order)
+except TimeoutError:
+ logging.warning("TradingAPI session did timeout, reconnecting for new session ID...")
+ trading_api.connect()
+ checking_response = trading_api.check_order(order=order)
+```
+
+This shows the following in the log, while the order is checked successfully after a successful reconnect:
+```python
+WARNING - TradingAPI session did timeout, reconnecting for new session ID...
+INFO - get_session_id:response_dict: {'isPassCodeEnabled': False, 'locale': 'nl_NL', 'redirectUrl': 'https://trader.degiro.nl/trader/', 'sessionId': '2BADBBEF3****', 'status': 0, 'statusText': 'success'}
+INFO - confirmation_id: "053df7cf-****"
+response_datetime {
+ seconds: 1643801134
+ nanos: 715765000
+}
+```
+
+**REFRESH TIMEOUT**
+
+As mentioned before, the timeout will be reset after each call to the `TradingAPI`. This provides the opportunity to make a periodic function call, for example every 10 minutes to [`get_update()`](#51-how-to-retrieve-pending-orders-).
+
+However, this might interfere with your other logic and might not be robust over time when DeGiro decides to decrease the timeout on their server.
+
+Therefor it's strongly recommended to always incorporate the exception handling for `TimeoutError` as indicated in the example above.
+
+**CHANGE PERIOD**
+
+It's possible to change the timeout period while creating the `TradingAPI`. Just add a `ModelConnection` object for parameter `connection_storage`:
+```python
+# SETUP TRADING API
+trading_api = TradingAPI(
+ credentials=credentials,
+ connection_storage=ModelConnection(
+ timeout=600,
+ )
+)
+
+# Connect:
+trading_api.connect()
+```
+The connection will now expire after 10 minutes (10 * 60 s).
+
+
+# 4. Order
+
+Creating and updating of orders is done with an `Order` object. Here are the parameters:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|id|str|Optional for [`update_order()`](#42-how-to-update-an-order-). It's the `order_id` of the created `Order` as returned by [`confirm_order()`](#412-confirm-order).|
+|action|`Order.Action`|Whether you want to : `BUY` or `SELL`.|
+|order_type|`Order.OrderType`|Type of order : `LIMIT`, `STOP_LIMIT`, `MARKET` or `STOP_LOSS`.|
+|price|float|Limit price of the order. <br /> Optional for the following `order_type` : `LIMIT` and `STOPLIMIT`.|
+|product_id|int|Identifier of the product concerned by the order.|
+|size|float|Size of the order.|
+|stop_price|float|Stop price of the order. <br /> Optional for the following `order_type` : `STOPLIMIT` and `STOPLOSS`|
+|time_type|`Order.TimeType`|Duration of the order : `GOOD_TILL_DAY` or `GOOD_TILL_CANCELED`|
+
+The full description of an `Order` is available here :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+## 4.1. How to create an Order ?
+
+The order creation is done in two steps :
+1. Checking : send the `Order` to the API to check if it is valid.
+2. Confirmation : confirm the creation of the `Order`.
+
+Keeping these two steps (instead of reducing to one single "create" function) provides more options.
+
+## 4.1.1 Check order
+Use the `check_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order|`Order`|The order to create with all necessary [parameters](#4-order).|
+
+### **Response parameters**
+On a succesfull request, a `dict` with the following parameters is returned:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|confirmation_id|str|Id necessary to confirm the creation of the Order by the [`confirm_order()`](#412-confirm-order) function.|
+|response_datetime|[`Timestamp`](https://pythonhosted.org/gax-google-pubsub-v1/google.protobuf.timestamp_pb2.html)|A `Timestamp` represents a point in time independent of any time zone or calendar, represented as seconds (`seconds`) and fractions of seconds at nanosecond resolution (`nanos`) in UTC Epoch time. A `Timestamp` can be converted to a RFC 3339 date string by using `ToJsonString()`.<br> Note: This `Timestamp` is created by Degiro Connector on reception of the API response, not by DeGiro server.|
+|free_space_new|float|New free space (balance) if the Order is confirmed.|
+|transaction_fees|float|Transaction fees that will be applied to the Order.|
+|show_ex_ante_report_link|bool|?|
+
+When the request fails, `None` is returned.
+
+## 4.1.2 Confirm order
+Use the `confirm_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|confirmation_id|str|The confirmtation id from the [`check_order()`](#411-check-order) response.|
+|order|`Order`|The same order from the [`check_order()`](#411-check-order) request.|
+
+### **Response parameters**
+On a succesfull request, a `dict` with the following parameters is returned:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order_id|str|A unique id of the accepted order. This id is required to [update](#42-how-to-update-an-order-) or [delete](#43-how-to-delete-an-order-) the pending order.|
+|response_datetime|[`Timestamp`](https://pythonhosted.org/gax-google-pubsub-v1/google.protobuf.timestamp_pb2.html)|A `Timestamp` represents a point in time independent of any time zone or calendar, represented as seconds (`seconds`) and fractions of seconds at nanosecond resolution (`nanos`) in UTC Epoch time. A `Timestamp` can be converted to a RFC 3339 date string by using `ToJsonString()`.<br> Note: This `Timestamp` is created by Degiro Connector on reception of the API response, not by DeGiro server.|
+
+When the request fails, `None` is returned.
+
+## 4.1.3 Example of combining these functions
+
+```python
+# SETUP ORDER
+order = Order(
+ action=Order.Action.BUY,
+ order_type=Order.OrderType.LIMIT,
+ price=10,
+ product_id=71981,
+ size=1,
+ time_type=Order.TimeType.GOOD_TILL_DAY,
+)
+
+# FETCH CHECKING_RESPONSE
+checking_response = trading_api.check_order(order=order)
+
+# EXTRACT CONFIRMATION_ID
+confirmation_id = checking_response.confirmation_id
+
+# SEND CONFIRMATION
+confirmation_response = trading_api.confirm_order(
+ confirmation_id=confirmation_id,
+ order=order,
+)
+```
+
+For a more comprehensive example :
+[order.py](examples/trading/order.py)
+
+## 4.2. How to update an Order ?
+
+To modify a specific Order, you need to set it up with the `order_id` from the [`confirm_order()`](#412-confirm-order) response and use the `update_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order|`Order`|The order to update with all necessary [parameters](#4-order), including `id` as returned by [`confirm_order()`](#412-confirm-order).|
+
+### **Response parameters**
+On a succesfull request, a `bool` with the value `True` is returned.
+
+When the request fails, `None` is returned. A valid reason is that the pending order has been already executed on the exchange, and this `order_id` no longer exists.
+
+Here is an example:
+
+```python
+# ORDER SETUP
+order = Order(
+ id=YOUR_ORDER_ID, # `order_id` from `confirm_order()` response
+ action=Order.Action.BUY,
+ order_type=Order.OrderType.LIMIT,
+ price=10.60,
+ product_id=71981,
+ size=1,
+ time_type=Order.TimeType.GOOD_TILL_DAY,
+)
+
+# UPDATE ORDER
+succcess = trading_api.update_order(order=order)
+```
+
+## 4.3. How to delete an Order ?
+
+To delete a specific Order you just need the `order_id` from the [`confirm_order()`](#412-confirm-order) response and use the `delete_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order_id|str|The unique id of the accepted order as returned by [`confirm_order()`](#412-confirm-order).|
+
+### **Response parameters**
+On a succesfull request, a `bool` with the value `True` is returned.
+
+When the request fails, `None` is returned. A valid reason is that the pending order has been already executed on the exchange, and this `order_id` no longer exists.
+
+Here is an example:
+
+```python
+# DELETE ORDER
+succcess = trading_api.delete_order(order_id=YOUR_ORDER_ID) # `order_id` from `confirm_order()` response
+```
+
+# 5. Portfolio
+
+## 5.1. How to retrieve pending Orders ?
+
+This is how to get the list of Orders currently created but not yet executed or deleted :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.ORDERS, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+orders_df = pd.DataFrame(update_dict['orders']['values'])
+```
+
+Example : Orders
+
+ product_id time_type price size id ... action order_type stop_price retained_order sent_to_exchange
+ 0 0 GOOD_TILL_DAY 2 3 202cb962-ac59-075b-964b-07152d234b70 ... BUY LIMIT 16 17 18
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+## 5.2. How to get the Portfolio ?
+
+This is how to list the stocks/products currently in the portfolio :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.PORTFOLIO, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+portfolio_df = pd.DataFrame(update_dict['portfolio']['values'])
+```
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+Note: In order to resolve product IDs to Human readable names, see [7.12. How to search products from ids ?](#712-how-to-search-products-from-ids-)
+
+## 5.3. How to get the TotalPortfolio ?
+
+This is how to get aggregated data about the portfolio :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.TOTALPORTFOLIO, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+total_portfolio_df = pd.DataFrame(update_dict['total_portfolio']['values'])
+```
+
+Example : DataFrame
+
+ degiroCash flatexCash totalCash totalDepositWithdrawal todayDepositWithdrawal ... reportNetliq reportOverallMargin reportTotalLongVal reportDeficit marginCallStatus
+ 0 0 1 2 3 4 ... 16 17 18 19 NO_MARGIN_CALL
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+## 5.4. How to retrieve the OrdersHistory ?
+
+This method returns data about passed orders between two dates.
+
+The result contains a list of "Orders" objects with the following attributes :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|created|str|RFC 3339 Datetime, example : "2020-10-06T20:07:18+02:00".|
+|orderId|str|MD5 HASH, example : "098f6bcd-4621-d373-cade-4e832627b4f6"|
+|productId|int|Id of the product example : 65156|
+|size|float|Size of the order, example : 10.0000|
+|price|float|Price of the order, example : 8.6800|
+|buysell|str|"B" or "S"|
+|orderTypeId|int|see 3.Order|
+|orderTimeTypeId|int|see 3.Order|
+|stopPrice|float|Price like : 0.0000|
+|totalTradedSize|int|-|
+|type|str|"CREATE", "DELETE" or "MODIFY"|
+|status|str|"CONFIRMED"|
+|last|str|RFC 3339 Datetime, example : "2020-10-06T20:07:18+02:00".|
+|isActive|bool|-|
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = OrdersHistory.Request.Date(year=2020,month=11,day=15)
+to_date = OrdersHistory.Request.Date(year=2020,month=10,day=15)
+request = OrdersHistory.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+orders_history = trading_api.get_orders_history(request=request)
+```
+
+For a more comprehensive example :
+[orders_history.py](examples/trading/orders_history.py)
+
+## 5.5. How to retrieve the TransactionsHistory ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = TransactionsHistory.Request.Date(year=2020,month=11,day=15)
+to_date = TransactionsHistory.Request.Date(year=2020,month=10,day=15)
+request = TransactionsHistory.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+transactions_history = trading_api.get_transactions_history(request=request)
+```
+
+For a more comprehensive example :
+[transactions_history.py](examples/trading/transactions_history.py)
+
+# 6. Account
+
+## 6.1. How to retrieve the table : Config ?
+
+The config table contains the following informations :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|sessionId|str|Current session id.|
+|clientId|int|Unique Degiro's Account identifier also called "userToken"|
+|tradingUrl|str|-|
+|paUrl|str|-|
+|reportingUrl|str|-|
+|paymentServiceUrl|str|-|
+|productSearchUrl|str|-|
+|dictionaryUrl|str|-|
+|productTypesUrl|str|-|
+|companiesServiceUrl|str|-|
+|i18nUrl|str|-|
+|vwdQuotecastServiceUrl|str|-|
+|vwdNewsUrl|str|-|
+|vwdGossipsUrl|str|-|
+|taskManagerUrl|str|-|
+|refinitivNewsUrl|str|-|
+|refinitivAgendaUrl|str|-|
+|refinitivCompanyProfileUrl|str|-|
+|refinitivCompanyRatiosUrl|str|-|
+|refinitivFinancialStatementsUrl|str|-|
+|refinitivClipsUrl|str|-|
+|landingPath|str|-|
+|betaLandingPath|str|-|
+|mobileLandingPath|str|-|
+|loginUrl|str|-|
+
+Here is how to get this table :
+
+```python
+# FETCH DATA
+config_table = trading_api.get_config()
+
+# EXTRACT SOME DATA
+user_token = config_table['clientId']
+session_id = config_table['sessionId']
+```
+
+For a more comprehensive example :
+[config_table.py](examples/trading/config_table.py)
+
+## 6.2. How to retrieve the table : ClientDetails ?
+
+The ClientDetails table contains information about the current Degiro Account.
+
+|**Parameter**|**Type**|
+|:-|:-|
+|id|int|
+|intAccount|int|
+|loggedInPersonId|int|
+|clientRole|str|
+|effectiveClientRole|str|
+|contractType|str|
+|username|str|
+|displayName|str|
+|email|str|
+|firstContact.firstName|str|
+|firstContact.lastName|str|
+|firstContact.displayName|str|
+|firstContact.nationality|str|
+|firstContact.gender|str|
+|firstContact.dateOfBirth|str|
+|firstContact.placeOfBirth|str|
+|firstContact.countryOfBirth|str|
+|address.streetAddress|str|
+|address.streetAddressNumber|str|
+|address.zip|str|
+|address.city|str|
+|address.country|str|
+|cellphoneNumber|str|
+|locale|str|
+|language|str|
+|culture|str|
+|bankAccount.bankAccountId|int|
+|bankAccount.bic|str|
+|bankAccount.iban|str|
+|bankAccount.status|str|
+|flatexBankAccount.bic|str|
+|flatexBankAccount.iban|str|
+|memberCode|str|
+|isWithdrawalAvailable|bool|
+|isAllocationAvailable|bool|
+|isIskClient|bool|
+|isCollectivePortfolio|bool|
+|isAmClientActive|bool|
+|canUpgrade|bool|
+
+Here is how to get this table :
+
+```python
+# FETCH DATA
+client_details_table = trading_api.get_client_details()
+
+# EXTRACT SOME DATA
+int_account = client_details_table['data']['intAccount']
+user_token = client_details_table['data']['id']
+```
+
+For a more comprehensive example :
+[client_details_table.py](examples/trading/client_details_table.py)
+
+## 6.3. How to retrieve the table : AccountInfo ?
+
+The AccountInfo table contains the following information about currencies.
+
+|**Parameter**|**Type**|
+|:-|:-|
+|clientId|int|
+|baseCurrency|str|
+|currencyPairs|dict|
+|marginType|str|
+|cashFunds|dict|
+|compensationCapping|float|-|
+
+Here is how to get this table :
+
+```python
+account_info_table = trading_api.get_account_info()
+```
+
+For a more comprehensive example :
+[account_info_table.py](examples/trading/account_info_table.py)
+
+## 6.4. How to get the table : AccountOverview ?
+
+It will provide a list of cash movements.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = AccountOverview.Request.Date(year=2020,month=11,day=15)
+to_date = AccountOverview.Request.Date(year=2020,month=10,day=15)
+request = AccountOverview.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+account_overview = trading_api.get_account_overview(request=request)
+```
+
+For a more comprehensive example :
+[account_overview.py](examples/trading/account_overview.py)
+
+Each cash movement contains this kind of parameters :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|date|str|
+|valueDate|str|
+|id|int|
+|orderId|str|
+|description|str|
+|productId|int|
+|currency|str|
+|change|float|
+|balance|dict|
+|unsettledCash|float|
+|total|float|
+
+
+## 6.5. How to export the table : CashAccountReport ?
+
+It will export a list of cash movements in a specific format.
+
+Available formats :
+- CSV
+- HTML
+- PDF
+- XLS
+
+Here is how to get this content in `CSV` format :
+
+```python
+# SETUP REQUEST
+from_date = CashAccountReport.Request.Date(year=2020,month=11,day=15)
+to_date = CashAccountReport.Request.Date(year=2020,month=10,day=15)
+request = CashAccountReport.Request(
+ format=CashAccountReport.Format.CSV,
+ country='FR',
+ lang='fr',
+ from_date=from_date,
+ to_date=to_date,
+)
+
+# FETCH DATA
+cash_account_report = trading_api.get_cash_account_report(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `CashAccountReport.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|format|CashAccountReport.Format|Wanted format : <br>`CSV`<br>`HTML`<br>`PDF`<br>`XLS`|
+|country|str|Country name, like : `FR`|
+|lang|int|Language, like : `fr`|
+|from_date|CashAccountReport.Request.Date|Events starting after this date.|
+|to_date|CashAccountReport.Request.Date|Events before this date.|
+
+Exact definitions of `CashAccountReport` and `CashAccountReport.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[cash_account_report.py](examples/trading/cash_account_report.py)
+
+## 6.6. How to export the table : PositionReport ?
+
+It will export a list of cash movements in a specific format.
+
+Available formats :
+- CSV
+- HTML
+- PDF
+- XLS
+
+Here is how to get this content in `CSV` format :
+
+```python
+# SETUP REQUEST
+to_date = CashAccountReport.Request.Date(year=2020,month=10,day=15)
+request = CashAccountReport.Request(
+ format=CashAccountReport.Format.CSV,
+ country='FR',
+ lang='fr',
+ to_date=to_date,
+)
+
+# FETCH DATA
+position_report = trading_api.get_position_report(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `PositionReport.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|format|PositionReport.Format|Wanted format : <br>`CSV`<br>`HTML`<br>`PDF`<br>`XLS`|
+|country|str|Country name, like : `FR`|
+|lang|int|Language, like : `fr`|
+|to_date|PositionReport.Request.Date|Events before this date.|
+
+Exact definitions of `PositionReport` and `PositionReport.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[position_report.py](examples/trading/position_report.py)
+
+# 7. Products
+
+## 7.1. How to get the table : ProductsConfig ?
+
+This table contains useful parameters to filter products.
+
+Here are the parameters which are inside this table :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|stockCountries|list|
+|bondExchanges|list|
+|bondIssuerTypes|list|
+|eurexCountries|list|
+|futureExchanges|list|
+|optionExchanges|list|
+|combinationExchanges|list|
+|cfdExchanges|list|
+|exchanges|list|
+|indices|list|
+|regions|list|
+|countries|list|
+|productTypes|list|
+|etfFeeTypes|list|
+|investmentFundFeeTypes|list|
+|optionAggregateTypes|list|
+|leveragedAggregateTypes|list|
+|etfAggregateTypes|list|
+|investmentFundAggregateTypes|list|
+|lookupSortColumns|list|
+|stockSortColumns|list|
+|bondSortColumns|list|
+|cfdSortColumns|list|
+|etfSortColumns|list|
+|futureSortColumns|list|
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+products_config = trading_api.get_products_config()
+```
+
+For a more comprehensive example :
+[products_config.py](examples/trading/products_config.py)
+
+## 7.2. How to get my favourite products ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+favourites_list = trading_api.get_favourites_list()
+```
+
+For a more comprehensive example :
+[favourites_list.py](examples/trading/favourites_list.py)
+
+## 7.3. How to lookup products (search by name) ?
+
+Text research on a financial product.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestLookup(
+ search_text='APPLE',
+ limit=10,
+ offset=0,
+ product_type_id=1,
+)
+
+# FETCH DATA
+products_lookup = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_lookup.py](examples/trading/product_lookup.py)
+
+## 7.4. How to search bonds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestBonds(
+ bond_issuer_type_id=0,
+ bond_exchange_id=710,
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+bond_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.5. How to search etfs ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestETFs(
+ popular_only=False,
+ input_aggregate_types='',
+ input_aggregate_values='',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+etf_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.6. How to search funds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestFunds(
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+fund_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.7. How to search futures ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestFutures(
+ future_exchange_id=1,
+ underlying_isin='FR0003500008',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+fund_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.8. How to search leverageds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestLeverageds(
+ popular_only=False,
+ input_aggregate_types='',
+ input_aggregate_values='',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+etf_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.9. How to search options ?
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestOptions(
+ input_aggregate_types='',
+ input_aggregate_values='',
+ option_exchange_id=3,
+ underlying_isin='FR0003500008',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='expirationDate,strike',
+ sort_types='asc,asc',
+)
+
+# FETCH DATA
+option_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.10. How to search stocks ?
+
+It contains information about available stocks.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestStocks(
+ index_id=122001, # NASDAQ 100
+ exchange_id=663, # NASDAQ
+ # You can either use `index_id` or `exchange id`
+ # See which one to use in the `ProductsConfig` table
+ is_in_us_green_list=True,
+ stock_country_id=846, # US
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+stock_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.11. How to search warrants ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestWarrants(
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+warrant_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.12. How to search products from ids ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductsInfo.Request()
+request.products.extend([96008, 1153605, 5462588])
+
+# FETCH DATA
+products_info = trading_api.get_products_info(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[products_info.py](examples/trading/products_info.py)
+
+## 7.13. How to create a favourite list ?
+
+Example :
+
+```python
+favorite_list_id = trading_api.create_favourite_list(name="SOME_NAME")
+```
+
+For a more comprehensive example :
+[favourite_list_create.py](examples/trading/favourite_list_create.py)
+
+## 7.14. How to delete a favourite list ?
+
+Example :
+
+```python
+success = trading_api.delete_favourite_list(id=1234567)
+```
+
+For a more comprehensive example :
+[favourite_list_delete.py](examples/trading/favourite_list_delete.py)
+
+## 7.15. How to put favourite list products ?
+
+Example :
+
+```python
+success = trading_api.put_favourite_list_product(
+ id=1234567,
+ product_id=1234567,
+)
+```
+
+For a more comprehensive example :
+[favourite_list_put_product.py](examples/trading/favourite_list_put_product.py)
+
+## 7.16. How to delete favourite list products ?
+
+Example :
+
+```python
+success = trading_api.delete_favourite_list_product(
+ id=1234567,
+ product_id=1234567,
+)
+```
+
+For a more comprehensive example :
+[favourite_list_delete product.py](examples/trading/favourite_list_delete product.py)
+
+# 8. Companies
+
+## 8.1. How to get : CompanyProfile ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+company_profile = trading_api.get_company_profile(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[company_profile.py](examples/trading/company_profile.py)
+
+## 8.2. How to get : CompanyRatios ?
+
+This table contains information about the company.
+
+Here are the parameters which are inside this table :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|totalFloat|str|
+|sharesOut|str|
+|consRecommendationTrend|dict|
+|forecastData|dict|
+|currentRatios|dict|
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+company_ratios = trading_api.get_company_ratios(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[company_ratios.py](examples/trading/company_ratios.py)
+
+## 8.3. How to get : FinancialStatements ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+financials_statements = trading_api.get_financials_statements(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[financial_statements.py](examples/trading/financial_statements.py)
+
+## 8.4. How to get : LatestNews ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = LatestNews.Request(
+ offset=0,
+ languages='en,fr',
+ limit=20,
+)
+
+# FETCH DATA
+latest_news = trading_api.get_latest_news(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[latest_news.py](examples/trading/latest_news.py)
+
+## 8.5. How to get : TopNewsPreview ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+top_news_preview = trading_api.get_top_news_preview(raw=True)
+```
+
+For a more comprehensive example :
+[top_news_preview.py](examples/trading/top_news_preview.py)
+
+## 8.6. How to get : NewsByCompany ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = NewsByCompany.Request(
+ isin='NL0000235190',
+ limit=10,
+ offset=0,
+ languages='en,fr',
+)
+
+# FETCH DATA
+news_by_company = trading_api.get_news_by_company(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[news_by_company.py](examples/trading/news_by_company.py)
+
+
+## 8.7. How to get : Agenda ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = Agenda.Request()
+request.start_date.FromJsonString('2021-06-21T22:00:00Z')
+request.end_date.FromJsonString('2021-11-28T23:00:00Z')
+request.calendar_type = Agenda.CalendarType.DIVIDEND_CALENDAR
+request.offset = 0
+request.limit = 25
+
+# FETCH DATA
+agenda = trading_api.get_agenda(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `Agenda.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|calendar_type|Agenda.CalendarType|Type of agenda : <br>`DIVIDEND_CALENDAR`<br>`ECONOMIC_CALENDAR`<br>`EARNINGS_CALENDAR`<br>`HOLIDAY_CALENDAR`<br>`IPO_CALENDAR`<br>`SPLIT_CALENDAR`|
+|offset|int|-|
+|limit|int|-|
+|order_by_desc|bool|-|
+|start_date|Timestamp|Events starting after this date.|
+|end_date|Timestamp|Events before this date.|
+|company_name|str|Filter used on the events description.|
+|countries|str|Comma separated list of countries like : `FR,US`|
+|classifications|str|Comma separated list of sectors like : `GovernmentSector,ExternalSector`|
+|units|str|Comma separated list of units like : `Acre,Barrel`|
+
+Exact definitions of `Agenda` and `Agenda.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[agenda.py](examples/trading/agenda.py)
+
+
+## 8.8. How to get : EstimatesSummaries ?
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = Agenda.Request()
+request.start_date.FromJsonString('2021-06-21T22:00:00Z')
+request.end_date.FromJsonString('2021-11-28T23:00:00Z')
+request.calendar_type = Agenda.CalendarType.DIVIDEND_CALENDAR
+request.offset = 0
+request.limit = 25
+
+# FETCH DATA
+product_isin = "FR0000131906"
+estimates_summaries = trading_api.get_estimates_summaries(
+ product_isin=product_isin,
+ raw=False,
+)
+```
+
+Here are the available parameters for `Agenda.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|annual|google.protobuf.Struct|Indicators by year.|
+|currency|str|currency, example `EUR`.|
+|interim|google.protobuf.Struct|Indicators by quarter.|
+|lastRetrieved|str|Last Retrieved, example : `2021-12-31T20:07:30.939Z`.|
+|lastUpdated|str|Last updated,, example : `2021-02-18T01:30:00Z`.|
+|preferredMeasure|str|Preferred measure, example : `EPS`.|
+|ric|str|Reuters Instrument Code, example : `BOUY.PA`.|
+
+Exact definition of `EstimatesSummaries` is in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[estimates_summaries.py](examples/trading/estimates_summaries.py)
+
+# 9. Contributing
+Pull requests are welcome.
+
+Feel free to open an issue or send me a message if you have a question.
+
+# 10. License
+[BSD-3-Clause License](https://raw.githubusercontent.com/Chavithra/degiro-connector/main/LICENSE)
+
+
+%package -n python3-degiro-connector
+Summary: This is yet another library to access Degiro's API.
+Provides: python-degiro-connector
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-degiro-connector
+# 1. **Degiro Connector**
+
+This is yet another library to access Degiro's API.
+
+Notes :
+- Migration scripts are available :
+```bash
+python -m degiro_connector.migration.from_0_1_3_to_1_0_0
+python -m degiro_connector.migration.from_1_0_4_to_1_0_5
+python -m degiro_connector.migration.from_1_0_10_to_2_0_0
+python -m degiro_connector.migration.from_2_0_2_to_2_0_3
+```
+- `GRPC` services are available to let you consume this library through other languages like Javascript, Java, Go, C++, Rust, etc :
+```bash
+python -m examples.quotecast.relay_server
+python -m examples.trading.relay_server
+
+```
+
+## 1.1. Which features ?
+Here are the features you can access through this library :
+
+|**Endpoint**|**Feature(s)**|
+|:-|:-|
+|AccountCashReport|Export cash movements in a specific format : CSV, HTML, PDF or XLS.|
+|AccountInfo|Retrieve a table containing : "clientId" and Currencies.|
+|AccountOverview|Retrieve all the cash movements between two dates.|
+|Agenda|Crucial events regarding products : Dividend, Economic, Earnings, Holiday, IPO or Split.|
+|Bonds<br>ETFs<br>Funds<br>Futures<br>Leverageds<br>Lookup<br>Options<br>Stocks<br>Warrants|Search list of products according their name, type and other criterias. <br> For instance all the stocks from NASDAQ 100.|
+|Chart|Retrieve chart data.|
+|ClientDetails|Retrieve a table containing : "clientId", "intAccount" and other account information.|
+|CompanyProfile|Retrieve a company's profile using its ISIN code.|
+|CompanyRatios|Retrieve a company's ratios using its ISIN code.|
+|Config|Retrieve a table containing : "clientId" and URLs which are constitutive of Degiro's API.|
+|EstimatesSummaries|Retrieve a company's estimates summaries using its ISIN code.|
+|FavouritesList|Add/Delete/Retrieve favourites lists.|
+|FavouritesListProducts|Add/Update favourites lists content.|
+|FinancialStatements|Retrieve a company's financial statements using its ISIN code.|
+|LatestNews|Retrieve latest news about all the companies.|
+|LoginQuotecast|Establish a connection for quotecast operations.|
+|LoginTrading|Establish a connection for trading operations.|
+|LogoutTrading|Destroy previously established connection for trading operations.|
+|NewsByCompany|Retrieve news related to a specific company.|
+|Order|Create, update, delete an Order.|
+|OrderHistory|Retrieve all Orders created between two dates.|
+|Orders|List pending Orders.|
+|Portfolio|List products in your Portfolio.|
+|ProductsConfig|Retrieve a table containing : useful parameters to filter products.|
+|ProductsInfo|Search for products using their ids.|
+|Quotecasts|Fetch real-time data on financial products. <br> For instance the real-time stock Price.|
+|TopNewsPreview|Retrieve some news preview about all the companies.|
+|TotalPorfolio|Retrieve aggregated information about your assets.|
+|TransactionsHistory|Retrieve all Transactions created between two dates.|
+
+## 1.2. How to install ?
+
+```bash
+pip install degiro-connector
+```
+
+## 1.3. How to upgrade ?
+
+```bash
+pip install --no-cache-dir --upgrade degiro-connector
+```
+
+## 1.4. How to uninstall ?
+
+```bash
+pip uninstall degiro-connector
+```
+
+## 1.5. Table of contents
+- [1. **Degiro Connector**](#1-degiro-connector)
+ * [1.1. Which features ?](#11-which-features-)
+ * [1.2. How to install ?](#12-how-to-install-)
+ * [1.3. How to upgrade ?](#13-how-to-upgrade-)
+ * [1.4. How to uninstall ?](#14-how-to-uninstall-)
+ * [1.5. Table of contents](#15-table-of-contents)
+- [2. Real-time data](#2-real-time-data)
+ * [2.1. What are the workflows ?](#21-what-are-the-workflows-)
+ * [2.2. What are the credentials ?](#22-what-are-the-credentials-)
+ * [2.3. How to find your : user_token ?](#23-how-to-find-your--user_token-)
+ * [2.4. How to login ?](#24-how-to-login-)
+ * [2.5. Is there a timeout ?](#25-is-there-a-timeout-)
+ * [2.6. How to subscribe to a data-stream ?](#26-how-to-subscribe-to-a-data-stream-)
+ * [2.7. How to unsubscribe to a data-stream ?](#27-how-to-unsubscribe-to-a-data-stream-)
+ * [2.8. How to fetch the data ?](#28-how-to-fetch-the-data-)
+ * [2.9. How to use this data ?](#29-how-to-use-this-data-)
+ * [2.10. Which are the available data types ?](#210-which-are-the-available-data-types-)
+ * [2.11. What is a Ticker ?](#211-what-is-a-ticker-)
+ * [2.12. What is inside the Dictionary ?](#212-what-is-inside-the-dictionary-)
+ * [2.13. What is inside the DataFrame ?](#213-what-is-inside-the-dataframe-)
+ * [2.14. How to get chart data ?](#214-how-to-get-chart-data-)
+ * [2.15. How to find a : vwd_id ?](#215-how-to-find-a--vwd_id-)
+- [3. Trading connection](#3-trading-connection)
+ * [3.1. How to login ?](#31-how-to-login-)
+ * [3.2. How to logout ?](#32-how-to-logout-)
+ * [3.3. What are the credentials ?](#33-what-are-the-credentials-)
+ * [3.4. How to find your : int_account ?](#34-how-to-find-your--int_account-)
+ * [3.5. How to use 2FA ?](#35-how-to-use-2fa-)
+ * [3.6. How to find your : totp_secret_key ?](#36-how-to-find-your--totp_secret_key-)
+ * [3.7. How to find your : one_time_password ?](#37-how-to-find-your--one_time_password-)
+ * [3.8. Is there a timeout ?](#38-is-there-a-timeout-)
+ * [3.9. How to manage : TimeoutError ?](#39-how-to-manage--TimeoutError-)
+- [4. Order](#4-order)
+ * [4.1. How to create an Order ?](#41-how-to-create-an-order-)
+ * [4.1.1. Check Order](#411-check-order)
+ * [4.1.2. Confirm Order](#412-confirm-order)
+ * [4.2. How to update an Order ?](#42-how-to-update-an-order-)
+ * [4.3. How to delete an Order ?](#43-how-to-delete-an-order-)
+- [5. Portfolio](#5-portfolio)
+ * [5.1. How to retrieve pending Orders ?](#51-how-to-retrieve-pending-orders-)
+ * [5.2. How to get the Portfolio ?](#52-how-to-get-the-portfolio-)
+ * [5.3. How to get the TotalPortfolio ?](#53-how-to-get-the-totalportfolio-)
+ * [5.4. How to retrieve the OrdersHistory ?](#54-how-to-retrieve-the-ordershistory-)
+ * [5.5. How to retrieve the TransactionsHistory ?](#55-how-to-retrieve-the-transactionshistory-)
+- [6. Account](#6-account)
+ * [6.1. How to retrieve the table : Config ?](#61-how-to-retrieve-the-table--config-)
+ * [6.2. How to retrieve the table : ClientDetails ?](#62-how-to-retrieve-the-table--clientdetails-)
+ * [6.3. How to retrieve the table : AccountInfo ?](#63-how-to-retrieve-the-table--accountinfo-)
+ * [6.4. How to get the table : AccountOverview ?](#64-how-to-get-the-table--accountoverview-)
+ * [6.5. How to export the table : CashAccountReport ?](#65-how-to-export-the-table--cashaccountreport-)
+ * [6.6. How to export the table : PositionReport ?](#66-how-to-export-the-table--positionreport-)
+- [7. Products](#7-products)
+ * [7.1. How to get the table : ProductsConfig ?](#71-how-to-get-the-table--productsconfig-)
+ * [7.2. How to get my favourite products ?](#72-how-to-get-my-favourite-products-)
+ * [7.3. How to lookup products (search by name) ?](#73-how-to-lookup-products-search-by-name-)
+ * [7.4. How to search bonds ?](#74-how-to-search-bonds-)
+ * [7.5. How to search etfs ?](#75-how-to-search-etfs-)
+ * [7.6. How to search funds ?](#76-how-to-search-funds-)
+ * [7.7. How to search futures ?](#77-how-to-search-futures-)
+ * [7.8. How to search leverageds ?](#78-how-to-search-leverageds-)
+ * [7.9. How to search options ?](#79-how-to-search-options-)
+ * [7.10. How to search stocks ?](#710-how-to-search-stocks-)
+ * [7.11. How to search warrants ?](#711-how-to-search-warrants-)
+ * [7.12. How to search products from ids ?](#712-how-to-search-products-from-ids-)
+ * [7.13. How to create a favourite list ?](#713-how-to-create-a-favourite-list-)
+ * [7.14. How to delete a favourite list ?](#714-how-to-delete-a-favourite-list-)
+ * [7.15. How to put favourite list products ?](#715-how-to-put-favourite-list-products-)
+ * [7.16. How to delete favourite list products ?](#716-how-to-delete-favourite-list-products-)
+- [8. Companies](#8-companies)
+ * [8.1. How to get : CompanyProfile ?](#81-how-to-get--companyprofile-)
+ * [8.2. How to get : CompanyRatios ?](#82-how-to-get--companyratios-)
+ * [8.3. How to get : FinancialStatements ?](#83-how-to-get--financialstatements-)
+ * [8.4. How to get : LatestNews ?](#84-how-to-get--latestnews-)
+ * [8.5. How to get : TopNewsPreview ?](#85-how-to-get--topnewspreview-)
+ * [8.6. How to get : NewsByCompany ?](#86-how-to-get--newsbycompany-)
+ * [8.7. How to get : Agenda ?](#87-how-to-get--agenda-)
+ * [8.8. How to get : EstimatesSummaries ?](#88-how-to-get--estimatessummaries-)
+- [9. Contributing](#9-contributing)
+- [10. License](#10-license)
+
+# 2. Real-time data
+
+It is possible to fetch a stream of data in real-time from Degiro's API.
+
+For instance if one needs the following data from the "AAPL" stock :
+* LastDate
+* LastTime
+* LastPrice
+* LastVolume
+
+You can use this library to retrieve updates like this :
+
+ LastDate LastTime LastPrice LastVolume
+ 2020-11-13 22:00:00 119.26 4697040
+
+For a list of available metrics, see the example in [section 2.6](#26-how-to-subscribe-to-a-data-stream-).
+
+## 2.1. What are the workflows ?
+
+This is the workflow for consuming real-time data-stream :
+
+ A. Find your "user_token".
+ B. Setup the API object with your "user_token".
+ C. Connect.
+ D. Subscribe to data-stream.
+ E. Fetch data-stream.
+
+This is the worflow for consuming charts :
+
+ A. Find your "user_token".
+ B. Setup the API object with your "user_token".
+ C. Fetch charts.
+
+All the details of these steps are explained in the rest of this section.
+
+## 2.2. What are the credentials ?
+
+The only credential you need in order to fetch real-time data and charts is the :
+* user_token
+
+Beware, these two identifiers are not the same thing :
+* user_token : used to fetch real-time data and charts.
+* int_account : used for some trading operations.
+
+## 2.3. How to find your : user_token ?
+You can find your "user_token" inside one of these tables :
+* "Config" : attribute "clientId"
+* "ClientDetails" : attribute "id"
+
+See sections related to ["Config"](#61-how-to-retrieve-the-table--config-) and ["ClientDetails"](#62-how-to-retrieve-the-table--clientdetails-) tables.
+
+## 2.4. How to login ?
+
+In order to fetch data you need to establish a connection.
+
+You can use the following code to connect :
+
+```python
+# SETUP QUOTECAST API
+quotecast_api = API(user_token=YOUR_USER_TOKEN)
+
+# CONNECTION
+quotecast_api.connect()
+```
+
+## 2.5. Is there a timeout ?
+
+Connection timeout is around 15 seconds.
+
+Which means a connection will cease to work after this timeout.
+
+This timeout is reset each time you use this connection to :
+* Subscribe to a metric (for instance a stock Price)
+* Fetch the data-stream
+
+So if you use it nonstop (in a loop) you won't need to reconnect.
+
+## 2.6. How to subscribe to a data-stream ?
+
+To subscribe to a data-stream you need to setup a Request message.
+
+A Request has the following parameters :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|subscriptions|MessageMap|List of products and metrics to subscribe to.|
+|unsubscriptions|MessageMap|List of products and metrics to unsubscribe to.|
+
+Here is an example of a request :
+```python
+request = Quotecast.Request()
+request.subscriptions['360015751'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+request.subscriptions['AAPL.BATS,E'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+```
+
+In this example these are the `vwd_id` of the products from which you want `Real-time data` :
+- 360015751
+- AAPL.BATS,E
+
+See the [section](#215-how-to-find-a--vwd_id-) related to `vwd_id` for more information.
+
+Once you have built this Request object you can send it to Degiro's API like this :
+```python
+quotecast_api.subscribe(request=request)
+```
+
+For more comprehensive examples :
+[realtime_poller.py](examples/quotecast/realtime_poller.py) /
+[realtime_one_shot.py](examples/quotecast/realtime_one_shot.py)
+
+## 2.7. How to unsubscribe to a data-stream ?
+
+To remove metrics from the data-stream you need to setup a Request message.
+
+If you try to unsubscribe to a metric to which you didn't subscribed previously it will most likely have no impact.
+
+A Request has the following parameters :
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|subscriptions|MessageMap|List of products and metrics to subscribe to.|
+|unsubscriptions|MessageMap|List of products and metrics to unsubscribe to.|
+
+Here is an example of a request :
+```python
+request = Quotecast.Request()
+request.unsubscriptions['360015751'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+request.unsubscriptions['AAPL.BATS,E'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+```
+
+Once you have built this Request object you can send it to Degiro's API like this :
+```python
+quotecast_api.subscribe(request=request)
+```
+
+For more comprehensive examples :
+[realtime_poller.py](examples/quotecast/realtime_poller.py) /
+[realtime_one_shot.py](examples/quotecast/realtime_one_shot.py)
+
+## 2.8. How to fetch the data ?
+
+You can use the following code :
+```python
+quotecast = quotecast_api.fetch_data()
+```
+
+For a more comprehensive example :
+[realtime_poller.py](examples/quotecast/realtime_poller.py)
+
+## 2.9. How to use this data ?
+
+Received data is a `Quotecast` object with the following properties :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|json_data|dict|Dictionary representation of what Degiro's API has sent.|
+|metadata|Metadata|Containing the "response_datetime" and "request_duration".|
+
+Here is how to access these properties :
+```python
+json_data = quotecast.json_data
+response_datetime = quotecast.metadata.response_datetime
+request_duration= quotecast.metadata.request_duration
+```
+Notes:
+* The API sometimes might return an empty Quotecast object.
+* The API often returns a subset of the requested metrics, e.g. only `'LastPrice'`. Please take this into account when appending consecutive data responses.
+
+## 2.10. Which are the available data types ?
+
+This library provides the tools to convert Degiro's JSON data into something more programmer-friendly.
+
+Here is the list of available data types :
+
+|**Type**|**Description**|
+|:-|:-|
+|Ticker|Protobuf message (for GRPC).|
+|Dictionaries|Standard Python Dictionaries : **dict**.|
+|DataFrame|DataFrame from the library Pandas.|
+
+Here is how to build each type :
+
+```python
+# UPDATE PARSER
+quotecast_parser.put_quotecast(quotecast=quotecast)
+
+# BUILD TICKER
+ticker = quotecast_parser.ticker
+
+# BUILD DICT
+ticker_dict = quotecast_parser.ticker_dict
+
+# BUILD PANDAS.DATAFRAME
+ticker_df = quotecast_parser.ticker_df
+```
+
+## 2.11. What is a Ticker ?
+
+The generated Ticker contains :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|metadata|Metadata|Containing the "response_datetime" and "request_duration".|
+|products|MessageMap|Dictionary like object containing the metrics group by "vwd_id".|
+|product_list|RepeatedScalarFieldContainer|List of available "vwd_id".|
+
+Here are some operations available :
+
+```python
+product = '360015751'
+metric_name = 'LastPrice'
+
+# ACCESS SPECIFIC PRODUCT
+product = ticker.products[product]
+
+# ACCESS SPECIFIC METRIC
+metric = product[metric_name]
+
+# LOOP OVER PRODUCTS
+for product in ticker.products:
+ product = ticker.products[product]
+
+# LOOP OVER METRICS
+for metric_name in product.metrics:
+ metric = product.metrics[metric_name]
+```
+
+A Ticker is a custom Protocol Buffer Message built for this library.
+
+It can be transmitted over GRPC framework.
+
+## 2.12. What is inside the Dictionary ?
+
+The dictionary representation of a ticker contains the metrics grouped by "vwd_id" (product id), with :
+* keys : vwd_id
+* values : another dictionary with the metrics concerning this specific product.
+
+Example - Dictionary :
+
+```python
+{
+ '360114899': {
+ 'vwd_id': 360114899,
+ 'response_datetime': '2020-11-08 12:00:27',
+ 'request_duration': 1.0224891666870117,
+ 'LastDate': '2020-11-06',
+ 'LastTime': '17:36:17',
+ 'LastPrice': '70.0',
+ 'LastVolume': '100'
+ },
+ '360015751': {
+ 'vwd_id': 360015751,
+ 'response_datetime': '2020-11-08 12:00:27',
+ 'request_duration': 1.0224891666870117,
+ 'LastDate': '2020-11-06',
+ 'LastTime': '17:36:17',
+ 'LastPrice': '22.99',
+ 'LastVolume': '470'
+ }
+}
+```
+
+## 2.13. What is inside the DataFrame ?
+
+In addition to whatever metrics you have chosen to subscribe to (see the example in [section 2.6](#26-how-to-subscribe-to-a-data-stream-)), the DataFrame will contain the following columns :
+|**Column**|**Description**|
+|:-|:-|
+|vwd_id|Product identifier, for instance "AAPL.BATS,E" for APPLE stock.|
+|response_datetime|Datetime at which the data was received.|
+|request_duration|Duration of the request used to fetch the data.|
+
+Example - DataFrame :
+
+ vwd_id response_datetime request_duration LastDate LastTime LastPrice LastVolume
+ 0 360114899 2020-11-08 12:00:27 1.022489 2020-11-06 17:39:57 70.0 100
+ 1 360015751 2020-11-08 12:00:27 1.022489 2020-11-06 17:36:17 22.99 470
+
+## 2.14. How to get chart data ?
+You can fetch an object containing the same data than in Degiro's website graph.
+
+For that you need to prepare a Chart.Request object.
+
+Here is a table with the available attributes for Chart.Request.
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|requestid|str|It sends you back whatever string you put here, you can set it to : "1".|
+|resolution|Chart.Resolution|Resolution of the chart like : Chart.Resolution.PT1M.|
+|culture|str|Country code like : "en-US" or "fr-FR".|
+|period|Chart.Period|Period of the chart, like : Chart.Period.P1D.|
+|series|repeated string|Data to get like : ['issueid:36014897', 'price:issueid:360148977'].|
+|tz|str|Timezone like : "Europe/Paris"|
+
+Example of code :
+
+```python
+request = Chart.Request()
+request.culture = "fr-FR"
+request.period = Chart.Interval.PT1H
+request.requestid = "1"
+request.resolution = Chart.Interval.P1D
+# request.series.append("issueid:360148977")
+# request.series.append("price:issueid:360148977")
+request.series.append("ohlc:issueid:360148977")
+# request.series.append("volume:issueid:360148977")
+# request.series.append("vwdkey:AAPL.BATS,E")
+# request.series.append("price:vwdkey:AAPL.BATS,E")
+# request.series.append("ohlc:vwdkey:AAPL.BATS,E")
+# request.series.append("volume:vwdkey:AAPL.BATS,E")
+request.tz = "Europe/Paris"
+
+# FETCH DATA
+chart = quotecast_api.get_chart(
+ request=request,
+ override={
+ "resolution": "P1D",
+ "period": "P1W",
+ },
+ raw=True,
+)
+```
+
+The `issueid` parameter is the `vwd_id` of the product from which you want the `Chart` data.
+
+See the section related to `vwd_id` for more information.
+
+All the options for the enumerations are available in this file :
+[quotecast.proto](protos/degiro_connector/quotecast/models/quotecast.proto)
+
+For a more comprehensive examples :
+ - [chart.py](examples/quotecast/chart.py)
+ - [chart_format.py](examples/quotecast/chart_format.py)
+
+## 2.15. How to find a : vwd_id ?
+
+In operations related to `Quotecast`, Degiro uses the `vwd_id` to identify a product.
+
+Which means that if you want a `Chart` or `Real-time data` for a specific product : you first need to find this product's `vwd_id`.
+
+This two identifiers are not the same :
+
+|**Identifier**|**API name(s)**|**Description**|
+|:-|:-|:-|
+|id|str|Id used identify a product in `Trading` related endpoints.|
+|vwd_id|issueid <br /> vwdId <br /> vwdIdSecondary <br />|Id used identify a product in `Quotecast` (`Chart` and `Real-time data`) related endpoint.|
+
+Here are some methods you can use to fetch a product's `vwd_id` :
+- `product_search`
+- `get_products_info`
+
+The method `product_search` let you use the name or other attributes of a product to fetch it's `vwd_id`.
+
+The method `get_products_info` let you use a product's `id` to fetch it's `vwd_id`.
+
+
+# 3. Trading connection
+
+This library is divided into two modules :
+- quotecast : to consume real-time financial data.
+- trading : to manage your Degiro's account.
+
+The module **quotecast** is described in the section related to real-time data.
+
+The rest of this document will only refer to the module : **trading**.
+
+## 3.1. How to login ?
+In order to use the module **trading.api** you need to establish a connection.
+
+Check the section related to **int_account** to understand how to get yours.
+
+Here is how to connect :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username = YOUR_USERNAME,
+ password = YOUR_PASSWORD,
+ int_account = YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+For a more comprehensive example :
+[connection.py](examples/trading/connection.py)
+
+## 3.2. How to logout ?
+
+Once you no longer need to use the API you can destroy your connection.
+
+You can use the following code to disconnect :
+
+```python
+# DESTROY CONNECTION
+trading_api.logout()
+```
+
+For a more comprehensive example :
+[logout.py](examples/trading/logout.py)
+
+## 3.3. What are the credentials ?
+
+Some credentials are required to use Degiro's trading API.
+
+Here are these credentials :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|username|str|Username used to log into Degiro's website.|
+|password|str|Password used to log into Degiro's website.|
+|int_account|int|OPTIONAL : unique identifier of the account : used by Degiro's server.|
+|totp_secret_key|str|OPTIONAL : used for Two-factor Authentication (2FA).|
+|one_time_password|str|OPTIONAL : used for Two-factor Authentication (2FA).|
+
+Check the section related to **int_account** to understand how to get yours.
+
+Check the section related to **2FA** if you want to know more about these two parameters :
+- **totp_secret_key**
+- **one_time_password**
+
+## 3.4. How to find your : int_account ?
+
+To get your **int_acccount** you can run this example :
+[client_details_table.py](examples/trading/client_details_table.py)
+
+See section related to **ClientDetails** table for more details.
+
+This **int_acccount** is required to do most of the trading operations available in this connector.
+
+Here are some operations for which your **int_acccount** is not required :
+- Connection
+- Fetch table : ClientDetails
+- Fetch table : Config
+
+Beware, these two identifiers are not the same thing :
+- user_token : used to fetch real-time data and charts.
+- int_account : used for some trading operations.
+
+## 3.5. How to use 2FA ?
+
+First I will briefly explain what is : **Two-Factor Authentication (2FA)**.
+
+I recommend to skip a few paragraphs if you already know what is **2FA**.
+
+In a standard connection you are providing two parameters:
+- username
+- password
+
+If you use **Two-Factor Authentication (2FA)** you need an extra parameter:
+- one_time_password
+
+This **one_time_password** has a validity of 30 secondes and is generated using a **totp_secret_key** code.
+
+Usually you use an app like **‎Google Authenticator** to store this **totp_secret_key** and generate the **one_time_password**.
+
+The **totp_secret_key** is stored inside the QRCode which is displayed when you enable 2FA on Degiro's website
+
+To use **2FA** with this library you have two solutions.
+
+**SOLUTION 1**
+
+Provide your **totp_secret_key** : the library will use it to generate a new **one_time_password** at each connection.
+
+So you won't have to type your **one_time_password** manually at each connection.
+
+This is the proper way.
+
+See the section about **totp_secret_key** to understand how to get yours.
+
+Here is an example of connection with the **totp_secret_key** :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username=YOUR_USERNAME,
+ password=YOUR_PASSWORD,
+ int_account=YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+ totp_secret_key=YOUR_2FA_SECRET_KEY, # ONLY IF 2FA IS ENABLED
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+A complete example here :
+[connection_2fa.py](examples/trading/connection_2fa.py)
+
+**SOLUTION 2**
+
+Provide a new **one_time_password** at each connection.
+
+Here is an example of connection with the **one_time_password** :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username=YOUR_USERNAME,
+ password=YOUR_PASSWORD,
+ int_account=YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+ one_time_password=YOUR_2FA_OTP, # ONLY IF 2FA IS ENABLED
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+A complete example here :
+[connection_otp.py](examples/trading/connection_otp.py)
+
+## 3.6. How to find your : totp_secret_key ?
+
+The parameter **totp_secret_key** is only required if you have enabled `2FA` on Degiro's website.
+
+When you try to activate `2FA` on Degiro's website, it displays a `QRCode`.
+
+This `QRCode` changes at each activation.
+
+A `QRCode` is a picture which can be converted into a text.
+
+You can download this `QRCode` and use a tool to extract the text from it.
+
+This extracted text will look like this :
+
+ otpauth://totp/DEGIRO:YOUR_USERNAME?algorithm=SHA1&issuer=DEGIRO&secret=YOUR_TOPT_SECRET_KEY&digits=6&period=30
+
+Has you can guess the "totp_secret_key" is in this part :
+
+ secret=YOUR_TOPT_SECRET_KEY
+
+Here is an example of script that extracts the text from a `QRCode` :
+[qrcode.py](examples/trading/qrcode.py)
+
+## 3.7. How to find your : one_time_password ?
+
+The parameter **one_time_password** is the password you type when you log in the website using **2FA**.
+
+Usually you get it through an app like **Google Authenticator**.
+
+It is preferable to use the parameter **totp_secret_key** instead of **one_time_password**.
+
+## 3.8. Is there a timeout ?
+A connection for trading operations has a timeout of 30 minutes.
+It's [defined](https://github.com/Chavithra/degiro-connector/blob/main/degiro_connector/core/constants/timeouts.py#L2) in seconds as constant `timeouts.TRADING_TIMEOUT`.
+
+The timeout period is started when the [`TradingAPI.connect()`](#31-how-to-login-) results successfully.
+
+Every time an operation is made to this `TradingAPI` connection, the timeout for this connection will be reset.
+
+If a `TradingAPI` connection is left unused during the timeout period, the connection will expire.
+Every consecutive function call to the `TraderAPI` will then throw a `TimeoutError` exception.
+
+A connection timeout might occur when your trading strategy only performs a few trades per day, e.g. once per hour.
+So when finally a buy opportuntiy occurs, [`check_order()`](#411-check-order):
+```python
+# FETCH CHECKING_RESPONSE
+checking_response = trading_api.check_order(order=order)
+```
+
+Will fail with `TimeoutError`:
+```
+TimeoutError: Connection has probably expired.
+```
+
+## 3.9. How to manage : TimeoutError ?
+
+**HANDLE EXCEPTION**
+
+It's recommended to catch the `TimeoutError` on every function call to the `TradingAPI`.
+
+When it's detected, it's sufficient to call [`connect()`](#31-how-to-login-) again, followed by repeating the original call that threw the exception.
+Example for the [`check_order()`](#411-check-order) call:
+
+```python
+try:
+ checking_response = trading_api.check_order(order=order)
+except TimeoutError:
+ logging.warning("TradingAPI session did timeout, reconnecting for new session ID...")
+ trading_api.connect()
+ checking_response = trading_api.check_order(order=order)
+```
+
+This shows the following in the log, while the order is checked successfully after a successful reconnect:
+```python
+WARNING - TradingAPI session did timeout, reconnecting for new session ID...
+INFO - get_session_id:response_dict: {'isPassCodeEnabled': False, 'locale': 'nl_NL', 'redirectUrl': 'https://trader.degiro.nl/trader/', 'sessionId': '2BADBBEF3****', 'status': 0, 'statusText': 'success'}
+INFO - confirmation_id: "053df7cf-****"
+response_datetime {
+ seconds: 1643801134
+ nanos: 715765000
+}
+```
+
+**REFRESH TIMEOUT**
+
+As mentioned before, the timeout will be reset after each call to the `TradingAPI`. This provides the opportunity to make a periodic function call, for example every 10 minutes to [`get_update()`](#51-how-to-retrieve-pending-orders-).
+
+However, this might interfere with your other logic and might not be robust over time when DeGiro decides to decrease the timeout on their server.
+
+Therefor it's strongly recommended to always incorporate the exception handling for `TimeoutError` as indicated in the example above.
+
+**CHANGE PERIOD**
+
+It's possible to change the timeout period while creating the `TradingAPI`. Just add a `ModelConnection` object for parameter `connection_storage`:
+```python
+# SETUP TRADING API
+trading_api = TradingAPI(
+ credentials=credentials,
+ connection_storage=ModelConnection(
+ timeout=600,
+ )
+)
+
+# Connect:
+trading_api.connect()
+```
+The connection will now expire after 10 minutes (10 * 60 s).
+
+
+# 4. Order
+
+Creating and updating of orders is done with an `Order` object. Here are the parameters:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|id|str|Optional for [`update_order()`](#42-how-to-update-an-order-). It's the `order_id` of the created `Order` as returned by [`confirm_order()`](#412-confirm-order).|
+|action|`Order.Action`|Whether you want to : `BUY` or `SELL`.|
+|order_type|`Order.OrderType`|Type of order : `LIMIT`, `STOP_LIMIT`, `MARKET` or `STOP_LOSS`.|
+|price|float|Limit price of the order. <br /> Optional for the following `order_type` : `LIMIT` and `STOPLIMIT`.|
+|product_id|int|Identifier of the product concerned by the order.|
+|size|float|Size of the order.|
+|stop_price|float|Stop price of the order. <br /> Optional for the following `order_type` : `STOPLIMIT` and `STOPLOSS`|
+|time_type|`Order.TimeType`|Duration of the order : `GOOD_TILL_DAY` or `GOOD_TILL_CANCELED`|
+
+The full description of an `Order` is available here :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+## 4.1. How to create an Order ?
+
+The order creation is done in two steps :
+1. Checking : send the `Order` to the API to check if it is valid.
+2. Confirmation : confirm the creation of the `Order`.
+
+Keeping these two steps (instead of reducing to one single "create" function) provides more options.
+
+## 4.1.1 Check order
+Use the `check_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order|`Order`|The order to create with all necessary [parameters](#4-order).|
+
+### **Response parameters**
+On a succesfull request, a `dict` with the following parameters is returned:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|confirmation_id|str|Id necessary to confirm the creation of the Order by the [`confirm_order()`](#412-confirm-order) function.|
+|response_datetime|[`Timestamp`](https://pythonhosted.org/gax-google-pubsub-v1/google.protobuf.timestamp_pb2.html)|A `Timestamp` represents a point in time independent of any time zone or calendar, represented as seconds (`seconds`) and fractions of seconds at nanosecond resolution (`nanos`) in UTC Epoch time. A `Timestamp` can be converted to a RFC 3339 date string by using `ToJsonString()`.<br> Note: This `Timestamp` is created by Degiro Connector on reception of the API response, not by DeGiro server.|
+|free_space_new|float|New free space (balance) if the Order is confirmed.|
+|transaction_fees|float|Transaction fees that will be applied to the Order.|
+|show_ex_ante_report_link|bool|?|
+
+When the request fails, `None` is returned.
+
+## 4.1.2 Confirm order
+Use the `confirm_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|confirmation_id|str|The confirmtation id from the [`check_order()`](#411-check-order) response.|
+|order|`Order`|The same order from the [`check_order()`](#411-check-order) request.|
+
+### **Response parameters**
+On a succesfull request, a `dict` with the following parameters is returned:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order_id|str|A unique id of the accepted order. This id is required to [update](#42-how-to-update-an-order-) or [delete](#43-how-to-delete-an-order-) the pending order.|
+|response_datetime|[`Timestamp`](https://pythonhosted.org/gax-google-pubsub-v1/google.protobuf.timestamp_pb2.html)|A `Timestamp` represents a point in time independent of any time zone or calendar, represented as seconds (`seconds`) and fractions of seconds at nanosecond resolution (`nanos`) in UTC Epoch time. A `Timestamp` can be converted to a RFC 3339 date string by using `ToJsonString()`.<br> Note: This `Timestamp` is created by Degiro Connector on reception of the API response, not by DeGiro server.|
+
+When the request fails, `None` is returned.
+
+## 4.1.3 Example of combining these functions
+
+```python
+# SETUP ORDER
+order = Order(
+ action=Order.Action.BUY,
+ order_type=Order.OrderType.LIMIT,
+ price=10,
+ product_id=71981,
+ size=1,
+ time_type=Order.TimeType.GOOD_TILL_DAY,
+)
+
+# FETCH CHECKING_RESPONSE
+checking_response = trading_api.check_order(order=order)
+
+# EXTRACT CONFIRMATION_ID
+confirmation_id = checking_response.confirmation_id
+
+# SEND CONFIRMATION
+confirmation_response = trading_api.confirm_order(
+ confirmation_id=confirmation_id,
+ order=order,
+)
+```
+
+For a more comprehensive example :
+[order.py](examples/trading/order.py)
+
+## 4.2. How to update an Order ?
+
+To modify a specific Order, you need to set it up with the `order_id` from the [`confirm_order()`](#412-confirm-order) response and use the `update_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order|`Order`|The order to update with all necessary [parameters](#4-order), including `id` as returned by [`confirm_order()`](#412-confirm-order).|
+
+### **Response parameters**
+On a succesfull request, a `bool` with the value `True` is returned.
+
+When the request fails, `None` is returned. A valid reason is that the pending order has been already executed on the exchange, and this `order_id` no longer exists.
+
+Here is an example:
+
+```python
+# ORDER SETUP
+order = Order(
+ id=YOUR_ORDER_ID, # `order_id` from `confirm_order()` response
+ action=Order.Action.BUY,
+ order_type=Order.OrderType.LIMIT,
+ price=10.60,
+ product_id=71981,
+ size=1,
+ time_type=Order.TimeType.GOOD_TILL_DAY,
+)
+
+# UPDATE ORDER
+succcess = trading_api.update_order(order=order)
+```
+
+## 4.3. How to delete an Order ?
+
+To delete a specific Order you just need the `order_id` from the [`confirm_order()`](#412-confirm-order) response and use the `delete_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order_id|str|The unique id of the accepted order as returned by [`confirm_order()`](#412-confirm-order).|
+
+### **Response parameters**
+On a succesfull request, a `bool` with the value `True` is returned.
+
+When the request fails, `None` is returned. A valid reason is that the pending order has been already executed on the exchange, and this `order_id` no longer exists.
+
+Here is an example:
+
+```python
+# DELETE ORDER
+succcess = trading_api.delete_order(order_id=YOUR_ORDER_ID) # `order_id` from `confirm_order()` response
+```
+
+# 5. Portfolio
+
+## 5.1. How to retrieve pending Orders ?
+
+This is how to get the list of Orders currently created but not yet executed or deleted :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.ORDERS, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+orders_df = pd.DataFrame(update_dict['orders']['values'])
+```
+
+Example : Orders
+
+ product_id time_type price size id ... action order_type stop_price retained_order sent_to_exchange
+ 0 0 GOOD_TILL_DAY 2 3 202cb962-ac59-075b-964b-07152d234b70 ... BUY LIMIT 16 17 18
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+## 5.2. How to get the Portfolio ?
+
+This is how to list the stocks/products currently in the portfolio :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.PORTFOLIO, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+portfolio_df = pd.DataFrame(update_dict['portfolio']['values'])
+```
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+Note: In order to resolve product IDs to Human readable names, see [7.12. How to search products from ids ?](#712-how-to-search-products-from-ids-)
+
+## 5.3. How to get the TotalPortfolio ?
+
+This is how to get aggregated data about the portfolio :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.TOTALPORTFOLIO, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+total_portfolio_df = pd.DataFrame(update_dict['total_portfolio']['values'])
+```
+
+Example : DataFrame
+
+ degiroCash flatexCash totalCash totalDepositWithdrawal todayDepositWithdrawal ... reportNetliq reportOverallMargin reportTotalLongVal reportDeficit marginCallStatus
+ 0 0 1 2 3 4 ... 16 17 18 19 NO_MARGIN_CALL
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+## 5.4. How to retrieve the OrdersHistory ?
+
+This method returns data about passed orders between two dates.
+
+The result contains a list of "Orders" objects with the following attributes :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|created|str|RFC 3339 Datetime, example : "2020-10-06T20:07:18+02:00".|
+|orderId|str|MD5 HASH, example : "098f6bcd-4621-d373-cade-4e832627b4f6"|
+|productId|int|Id of the product example : 65156|
+|size|float|Size of the order, example : 10.0000|
+|price|float|Price of the order, example : 8.6800|
+|buysell|str|"B" or "S"|
+|orderTypeId|int|see 3.Order|
+|orderTimeTypeId|int|see 3.Order|
+|stopPrice|float|Price like : 0.0000|
+|totalTradedSize|int|-|
+|type|str|"CREATE", "DELETE" or "MODIFY"|
+|status|str|"CONFIRMED"|
+|last|str|RFC 3339 Datetime, example : "2020-10-06T20:07:18+02:00".|
+|isActive|bool|-|
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = OrdersHistory.Request.Date(year=2020,month=11,day=15)
+to_date = OrdersHistory.Request.Date(year=2020,month=10,day=15)
+request = OrdersHistory.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+orders_history = trading_api.get_orders_history(request=request)
+```
+
+For a more comprehensive example :
+[orders_history.py](examples/trading/orders_history.py)
+
+## 5.5. How to retrieve the TransactionsHistory ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = TransactionsHistory.Request.Date(year=2020,month=11,day=15)
+to_date = TransactionsHistory.Request.Date(year=2020,month=10,day=15)
+request = TransactionsHistory.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+transactions_history = trading_api.get_transactions_history(request=request)
+```
+
+For a more comprehensive example :
+[transactions_history.py](examples/trading/transactions_history.py)
+
+# 6. Account
+
+## 6.1. How to retrieve the table : Config ?
+
+The config table contains the following informations :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|sessionId|str|Current session id.|
+|clientId|int|Unique Degiro's Account identifier also called "userToken"|
+|tradingUrl|str|-|
+|paUrl|str|-|
+|reportingUrl|str|-|
+|paymentServiceUrl|str|-|
+|productSearchUrl|str|-|
+|dictionaryUrl|str|-|
+|productTypesUrl|str|-|
+|companiesServiceUrl|str|-|
+|i18nUrl|str|-|
+|vwdQuotecastServiceUrl|str|-|
+|vwdNewsUrl|str|-|
+|vwdGossipsUrl|str|-|
+|taskManagerUrl|str|-|
+|refinitivNewsUrl|str|-|
+|refinitivAgendaUrl|str|-|
+|refinitivCompanyProfileUrl|str|-|
+|refinitivCompanyRatiosUrl|str|-|
+|refinitivFinancialStatementsUrl|str|-|
+|refinitivClipsUrl|str|-|
+|landingPath|str|-|
+|betaLandingPath|str|-|
+|mobileLandingPath|str|-|
+|loginUrl|str|-|
+
+Here is how to get this table :
+
+```python
+# FETCH DATA
+config_table = trading_api.get_config()
+
+# EXTRACT SOME DATA
+user_token = config_table['clientId']
+session_id = config_table['sessionId']
+```
+
+For a more comprehensive example :
+[config_table.py](examples/trading/config_table.py)
+
+## 6.2. How to retrieve the table : ClientDetails ?
+
+The ClientDetails table contains information about the current Degiro Account.
+
+|**Parameter**|**Type**|
+|:-|:-|
+|id|int|
+|intAccount|int|
+|loggedInPersonId|int|
+|clientRole|str|
+|effectiveClientRole|str|
+|contractType|str|
+|username|str|
+|displayName|str|
+|email|str|
+|firstContact.firstName|str|
+|firstContact.lastName|str|
+|firstContact.displayName|str|
+|firstContact.nationality|str|
+|firstContact.gender|str|
+|firstContact.dateOfBirth|str|
+|firstContact.placeOfBirth|str|
+|firstContact.countryOfBirth|str|
+|address.streetAddress|str|
+|address.streetAddressNumber|str|
+|address.zip|str|
+|address.city|str|
+|address.country|str|
+|cellphoneNumber|str|
+|locale|str|
+|language|str|
+|culture|str|
+|bankAccount.bankAccountId|int|
+|bankAccount.bic|str|
+|bankAccount.iban|str|
+|bankAccount.status|str|
+|flatexBankAccount.bic|str|
+|flatexBankAccount.iban|str|
+|memberCode|str|
+|isWithdrawalAvailable|bool|
+|isAllocationAvailable|bool|
+|isIskClient|bool|
+|isCollectivePortfolio|bool|
+|isAmClientActive|bool|
+|canUpgrade|bool|
+
+Here is how to get this table :
+
+```python
+# FETCH DATA
+client_details_table = trading_api.get_client_details()
+
+# EXTRACT SOME DATA
+int_account = client_details_table['data']['intAccount']
+user_token = client_details_table['data']['id']
+```
+
+For a more comprehensive example :
+[client_details_table.py](examples/trading/client_details_table.py)
+
+## 6.3. How to retrieve the table : AccountInfo ?
+
+The AccountInfo table contains the following information about currencies.
+
+|**Parameter**|**Type**|
+|:-|:-|
+|clientId|int|
+|baseCurrency|str|
+|currencyPairs|dict|
+|marginType|str|
+|cashFunds|dict|
+|compensationCapping|float|-|
+
+Here is how to get this table :
+
+```python
+account_info_table = trading_api.get_account_info()
+```
+
+For a more comprehensive example :
+[account_info_table.py](examples/trading/account_info_table.py)
+
+## 6.4. How to get the table : AccountOverview ?
+
+It will provide a list of cash movements.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = AccountOverview.Request.Date(year=2020,month=11,day=15)
+to_date = AccountOverview.Request.Date(year=2020,month=10,day=15)
+request = AccountOverview.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+account_overview = trading_api.get_account_overview(request=request)
+```
+
+For a more comprehensive example :
+[account_overview.py](examples/trading/account_overview.py)
+
+Each cash movement contains this kind of parameters :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|date|str|
+|valueDate|str|
+|id|int|
+|orderId|str|
+|description|str|
+|productId|int|
+|currency|str|
+|change|float|
+|balance|dict|
+|unsettledCash|float|
+|total|float|
+
+
+## 6.5. How to export the table : CashAccountReport ?
+
+It will export a list of cash movements in a specific format.
+
+Available formats :
+- CSV
+- HTML
+- PDF
+- XLS
+
+Here is how to get this content in `CSV` format :
+
+```python
+# SETUP REQUEST
+from_date = CashAccountReport.Request.Date(year=2020,month=11,day=15)
+to_date = CashAccountReport.Request.Date(year=2020,month=10,day=15)
+request = CashAccountReport.Request(
+ format=CashAccountReport.Format.CSV,
+ country='FR',
+ lang='fr',
+ from_date=from_date,
+ to_date=to_date,
+)
+
+# FETCH DATA
+cash_account_report = trading_api.get_cash_account_report(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `CashAccountReport.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|format|CashAccountReport.Format|Wanted format : <br>`CSV`<br>`HTML`<br>`PDF`<br>`XLS`|
+|country|str|Country name, like : `FR`|
+|lang|int|Language, like : `fr`|
+|from_date|CashAccountReport.Request.Date|Events starting after this date.|
+|to_date|CashAccountReport.Request.Date|Events before this date.|
+
+Exact definitions of `CashAccountReport` and `CashAccountReport.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[cash_account_report.py](examples/trading/cash_account_report.py)
+
+## 6.6. How to export the table : PositionReport ?
+
+It will export a list of cash movements in a specific format.
+
+Available formats :
+- CSV
+- HTML
+- PDF
+- XLS
+
+Here is how to get this content in `CSV` format :
+
+```python
+# SETUP REQUEST
+to_date = CashAccountReport.Request.Date(year=2020,month=10,day=15)
+request = CashAccountReport.Request(
+ format=CashAccountReport.Format.CSV,
+ country='FR',
+ lang='fr',
+ to_date=to_date,
+)
+
+# FETCH DATA
+position_report = trading_api.get_position_report(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `PositionReport.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|format|PositionReport.Format|Wanted format : <br>`CSV`<br>`HTML`<br>`PDF`<br>`XLS`|
+|country|str|Country name, like : `FR`|
+|lang|int|Language, like : `fr`|
+|to_date|PositionReport.Request.Date|Events before this date.|
+
+Exact definitions of `PositionReport` and `PositionReport.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[position_report.py](examples/trading/position_report.py)
+
+# 7. Products
+
+## 7.1. How to get the table : ProductsConfig ?
+
+This table contains useful parameters to filter products.
+
+Here are the parameters which are inside this table :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|stockCountries|list|
+|bondExchanges|list|
+|bondIssuerTypes|list|
+|eurexCountries|list|
+|futureExchanges|list|
+|optionExchanges|list|
+|combinationExchanges|list|
+|cfdExchanges|list|
+|exchanges|list|
+|indices|list|
+|regions|list|
+|countries|list|
+|productTypes|list|
+|etfFeeTypes|list|
+|investmentFundFeeTypes|list|
+|optionAggregateTypes|list|
+|leveragedAggregateTypes|list|
+|etfAggregateTypes|list|
+|investmentFundAggregateTypes|list|
+|lookupSortColumns|list|
+|stockSortColumns|list|
+|bondSortColumns|list|
+|cfdSortColumns|list|
+|etfSortColumns|list|
+|futureSortColumns|list|
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+products_config = trading_api.get_products_config()
+```
+
+For a more comprehensive example :
+[products_config.py](examples/trading/products_config.py)
+
+## 7.2. How to get my favourite products ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+favourites_list = trading_api.get_favourites_list()
+```
+
+For a more comprehensive example :
+[favourites_list.py](examples/trading/favourites_list.py)
+
+## 7.3. How to lookup products (search by name) ?
+
+Text research on a financial product.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestLookup(
+ search_text='APPLE',
+ limit=10,
+ offset=0,
+ product_type_id=1,
+)
+
+# FETCH DATA
+products_lookup = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_lookup.py](examples/trading/product_lookup.py)
+
+## 7.4. How to search bonds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestBonds(
+ bond_issuer_type_id=0,
+ bond_exchange_id=710,
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+bond_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.5. How to search etfs ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestETFs(
+ popular_only=False,
+ input_aggregate_types='',
+ input_aggregate_values='',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+etf_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.6. How to search funds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestFunds(
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+fund_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.7. How to search futures ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestFutures(
+ future_exchange_id=1,
+ underlying_isin='FR0003500008',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+fund_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.8. How to search leverageds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestLeverageds(
+ popular_only=False,
+ input_aggregate_types='',
+ input_aggregate_values='',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+etf_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.9. How to search options ?
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestOptions(
+ input_aggregate_types='',
+ input_aggregate_values='',
+ option_exchange_id=3,
+ underlying_isin='FR0003500008',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='expirationDate,strike',
+ sort_types='asc,asc',
+)
+
+# FETCH DATA
+option_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.10. How to search stocks ?
+
+It contains information about available stocks.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestStocks(
+ index_id=122001, # NASDAQ 100
+ exchange_id=663, # NASDAQ
+ # You can either use `index_id` or `exchange id`
+ # See which one to use in the `ProductsConfig` table
+ is_in_us_green_list=True,
+ stock_country_id=846, # US
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+stock_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.11. How to search warrants ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestWarrants(
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+warrant_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.12. How to search products from ids ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductsInfo.Request()
+request.products.extend([96008, 1153605, 5462588])
+
+# FETCH DATA
+products_info = trading_api.get_products_info(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[products_info.py](examples/trading/products_info.py)
+
+## 7.13. How to create a favourite list ?
+
+Example :
+
+```python
+favorite_list_id = trading_api.create_favourite_list(name="SOME_NAME")
+```
+
+For a more comprehensive example :
+[favourite_list_create.py](examples/trading/favourite_list_create.py)
+
+## 7.14. How to delete a favourite list ?
+
+Example :
+
+```python
+success = trading_api.delete_favourite_list(id=1234567)
+```
+
+For a more comprehensive example :
+[favourite_list_delete.py](examples/trading/favourite_list_delete.py)
+
+## 7.15. How to put favourite list products ?
+
+Example :
+
+```python
+success = trading_api.put_favourite_list_product(
+ id=1234567,
+ product_id=1234567,
+)
+```
+
+For a more comprehensive example :
+[favourite_list_put_product.py](examples/trading/favourite_list_put_product.py)
+
+## 7.16. How to delete favourite list products ?
+
+Example :
+
+```python
+success = trading_api.delete_favourite_list_product(
+ id=1234567,
+ product_id=1234567,
+)
+```
+
+For a more comprehensive example :
+[favourite_list_delete product.py](examples/trading/favourite_list_delete product.py)
+
+# 8. Companies
+
+## 8.1. How to get : CompanyProfile ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+company_profile = trading_api.get_company_profile(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[company_profile.py](examples/trading/company_profile.py)
+
+## 8.2. How to get : CompanyRatios ?
+
+This table contains information about the company.
+
+Here are the parameters which are inside this table :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|totalFloat|str|
+|sharesOut|str|
+|consRecommendationTrend|dict|
+|forecastData|dict|
+|currentRatios|dict|
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+company_ratios = trading_api.get_company_ratios(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[company_ratios.py](examples/trading/company_ratios.py)
+
+## 8.3. How to get : FinancialStatements ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+financials_statements = trading_api.get_financials_statements(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[financial_statements.py](examples/trading/financial_statements.py)
+
+## 8.4. How to get : LatestNews ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = LatestNews.Request(
+ offset=0,
+ languages='en,fr',
+ limit=20,
+)
+
+# FETCH DATA
+latest_news = trading_api.get_latest_news(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[latest_news.py](examples/trading/latest_news.py)
+
+## 8.5. How to get : TopNewsPreview ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+top_news_preview = trading_api.get_top_news_preview(raw=True)
+```
+
+For a more comprehensive example :
+[top_news_preview.py](examples/trading/top_news_preview.py)
+
+## 8.6. How to get : NewsByCompany ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = NewsByCompany.Request(
+ isin='NL0000235190',
+ limit=10,
+ offset=0,
+ languages='en,fr',
+)
+
+# FETCH DATA
+news_by_company = trading_api.get_news_by_company(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[news_by_company.py](examples/trading/news_by_company.py)
+
+
+## 8.7. How to get : Agenda ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = Agenda.Request()
+request.start_date.FromJsonString('2021-06-21T22:00:00Z')
+request.end_date.FromJsonString('2021-11-28T23:00:00Z')
+request.calendar_type = Agenda.CalendarType.DIVIDEND_CALENDAR
+request.offset = 0
+request.limit = 25
+
+# FETCH DATA
+agenda = trading_api.get_agenda(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `Agenda.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|calendar_type|Agenda.CalendarType|Type of agenda : <br>`DIVIDEND_CALENDAR`<br>`ECONOMIC_CALENDAR`<br>`EARNINGS_CALENDAR`<br>`HOLIDAY_CALENDAR`<br>`IPO_CALENDAR`<br>`SPLIT_CALENDAR`|
+|offset|int|-|
+|limit|int|-|
+|order_by_desc|bool|-|
+|start_date|Timestamp|Events starting after this date.|
+|end_date|Timestamp|Events before this date.|
+|company_name|str|Filter used on the events description.|
+|countries|str|Comma separated list of countries like : `FR,US`|
+|classifications|str|Comma separated list of sectors like : `GovernmentSector,ExternalSector`|
+|units|str|Comma separated list of units like : `Acre,Barrel`|
+
+Exact definitions of `Agenda` and `Agenda.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[agenda.py](examples/trading/agenda.py)
+
+
+## 8.8. How to get : EstimatesSummaries ?
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = Agenda.Request()
+request.start_date.FromJsonString('2021-06-21T22:00:00Z')
+request.end_date.FromJsonString('2021-11-28T23:00:00Z')
+request.calendar_type = Agenda.CalendarType.DIVIDEND_CALENDAR
+request.offset = 0
+request.limit = 25
+
+# FETCH DATA
+product_isin = "FR0000131906"
+estimates_summaries = trading_api.get_estimates_summaries(
+ product_isin=product_isin,
+ raw=False,
+)
+```
+
+Here are the available parameters for `Agenda.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|annual|google.protobuf.Struct|Indicators by year.|
+|currency|str|currency, example `EUR`.|
+|interim|google.protobuf.Struct|Indicators by quarter.|
+|lastRetrieved|str|Last Retrieved, example : `2021-12-31T20:07:30.939Z`.|
+|lastUpdated|str|Last updated,, example : `2021-02-18T01:30:00Z`.|
+|preferredMeasure|str|Preferred measure, example : `EPS`.|
+|ric|str|Reuters Instrument Code, example : `BOUY.PA`.|
+
+Exact definition of `EstimatesSummaries` is in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[estimates_summaries.py](examples/trading/estimates_summaries.py)
+
+# 9. Contributing
+Pull requests are welcome.
+
+Feel free to open an issue or send me a message if you have a question.
+
+# 10. License
+[BSD-3-Clause License](https://raw.githubusercontent.com/Chavithra/degiro-connector/main/LICENSE)
+
+
+%package help
+Summary: Development documents and examples for degiro-connector
+Provides: python3-degiro-connector-doc
+%description help
+# 1. **Degiro Connector**
+
+This is yet another library to access Degiro's API.
+
+Notes :
+- Migration scripts are available :
+```bash
+python -m degiro_connector.migration.from_0_1_3_to_1_0_0
+python -m degiro_connector.migration.from_1_0_4_to_1_0_5
+python -m degiro_connector.migration.from_1_0_10_to_2_0_0
+python -m degiro_connector.migration.from_2_0_2_to_2_0_3
+```
+- `GRPC` services are available to let you consume this library through other languages like Javascript, Java, Go, C++, Rust, etc :
+```bash
+python -m examples.quotecast.relay_server
+python -m examples.trading.relay_server
+
+```
+
+## 1.1. Which features ?
+Here are the features you can access through this library :
+
+|**Endpoint**|**Feature(s)**|
+|:-|:-|
+|AccountCashReport|Export cash movements in a specific format : CSV, HTML, PDF or XLS.|
+|AccountInfo|Retrieve a table containing : "clientId" and Currencies.|
+|AccountOverview|Retrieve all the cash movements between two dates.|
+|Agenda|Crucial events regarding products : Dividend, Economic, Earnings, Holiday, IPO or Split.|
+|Bonds<br>ETFs<br>Funds<br>Futures<br>Leverageds<br>Lookup<br>Options<br>Stocks<br>Warrants|Search list of products according their name, type and other criterias. <br> For instance all the stocks from NASDAQ 100.|
+|Chart|Retrieve chart data.|
+|ClientDetails|Retrieve a table containing : "clientId", "intAccount" and other account information.|
+|CompanyProfile|Retrieve a company's profile using its ISIN code.|
+|CompanyRatios|Retrieve a company's ratios using its ISIN code.|
+|Config|Retrieve a table containing : "clientId" and URLs which are constitutive of Degiro's API.|
+|EstimatesSummaries|Retrieve a company's estimates summaries using its ISIN code.|
+|FavouritesList|Add/Delete/Retrieve favourites lists.|
+|FavouritesListProducts|Add/Update favourites lists content.|
+|FinancialStatements|Retrieve a company's financial statements using its ISIN code.|
+|LatestNews|Retrieve latest news about all the companies.|
+|LoginQuotecast|Establish a connection for quotecast operations.|
+|LoginTrading|Establish a connection for trading operations.|
+|LogoutTrading|Destroy previously established connection for trading operations.|
+|NewsByCompany|Retrieve news related to a specific company.|
+|Order|Create, update, delete an Order.|
+|OrderHistory|Retrieve all Orders created between two dates.|
+|Orders|List pending Orders.|
+|Portfolio|List products in your Portfolio.|
+|ProductsConfig|Retrieve a table containing : useful parameters to filter products.|
+|ProductsInfo|Search for products using their ids.|
+|Quotecasts|Fetch real-time data on financial products. <br> For instance the real-time stock Price.|
+|TopNewsPreview|Retrieve some news preview about all the companies.|
+|TotalPorfolio|Retrieve aggregated information about your assets.|
+|TransactionsHistory|Retrieve all Transactions created between two dates.|
+
+## 1.2. How to install ?
+
+```bash
+pip install degiro-connector
+```
+
+## 1.3. How to upgrade ?
+
+```bash
+pip install --no-cache-dir --upgrade degiro-connector
+```
+
+## 1.4. How to uninstall ?
+
+```bash
+pip uninstall degiro-connector
+```
+
+## 1.5. Table of contents
+- [1. **Degiro Connector**](#1-degiro-connector)
+ * [1.1. Which features ?](#11-which-features-)
+ * [1.2. How to install ?](#12-how-to-install-)
+ * [1.3. How to upgrade ?](#13-how-to-upgrade-)
+ * [1.4. How to uninstall ?](#14-how-to-uninstall-)
+ * [1.5. Table of contents](#15-table-of-contents)
+- [2. Real-time data](#2-real-time-data)
+ * [2.1. What are the workflows ?](#21-what-are-the-workflows-)
+ * [2.2. What are the credentials ?](#22-what-are-the-credentials-)
+ * [2.3. How to find your : user_token ?](#23-how-to-find-your--user_token-)
+ * [2.4. How to login ?](#24-how-to-login-)
+ * [2.5. Is there a timeout ?](#25-is-there-a-timeout-)
+ * [2.6. How to subscribe to a data-stream ?](#26-how-to-subscribe-to-a-data-stream-)
+ * [2.7. How to unsubscribe to a data-stream ?](#27-how-to-unsubscribe-to-a-data-stream-)
+ * [2.8. How to fetch the data ?](#28-how-to-fetch-the-data-)
+ * [2.9. How to use this data ?](#29-how-to-use-this-data-)
+ * [2.10. Which are the available data types ?](#210-which-are-the-available-data-types-)
+ * [2.11. What is a Ticker ?](#211-what-is-a-ticker-)
+ * [2.12. What is inside the Dictionary ?](#212-what-is-inside-the-dictionary-)
+ * [2.13. What is inside the DataFrame ?](#213-what-is-inside-the-dataframe-)
+ * [2.14. How to get chart data ?](#214-how-to-get-chart-data-)
+ * [2.15. How to find a : vwd_id ?](#215-how-to-find-a--vwd_id-)
+- [3. Trading connection](#3-trading-connection)
+ * [3.1. How to login ?](#31-how-to-login-)
+ * [3.2. How to logout ?](#32-how-to-logout-)
+ * [3.3. What are the credentials ?](#33-what-are-the-credentials-)
+ * [3.4. How to find your : int_account ?](#34-how-to-find-your--int_account-)
+ * [3.5. How to use 2FA ?](#35-how-to-use-2fa-)
+ * [3.6. How to find your : totp_secret_key ?](#36-how-to-find-your--totp_secret_key-)
+ * [3.7. How to find your : one_time_password ?](#37-how-to-find-your--one_time_password-)
+ * [3.8. Is there a timeout ?](#38-is-there-a-timeout-)
+ * [3.9. How to manage : TimeoutError ?](#39-how-to-manage--TimeoutError-)
+- [4. Order](#4-order)
+ * [4.1. How to create an Order ?](#41-how-to-create-an-order-)
+ * [4.1.1. Check Order](#411-check-order)
+ * [4.1.2. Confirm Order](#412-confirm-order)
+ * [4.2. How to update an Order ?](#42-how-to-update-an-order-)
+ * [4.3. How to delete an Order ?](#43-how-to-delete-an-order-)
+- [5. Portfolio](#5-portfolio)
+ * [5.1. How to retrieve pending Orders ?](#51-how-to-retrieve-pending-orders-)
+ * [5.2. How to get the Portfolio ?](#52-how-to-get-the-portfolio-)
+ * [5.3. How to get the TotalPortfolio ?](#53-how-to-get-the-totalportfolio-)
+ * [5.4. How to retrieve the OrdersHistory ?](#54-how-to-retrieve-the-ordershistory-)
+ * [5.5. How to retrieve the TransactionsHistory ?](#55-how-to-retrieve-the-transactionshistory-)
+- [6. Account](#6-account)
+ * [6.1. How to retrieve the table : Config ?](#61-how-to-retrieve-the-table--config-)
+ * [6.2. How to retrieve the table : ClientDetails ?](#62-how-to-retrieve-the-table--clientdetails-)
+ * [6.3. How to retrieve the table : AccountInfo ?](#63-how-to-retrieve-the-table--accountinfo-)
+ * [6.4. How to get the table : AccountOverview ?](#64-how-to-get-the-table--accountoverview-)
+ * [6.5. How to export the table : CashAccountReport ?](#65-how-to-export-the-table--cashaccountreport-)
+ * [6.6. How to export the table : PositionReport ?](#66-how-to-export-the-table--positionreport-)
+- [7. Products](#7-products)
+ * [7.1. How to get the table : ProductsConfig ?](#71-how-to-get-the-table--productsconfig-)
+ * [7.2. How to get my favourite products ?](#72-how-to-get-my-favourite-products-)
+ * [7.3. How to lookup products (search by name) ?](#73-how-to-lookup-products-search-by-name-)
+ * [7.4. How to search bonds ?](#74-how-to-search-bonds-)
+ * [7.5. How to search etfs ?](#75-how-to-search-etfs-)
+ * [7.6. How to search funds ?](#76-how-to-search-funds-)
+ * [7.7. How to search futures ?](#77-how-to-search-futures-)
+ * [7.8. How to search leverageds ?](#78-how-to-search-leverageds-)
+ * [7.9. How to search options ?](#79-how-to-search-options-)
+ * [7.10. How to search stocks ?](#710-how-to-search-stocks-)
+ * [7.11. How to search warrants ?](#711-how-to-search-warrants-)
+ * [7.12. How to search products from ids ?](#712-how-to-search-products-from-ids-)
+ * [7.13. How to create a favourite list ?](#713-how-to-create-a-favourite-list-)
+ * [7.14. How to delete a favourite list ?](#714-how-to-delete-a-favourite-list-)
+ * [7.15. How to put favourite list products ?](#715-how-to-put-favourite-list-products-)
+ * [7.16. How to delete favourite list products ?](#716-how-to-delete-favourite-list-products-)
+- [8. Companies](#8-companies)
+ * [8.1. How to get : CompanyProfile ?](#81-how-to-get--companyprofile-)
+ * [8.2. How to get : CompanyRatios ?](#82-how-to-get--companyratios-)
+ * [8.3. How to get : FinancialStatements ?](#83-how-to-get--financialstatements-)
+ * [8.4. How to get : LatestNews ?](#84-how-to-get--latestnews-)
+ * [8.5. How to get : TopNewsPreview ?](#85-how-to-get--topnewspreview-)
+ * [8.6. How to get : NewsByCompany ?](#86-how-to-get--newsbycompany-)
+ * [8.7. How to get : Agenda ?](#87-how-to-get--agenda-)
+ * [8.8. How to get : EstimatesSummaries ?](#88-how-to-get--estimatessummaries-)
+- [9. Contributing](#9-contributing)
+- [10. License](#10-license)
+
+# 2. Real-time data
+
+It is possible to fetch a stream of data in real-time from Degiro's API.
+
+For instance if one needs the following data from the "AAPL" stock :
+* LastDate
+* LastTime
+* LastPrice
+* LastVolume
+
+You can use this library to retrieve updates like this :
+
+ LastDate LastTime LastPrice LastVolume
+ 2020-11-13 22:00:00 119.26 4697040
+
+For a list of available metrics, see the example in [section 2.6](#26-how-to-subscribe-to-a-data-stream-).
+
+## 2.1. What are the workflows ?
+
+This is the workflow for consuming real-time data-stream :
+
+ A. Find your "user_token".
+ B. Setup the API object with your "user_token".
+ C. Connect.
+ D. Subscribe to data-stream.
+ E. Fetch data-stream.
+
+This is the worflow for consuming charts :
+
+ A. Find your "user_token".
+ B. Setup the API object with your "user_token".
+ C. Fetch charts.
+
+All the details of these steps are explained in the rest of this section.
+
+## 2.2. What are the credentials ?
+
+The only credential you need in order to fetch real-time data and charts is the :
+* user_token
+
+Beware, these two identifiers are not the same thing :
+* user_token : used to fetch real-time data and charts.
+* int_account : used for some trading operations.
+
+## 2.3. How to find your : user_token ?
+You can find your "user_token" inside one of these tables :
+* "Config" : attribute "clientId"
+* "ClientDetails" : attribute "id"
+
+See sections related to ["Config"](#61-how-to-retrieve-the-table--config-) and ["ClientDetails"](#62-how-to-retrieve-the-table--clientdetails-) tables.
+
+## 2.4. How to login ?
+
+In order to fetch data you need to establish a connection.
+
+You can use the following code to connect :
+
+```python
+# SETUP QUOTECAST API
+quotecast_api = API(user_token=YOUR_USER_TOKEN)
+
+# CONNECTION
+quotecast_api.connect()
+```
+
+## 2.5. Is there a timeout ?
+
+Connection timeout is around 15 seconds.
+
+Which means a connection will cease to work after this timeout.
+
+This timeout is reset each time you use this connection to :
+* Subscribe to a metric (for instance a stock Price)
+* Fetch the data-stream
+
+So if you use it nonstop (in a loop) you won't need to reconnect.
+
+## 2.6. How to subscribe to a data-stream ?
+
+To subscribe to a data-stream you need to setup a Request message.
+
+A Request has the following parameters :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|subscriptions|MessageMap|List of products and metrics to subscribe to.|
+|unsubscriptions|MessageMap|List of products and metrics to unsubscribe to.|
+
+Here is an example of a request :
+```python
+request = Quotecast.Request()
+request.subscriptions['360015751'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+request.subscriptions['AAPL.BATS,E'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+```
+
+In this example these are the `vwd_id` of the products from which you want `Real-time data` :
+- 360015751
+- AAPL.BATS,E
+
+See the [section](#215-how-to-find-a--vwd_id-) related to `vwd_id` for more information.
+
+Once you have built this Request object you can send it to Degiro's API like this :
+```python
+quotecast_api.subscribe(request=request)
+```
+
+For more comprehensive examples :
+[realtime_poller.py](examples/quotecast/realtime_poller.py) /
+[realtime_one_shot.py](examples/quotecast/realtime_one_shot.py)
+
+## 2.7. How to unsubscribe to a data-stream ?
+
+To remove metrics from the data-stream you need to setup a Request message.
+
+If you try to unsubscribe to a metric to which you didn't subscribed previously it will most likely have no impact.
+
+A Request has the following parameters :
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|subscriptions|MessageMap|List of products and metrics to subscribe to.|
+|unsubscriptions|MessageMap|List of products and metrics to unsubscribe to.|
+
+Here is an example of a request :
+```python
+request = Quotecast.Request()
+request.unsubscriptions['360015751'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+request.unsubscriptions['AAPL.BATS,E'].extend([
+ 'LastDate',
+ 'LastTime',
+ 'LastPrice',
+ 'LastVolume',
+ 'AskPrice',
+ 'AskVolume',
+ 'LowPrice',
+ 'HighPrice',
+ 'BidPrice',
+ 'BidVolume'
+])
+```
+
+Once you have built this Request object you can send it to Degiro's API like this :
+```python
+quotecast_api.subscribe(request=request)
+```
+
+For more comprehensive examples :
+[realtime_poller.py](examples/quotecast/realtime_poller.py) /
+[realtime_one_shot.py](examples/quotecast/realtime_one_shot.py)
+
+## 2.8. How to fetch the data ?
+
+You can use the following code :
+```python
+quotecast = quotecast_api.fetch_data()
+```
+
+For a more comprehensive example :
+[realtime_poller.py](examples/quotecast/realtime_poller.py)
+
+## 2.9. How to use this data ?
+
+Received data is a `Quotecast` object with the following properties :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|json_data|dict|Dictionary representation of what Degiro's API has sent.|
+|metadata|Metadata|Containing the "response_datetime" and "request_duration".|
+
+Here is how to access these properties :
+```python
+json_data = quotecast.json_data
+response_datetime = quotecast.metadata.response_datetime
+request_duration= quotecast.metadata.request_duration
+```
+Notes:
+* The API sometimes might return an empty Quotecast object.
+* The API often returns a subset of the requested metrics, e.g. only `'LastPrice'`. Please take this into account when appending consecutive data responses.
+
+## 2.10. Which are the available data types ?
+
+This library provides the tools to convert Degiro's JSON data into something more programmer-friendly.
+
+Here is the list of available data types :
+
+|**Type**|**Description**|
+|:-|:-|
+|Ticker|Protobuf message (for GRPC).|
+|Dictionaries|Standard Python Dictionaries : **dict**.|
+|DataFrame|DataFrame from the library Pandas.|
+
+Here is how to build each type :
+
+```python
+# UPDATE PARSER
+quotecast_parser.put_quotecast(quotecast=quotecast)
+
+# BUILD TICKER
+ticker = quotecast_parser.ticker
+
+# BUILD DICT
+ticker_dict = quotecast_parser.ticker_dict
+
+# BUILD PANDAS.DATAFRAME
+ticker_df = quotecast_parser.ticker_df
+```
+
+## 2.11. What is a Ticker ?
+
+The generated Ticker contains :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|metadata|Metadata|Containing the "response_datetime" and "request_duration".|
+|products|MessageMap|Dictionary like object containing the metrics group by "vwd_id".|
+|product_list|RepeatedScalarFieldContainer|List of available "vwd_id".|
+
+Here are some operations available :
+
+```python
+product = '360015751'
+metric_name = 'LastPrice'
+
+# ACCESS SPECIFIC PRODUCT
+product = ticker.products[product]
+
+# ACCESS SPECIFIC METRIC
+metric = product[metric_name]
+
+# LOOP OVER PRODUCTS
+for product in ticker.products:
+ product = ticker.products[product]
+
+# LOOP OVER METRICS
+for metric_name in product.metrics:
+ metric = product.metrics[metric_name]
+```
+
+A Ticker is a custom Protocol Buffer Message built for this library.
+
+It can be transmitted over GRPC framework.
+
+## 2.12. What is inside the Dictionary ?
+
+The dictionary representation of a ticker contains the metrics grouped by "vwd_id" (product id), with :
+* keys : vwd_id
+* values : another dictionary with the metrics concerning this specific product.
+
+Example - Dictionary :
+
+```python
+{
+ '360114899': {
+ 'vwd_id': 360114899,
+ 'response_datetime': '2020-11-08 12:00:27',
+ 'request_duration': 1.0224891666870117,
+ 'LastDate': '2020-11-06',
+ 'LastTime': '17:36:17',
+ 'LastPrice': '70.0',
+ 'LastVolume': '100'
+ },
+ '360015751': {
+ 'vwd_id': 360015751,
+ 'response_datetime': '2020-11-08 12:00:27',
+ 'request_duration': 1.0224891666870117,
+ 'LastDate': '2020-11-06',
+ 'LastTime': '17:36:17',
+ 'LastPrice': '22.99',
+ 'LastVolume': '470'
+ }
+}
+```
+
+## 2.13. What is inside the DataFrame ?
+
+In addition to whatever metrics you have chosen to subscribe to (see the example in [section 2.6](#26-how-to-subscribe-to-a-data-stream-)), the DataFrame will contain the following columns :
+|**Column**|**Description**|
+|:-|:-|
+|vwd_id|Product identifier, for instance "AAPL.BATS,E" for APPLE stock.|
+|response_datetime|Datetime at which the data was received.|
+|request_duration|Duration of the request used to fetch the data.|
+
+Example - DataFrame :
+
+ vwd_id response_datetime request_duration LastDate LastTime LastPrice LastVolume
+ 0 360114899 2020-11-08 12:00:27 1.022489 2020-11-06 17:39:57 70.0 100
+ 1 360015751 2020-11-08 12:00:27 1.022489 2020-11-06 17:36:17 22.99 470
+
+## 2.14. How to get chart data ?
+You can fetch an object containing the same data than in Degiro's website graph.
+
+For that you need to prepare a Chart.Request object.
+
+Here is a table with the available attributes for Chart.Request.
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|requestid|str|It sends you back whatever string you put here, you can set it to : "1".|
+|resolution|Chart.Resolution|Resolution of the chart like : Chart.Resolution.PT1M.|
+|culture|str|Country code like : "en-US" or "fr-FR".|
+|period|Chart.Period|Period of the chart, like : Chart.Period.P1D.|
+|series|repeated string|Data to get like : ['issueid:36014897', 'price:issueid:360148977'].|
+|tz|str|Timezone like : "Europe/Paris"|
+
+Example of code :
+
+```python
+request = Chart.Request()
+request.culture = "fr-FR"
+request.period = Chart.Interval.PT1H
+request.requestid = "1"
+request.resolution = Chart.Interval.P1D
+# request.series.append("issueid:360148977")
+# request.series.append("price:issueid:360148977")
+request.series.append("ohlc:issueid:360148977")
+# request.series.append("volume:issueid:360148977")
+# request.series.append("vwdkey:AAPL.BATS,E")
+# request.series.append("price:vwdkey:AAPL.BATS,E")
+# request.series.append("ohlc:vwdkey:AAPL.BATS,E")
+# request.series.append("volume:vwdkey:AAPL.BATS,E")
+request.tz = "Europe/Paris"
+
+# FETCH DATA
+chart = quotecast_api.get_chart(
+ request=request,
+ override={
+ "resolution": "P1D",
+ "period": "P1W",
+ },
+ raw=True,
+)
+```
+
+The `issueid` parameter is the `vwd_id` of the product from which you want the `Chart` data.
+
+See the section related to `vwd_id` for more information.
+
+All the options for the enumerations are available in this file :
+[quotecast.proto](protos/degiro_connector/quotecast/models/quotecast.proto)
+
+For a more comprehensive examples :
+ - [chart.py](examples/quotecast/chart.py)
+ - [chart_format.py](examples/quotecast/chart_format.py)
+
+## 2.15. How to find a : vwd_id ?
+
+In operations related to `Quotecast`, Degiro uses the `vwd_id` to identify a product.
+
+Which means that if you want a `Chart` or `Real-time data` for a specific product : you first need to find this product's `vwd_id`.
+
+This two identifiers are not the same :
+
+|**Identifier**|**API name(s)**|**Description**|
+|:-|:-|:-|
+|id|str|Id used identify a product in `Trading` related endpoints.|
+|vwd_id|issueid <br /> vwdId <br /> vwdIdSecondary <br />|Id used identify a product in `Quotecast` (`Chart` and `Real-time data`) related endpoint.|
+
+Here are some methods you can use to fetch a product's `vwd_id` :
+- `product_search`
+- `get_products_info`
+
+The method `product_search` let you use the name or other attributes of a product to fetch it's `vwd_id`.
+
+The method `get_products_info` let you use a product's `id` to fetch it's `vwd_id`.
+
+
+# 3. Trading connection
+
+This library is divided into two modules :
+- quotecast : to consume real-time financial data.
+- trading : to manage your Degiro's account.
+
+The module **quotecast** is described in the section related to real-time data.
+
+The rest of this document will only refer to the module : **trading**.
+
+## 3.1. How to login ?
+In order to use the module **trading.api** you need to establish a connection.
+
+Check the section related to **int_account** to understand how to get yours.
+
+Here is how to connect :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username = YOUR_USERNAME,
+ password = YOUR_PASSWORD,
+ int_account = YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+For a more comprehensive example :
+[connection.py](examples/trading/connection.py)
+
+## 3.2. How to logout ?
+
+Once you no longer need to use the API you can destroy your connection.
+
+You can use the following code to disconnect :
+
+```python
+# DESTROY CONNECTION
+trading_api.logout()
+```
+
+For a more comprehensive example :
+[logout.py](examples/trading/logout.py)
+
+## 3.3. What are the credentials ?
+
+Some credentials are required to use Degiro's trading API.
+
+Here are these credentials :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|username|str|Username used to log into Degiro's website.|
+|password|str|Password used to log into Degiro's website.|
+|int_account|int|OPTIONAL : unique identifier of the account : used by Degiro's server.|
+|totp_secret_key|str|OPTIONAL : used for Two-factor Authentication (2FA).|
+|one_time_password|str|OPTIONAL : used for Two-factor Authentication (2FA).|
+
+Check the section related to **int_account** to understand how to get yours.
+
+Check the section related to **2FA** if you want to know more about these two parameters :
+- **totp_secret_key**
+- **one_time_password**
+
+## 3.4. How to find your : int_account ?
+
+To get your **int_acccount** you can run this example :
+[client_details_table.py](examples/trading/client_details_table.py)
+
+See section related to **ClientDetails** table for more details.
+
+This **int_acccount** is required to do most of the trading operations available in this connector.
+
+Here are some operations for which your **int_acccount** is not required :
+- Connection
+- Fetch table : ClientDetails
+- Fetch table : Config
+
+Beware, these two identifiers are not the same thing :
+- user_token : used to fetch real-time data and charts.
+- int_account : used for some trading operations.
+
+## 3.5. How to use 2FA ?
+
+First I will briefly explain what is : **Two-Factor Authentication (2FA)**.
+
+I recommend to skip a few paragraphs if you already know what is **2FA**.
+
+In a standard connection you are providing two parameters:
+- username
+- password
+
+If you use **Two-Factor Authentication (2FA)** you need an extra parameter:
+- one_time_password
+
+This **one_time_password** has a validity of 30 secondes and is generated using a **totp_secret_key** code.
+
+Usually you use an app like **‎Google Authenticator** to store this **totp_secret_key** and generate the **one_time_password**.
+
+The **totp_secret_key** is stored inside the QRCode which is displayed when you enable 2FA on Degiro's website
+
+To use **2FA** with this library you have two solutions.
+
+**SOLUTION 1**
+
+Provide your **totp_secret_key** : the library will use it to generate a new **one_time_password** at each connection.
+
+So you won't have to type your **one_time_password** manually at each connection.
+
+This is the proper way.
+
+See the section about **totp_secret_key** to understand how to get yours.
+
+Here is an example of connection with the **totp_secret_key** :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username=YOUR_USERNAME,
+ password=YOUR_PASSWORD,
+ int_account=YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+ totp_secret_key=YOUR_2FA_SECRET_KEY, # ONLY IF 2FA IS ENABLED
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+A complete example here :
+[connection_2fa.py](examples/trading/connection_2fa.py)
+
+**SOLUTION 2**
+
+Provide a new **one_time_password** at each connection.
+
+Here is an example of connection with the **one_time_password** :
+```python
+# SETUP CREDENTIALS
+credentials = Credentials(
+ username=YOUR_USERNAME,
+ password=YOUR_PASSWORD,
+ int_account=YOUR_INT_ACCOUNT, # OPTIONAL FOR LOGIN
+ one_time_password=YOUR_2FA_OTP, # ONLY IF 2FA IS ENABLED
+)
+
+# SETUP TRADING API
+trading_api = API(credentials=credentials)
+
+# ESTABLISH CONNECTION
+trading_api.connect()
+```
+
+A complete example here :
+[connection_otp.py](examples/trading/connection_otp.py)
+
+## 3.6. How to find your : totp_secret_key ?
+
+The parameter **totp_secret_key** is only required if you have enabled `2FA` on Degiro's website.
+
+When you try to activate `2FA` on Degiro's website, it displays a `QRCode`.
+
+This `QRCode` changes at each activation.
+
+A `QRCode` is a picture which can be converted into a text.
+
+You can download this `QRCode` and use a tool to extract the text from it.
+
+This extracted text will look like this :
+
+ otpauth://totp/DEGIRO:YOUR_USERNAME?algorithm=SHA1&issuer=DEGIRO&secret=YOUR_TOPT_SECRET_KEY&digits=6&period=30
+
+Has you can guess the "totp_secret_key" is in this part :
+
+ secret=YOUR_TOPT_SECRET_KEY
+
+Here is an example of script that extracts the text from a `QRCode` :
+[qrcode.py](examples/trading/qrcode.py)
+
+## 3.7. How to find your : one_time_password ?
+
+The parameter **one_time_password** is the password you type when you log in the website using **2FA**.
+
+Usually you get it through an app like **Google Authenticator**.
+
+It is preferable to use the parameter **totp_secret_key** instead of **one_time_password**.
+
+## 3.8. Is there a timeout ?
+A connection for trading operations has a timeout of 30 minutes.
+It's [defined](https://github.com/Chavithra/degiro-connector/blob/main/degiro_connector/core/constants/timeouts.py#L2) in seconds as constant `timeouts.TRADING_TIMEOUT`.
+
+The timeout period is started when the [`TradingAPI.connect()`](#31-how-to-login-) results successfully.
+
+Every time an operation is made to this `TradingAPI` connection, the timeout for this connection will be reset.
+
+If a `TradingAPI` connection is left unused during the timeout period, the connection will expire.
+Every consecutive function call to the `TraderAPI` will then throw a `TimeoutError` exception.
+
+A connection timeout might occur when your trading strategy only performs a few trades per day, e.g. once per hour.
+So when finally a buy opportuntiy occurs, [`check_order()`](#411-check-order):
+```python
+# FETCH CHECKING_RESPONSE
+checking_response = trading_api.check_order(order=order)
+```
+
+Will fail with `TimeoutError`:
+```
+TimeoutError: Connection has probably expired.
+```
+
+## 3.9. How to manage : TimeoutError ?
+
+**HANDLE EXCEPTION**
+
+It's recommended to catch the `TimeoutError` on every function call to the `TradingAPI`.
+
+When it's detected, it's sufficient to call [`connect()`](#31-how-to-login-) again, followed by repeating the original call that threw the exception.
+Example for the [`check_order()`](#411-check-order) call:
+
+```python
+try:
+ checking_response = trading_api.check_order(order=order)
+except TimeoutError:
+ logging.warning("TradingAPI session did timeout, reconnecting for new session ID...")
+ trading_api.connect()
+ checking_response = trading_api.check_order(order=order)
+```
+
+This shows the following in the log, while the order is checked successfully after a successful reconnect:
+```python
+WARNING - TradingAPI session did timeout, reconnecting for new session ID...
+INFO - get_session_id:response_dict: {'isPassCodeEnabled': False, 'locale': 'nl_NL', 'redirectUrl': 'https://trader.degiro.nl/trader/', 'sessionId': '2BADBBEF3****', 'status': 0, 'statusText': 'success'}
+INFO - confirmation_id: "053df7cf-****"
+response_datetime {
+ seconds: 1643801134
+ nanos: 715765000
+}
+```
+
+**REFRESH TIMEOUT**
+
+As mentioned before, the timeout will be reset after each call to the `TradingAPI`. This provides the opportunity to make a periodic function call, for example every 10 minutes to [`get_update()`](#51-how-to-retrieve-pending-orders-).
+
+However, this might interfere with your other logic and might not be robust over time when DeGiro decides to decrease the timeout on their server.
+
+Therefor it's strongly recommended to always incorporate the exception handling for `TimeoutError` as indicated in the example above.
+
+**CHANGE PERIOD**
+
+It's possible to change the timeout period while creating the `TradingAPI`. Just add a `ModelConnection` object for parameter `connection_storage`:
+```python
+# SETUP TRADING API
+trading_api = TradingAPI(
+ credentials=credentials,
+ connection_storage=ModelConnection(
+ timeout=600,
+ )
+)
+
+# Connect:
+trading_api.connect()
+```
+The connection will now expire after 10 minutes (10 * 60 s).
+
+
+# 4. Order
+
+Creating and updating of orders is done with an `Order` object. Here are the parameters:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|id|str|Optional for [`update_order()`](#42-how-to-update-an-order-). It's the `order_id` of the created `Order` as returned by [`confirm_order()`](#412-confirm-order).|
+|action|`Order.Action`|Whether you want to : `BUY` or `SELL`.|
+|order_type|`Order.OrderType`|Type of order : `LIMIT`, `STOP_LIMIT`, `MARKET` or `STOP_LOSS`.|
+|price|float|Limit price of the order. <br /> Optional for the following `order_type` : `LIMIT` and `STOPLIMIT`.|
+|product_id|int|Identifier of the product concerned by the order.|
+|size|float|Size of the order.|
+|stop_price|float|Stop price of the order. <br /> Optional for the following `order_type` : `STOPLIMIT` and `STOPLOSS`|
+|time_type|`Order.TimeType`|Duration of the order : `GOOD_TILL_DAY` or `GOOD_TILL_CANCELED`|
+
+The full description of an `Order` is available here :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+## 4.1. How to create an Order ?
+
+The order creation is done in two steps :
+1. Checking : send the `Order` to the API to check if it is valid.
+2. Confirmation : confirm the creation of the `Order`.
+
+Keeping these two steps (instead of reducing to one single "create" function) provides more options.
+
+## 4.1.1 Check order
+Use the `check_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order|`Order`|The order to create with all necessary [parameters](#4-order).|
+
+### **Response parameters**
+On a succesfull request, a `dict` with the following parameters is returned:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|confirmation_id|str|Id necessary to confirm the creation of the Order by the [`confirm_order()`](#412-confirm-order) function.|
+|response_datetime|[`Timestamp`](https://pythonhosted.org/gax-google-pubsub-v1/google.protobuf.timestamp_pb2.html)|A `Timestamp` represents a point in time independent of any time zone or calendar, represented as seconds (`seconds`) and fractions of seconds at nanosecond resolution (`nanos`) in UTC Epoch time. A `Timestamp` can be converted to a RFC 3339 date string by using `ToJsonString()`.<br> Note: This `Timestamp` is created by Degiro Connector on reception of the API response, not by DeGiro server.|
+|free_space_new|float|New free space (balance) if the Order is confirmed.|
+|transaction_fees|float|Transaction fees that will be applied to the Order.|
+|show_ex_ante_report_link|bool|?|
+
+When the request fails, `None` is returned.
+
+## 4.1.2 Confirm order
+Use the `confirm_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|confirmation_id|str|The confirmtation id from the [`check_order()`](#411-check-order) response.|
+|order|`Order`|The same order from the [`check_order()`](#411-check-order) request.|
+
+### **Response parameters**
+On a succesfull request, a `dict` with the following parameters is returned:
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order_id|str|A unique id of the accepted order. This id is required to [update](#42-how-to-update-an-order-) or [delete](#43-how-to-delete-an-order-) the pending order.|
+|response_datetime|[`Timestamp`](https://pythonhosted.org/gax-google-pubsub-v1/google.protobuf.timestamp_pb2.html)|A `Timestamp` represents a point in time independent of any time zone or calendar, represented as seconds (`seconds`) and fractions of seconds at nanosecond resolution (`nanos`) in UTC Epoch time. A `Timestamp` can be converted to a RFC 3339 date string by using `ToJsonString()`.<br> Note: This `Timestamp` is created by Degiro Connector on reception of the API response, not by DeGiro server.|
+
+When the request fails, `None` is returned.
+
+## 4.1.3 Example of combining these functions
+
+```python
+# SETUP ORDER
+order = Order(
+ action=Order.Action.BUY,
+ order_type=Order.OrderType.LIMIT,
+ price=10,
+ product_id=71981,
+ size=1,
+ time_type=Order.TimeType.GOOD_TILL_DAY,
+)
+
+# FETCH CHECKING_RESPONSE
+checking_response = trading_api.check_order(order=order)
+
+# EXTRACT CONFIRMATION_ID
+confirmation_id = checking_response.confirmation_id
+
+# SEND CONFIRMATION
+confirmation_response = trading_api.confirm_order(
+ confirmation_id=confirmation_id,
+ order=order,
+)
+```
+
+For a more comprehensive example :
+[order.py](examples/trading/order.py)
+
+## 4.2. How to update an Order ?
+
+To modify a specific Order, you need to set it up with the `order_id` from the [`confirm_order()`](#412-confirm-order) response and use the `update_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order|`Order`|The order to update with all necessary [parameters](#4-order), including `id` as returned by [`confirm_order()`](#412-confirm-order).|
+
+### **Response parameters**
+On a succesfull request, a `bool` with the value `True` is returned.
+
+When the request fails, `None` is returned. A valid reason is that the pending order has been already executed on the exchange, and this `order_id` no longer exists.
+
+Here is an example:
+
+```python
+# ORDER SETUP
+order = Order(
+ id=YOUR_ORDER_ID, # `order_id` from `confirm_order()` response
+ action=Order.Action.BUY,
+ order_type=Order.OrderType.LIMIT,
+ price=10.60,
+ product_id=71981,
+ size=1,
+ time_type=Order.TimeType.GOOD_TILL_DAY,
+)
+
+# UPDATE ORDER
+succcess = trading_api.update_order(order=order)
+```
+
+## 4.3. How to delete an Order ?
+
+To delete a specific Order you just need the `order_id` from the [`confirm_order()`](#412-confirm-order) response and use the `delete_order()` function of the Trading API:
+
+### **Request parameters**
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|order_id|str|The unique id of the accepted order as returned by [`confirm_order()`](#412-confirm-order).|
+
+### **Response parameters**
+On a succesfull request, a `bool` with the value `True` is returned.
+
+When the request fails, `None` is returned. A valid reason is that the pending order has been already executed on the exchange, and this `order_id` no longer exists.
+
+Here is an example:
+
+```python
+# DELETE ORDER
+succcess = trading_api.delete_order(order_id=YOUR_ORDER_ID) # `order_id` from `confirm_order()` response
+```
+
+# 5. Portfolio
+
+## 5.1. How to retrieve pending Orders ?
+
+This is how to get the list of Orders currently created but not yet executed or deleted :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.ORDERS, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+orders_df = pd.DataFrame(update_dict['orders']['values'])
+```
+
+Example : Orders
+
+ product_id time_type price size id ... action order_type stop_price retained_order sent_to_exchange
+ 0 0 GOOD_TILL_DAY 2 3 202cb962-ac59-075b-964b-07152d234b70 ... BUY LIMIT 16 17 18
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+## 5.2. How to get the Portfolio ?
+
+This is how to list the stocks/products currently in the portfolio :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.PORTFOLIO, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+portfolio_df = pd.DataFrame(update_dict['portfolio']['values'])
+```
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+Note: In order to resolve product IDs to Human readable names, see [7.12. How to search products from ids ?](#712-how-to-search-products-from-ids-)
+
+## 5.3. How to get the TotalPortfolio ?
+
+This is how to get aggregated data about the portfolio :
+```python
+request_list = Update.RequestList()
+request_list.values.extend([
+ Update.Request(option=Update.Option.TOTALPORTFOLIO, last_updated=0),
+])
+
+update = trading_api.get_update(request_list=request_list)
+update_dict = pb_handler.message_to_dict(message=update)
+total_portfolio_df = pd.DataFrame(update_dict['total_portfolio']['values'])
+```
+
+Example : DataFrame
+
+ degiroCash flatexCash totalCash totalDepositWithdrawal todayDepositWithdrawal ... reportNetliq reportOverallMargin reportTotalLongVal reportDeficit marginCallStatus
+ 0 0 1 2 3 4 ... 16 17 18 19 NO_MARGIN_CALL
+
+For a more comprehensive example :
+[update.py](examples/trading/update.py)
+
+## 5.4. How to retrieve the OrdersHistory ?
+
+This method returns data about passed orders between two dates.
+
+The result contains a list of "Orders" objects with the following attributes :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|created|str|RFC 3339 Datetime, example : "2020-10-06T20:07:18+02:00".|
+|orderId|str|MD5 HASH, example : "098f6bcd-4621-d373-cade-4e832627b4f6"|
+|productId|int|Id of the product example : 65156|
+|size|float|Size of the order, example : 10.0000|
+|price|float|Price of the order, example : 8.6800|
+|buysell|str|"B" or "S"|
+|orderTypeId|int|see 3.Order|
+|orderTimeTypeId|int|see 3.Order|
+|stopPrice|float|Price like : 0.0000|
+|totalTradedSize|int|-|
+|type|str|"CREATE", "DELETE" or "MODIFY"|
+|status|str|"CONFIRMED"|
+|last|str|RFC 3339 Datetime, example : "2020-10-06T20:07:18+02:00".|
+|isActive|bool|-|
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = OrdersHistory.Request.Date(year=2020,month=11,day=15)
+to_date = OrdersHistory.Request.Date(year=2020,month=10,day=15)
+request = OrdersHistory.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+orders_history = trading_api.get_orders_history(request=request)
+```
+
+For a more comprehensive example :
+[orders_history.py](examples/trading/orders_history.py)
+
+## 5.5. How to retrieve the TransactionsHistory ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = TransactionsHistory.Request.Date(year=2020,month=11,day=15)
+to_date = TransactionsHistory.Request.Date(year=2020,month=10,day=15)
+request = TransactionsHistory.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+transactions_history = trading_api.get_transactions_history(request=request)
+```
+
+For a more comprehensive example :
+[transactions_history.py](examples/trading/transactions_history.py)
+
+# 6. Account
+
+## 6.1. How to retrieve the table : Config ?
+
+The config table contains the following informations :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|sessionId|str|Current session id.|
+|clientId|int|Unique Degiro's Account identifier also called "userToken"|
+|tradingUrl|str|-|
+|paUrl|str|-|
+|reportingUrl|str|-|
+|paymentServiceUrl|str|-|
+|productSearchUrl|str|-|
+|dictionaryUrl|str|-|
+|productTypesUrl|str|-|
+|companiesServiceUrl|str|-|
+|i18nUrl|str|-|
+|vwdQuotecastServiceUrl|str|-|
+|vwdNewsUrl|str|-|
+|vwdGossipsUrl|str|-|
+|taskManagerUrl|str|-|
+|refinitivNewsUrl|str|-|
+|refinitivAgendaUrl|str|-|
+|refinitivCompanyProfileUrl|str|-|
+|refinitivCompanyRatiosUrl|str|-|
+|refinitivFinancialStatementsUrl|str|-|
+|refinitivClipsUrl|str|-|
+|landingPath|str|-|
+|betaLandingPath|str|-|
+|mobileLandingPath|str|-|
+|loginUrl|str|-|
+
+Here is how to get this table :
+
+```python
+# FETCH DATA
+config_table = trading_api.get_config()
+
+# EXTRACT SOME DATA
+user_token = config_table['clientId']
+session_id = config_table['sessionId']
+```
+
+For a more comprehensive example :
+[config_table.py](examples/trading/config_table.py)
+
+## 6.2. How to retrieve the table : ClientDetails ?
+
+The ClientDetails table contains information about the current Degiro Account.
+
+|**Parameter**|**Type**|
+|:-|:-|
+|id|int|
+|intAccount|int|
+|loggedInPersonId|int|
+|clientRole|str|
+|effectiveClientRole|str|
+|contractType|str|
+|username|str|
+|displayName|str|
+|email|str|
+|firstContact.firstName|str|
+|firstContact.lastName|str|
+|firstContact.displayName|str|
+|firstContact.nationality|str|
+|firstContact.gender|str|
+|firstContact.dateOfBirth|str|
+|firstContact.placeOfBirth|str|
+|firstContact.countryOfBirth|str|
+|address.streetAddress|str|
+|address.streetAddressNumber|str|
+|address.zip|str|
+|address.city|str|
+|address.country|str|
+|cellphoneNumber|str|
+|locale|str|
+|language|str|
+|culture|str|
+|bankAccount.bankAccountId|int|
+|bankAccount.bic|str|
+|bankAccount.iban|str|
+|bankAccount.status|str|
+|flatexBankAccount.bic|str|
+|flatexBankAccount.iban|str|
+|memberCode|str|
+|isWithdrawalAvailable|bool|
+|isAllocationAvailable|bool|
+|isIskClient|bool|
+|isCollectivePortfolio|bool|
+|isAmClientActive|bool|
+|canUpgrade|bool|
+
+Here is how to get this table :
+
+```python
+# FETCH DATA
+client_details_table = trading_api.get_client_details()
+
+# EXTRACT SOME DATA
+int_account = client_details_table['data']['intAccount']
+user_token = client_details_table['data']['id']
+```
+
+For a more comprehensive example :
+[client_details_table.py](examples/trading/client_details_table.py)
+
+## 6.3. How to retrieve the table : AccountInfo ?
+
+The AccountInfo table contains the following information about currencies.
+
+|**Parameter**|**Type**|
+|:-|:-|
+|clientId|int|
+|baseCurrency|str|
+|currencyPairs|dict|
+|marginType|str|
+|cashFunds|dict|
+|compensationCapping|float|-|
+
+Here is how to get this table :
+
+```python
+account_info_table = trading_api.get_account_info()
+```
+
+For a more comprehensive example :
+[account_info_table.py](examples/trading/account_info_table.py)
+
+## 6.4. How to get the table : AccountOverview ?
+
+It will provide a list of cash movements.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+from_date = AccountOverview.Request.Date(year=2020,month=11,day=15)
+to_date = AccountOverview.Request.Date(year=2020,month=10,day=15)
+request = AccountOverview.Request(from_date=from_date, to_date=to_date)
+
+# FETCH DATA
+account_overview = trading_api.get_account_overview(request=request)
+```
+
+For a more comprehensive example :
+[account_overview.py](examples/trading/account_overview.py)
+
+Each cash movement contains this kind of parameters :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|date|str|
+|valueDate|str|
+|id|int|
+|orderId|str|
+|description|str|
+|productId|int|
+|currency|str|
+|change|float|
+|balance|dict|
+|unsettledCash|float|
+|total|float|
+
+
+## 6.5. How to export the table : CashAccountReport ?
+
+It will export a list of cash movements in a specific format.
+
+Available formats :
+- CSV
+- HTML
+- PDF
+- XLS
+
+Here is how to get this content in `CSV` format :
+
+```python
+# SETUP REQUEST
+from_date = CashAccountReport.Request.Date(year=2020,month=11,day=15)
+to_date = CashAccountReport.Request.Date(year=2020,month=10,day=15)
+request = CashAccountReport.Request(
+ format=CashAccountReport.Format.CSV,
+ country='FR',
+ lang='fr',
+ from_date=from_date,
+ to_date=to_date,
+)
+
+# FETCH DATA
+cash_account_report = trading_api.get_cash_account_report(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `CashAccountReport.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|format|CashAccountReport.Format|Wanted format : <br>`CSV`<br>`HTML`<br>`PDF`<br>`XLS`|
+|country|str|Country name, like : `FR`|
+|lang|int|Language, like : `fr`|
+|from_date|CashAccountReport.Request.Date|Events starting after this date.|
+|to_date|CashAccountReport.Request.Date|Events before this date.|
+
+Exact definitions of `CashAccountReport` and `CashAccountReport.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[cash_account_report.py](examples/trading/cash_account_report.py)
+
+## 6.6. How to export the table : PositionReport ?
+
+It will export a list of cash movements in a specific format.
+
+Available formats :
+- CSV
+- HTML
+- PDF
+- XLS
+
+Here is how to get this content in `CSV` format :
+
+```python
+# SETUP REQUEST
+to_date = CashAccountReport.Request.Date(year=2020,month=10,day=15)
+request = CashAccountReport.Request(
+ format=CashAccountReport.Format.CSV,
+ country='FR',
+ lang='fr',
+ to_date=to_date,
+)
+
+# FETCH DATA
+position_report = trading_api.get_position_report(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `PositionReport.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|format|PositionReport.Format|Wanted format : <br>`CSV`<br>`HTML`<br>`PDF`<br>`XLS`|
+|country|str|Country name, like : `FR`|
+|lang|int|Language, like : `fr`|
+|to_date|PositionReport.Request.Date|Events before this date.|
+
+Exact definitions of `PositionReport` and `PositionReport.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[position_report.py](examples/trading/position_report.py)
+
+# 7. Products
+
+## 7.1. How to get the table : ProductsConfig ?
+
+This table contains useful parameters to filter products.
+
+Here are the parameters which are inside this table :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|stockCountries|list|
+|bondExchanges|list|
+|bondIssuerTypes|list|
+|eurexCountries|list|
+|futureExchanges|list|
+|optionExchanges|list|
+|combinationExchanges|list|
+|cfdExchanges|list|
+|exchanges|list|
+|indices|list|
+|regions|list|
+|countries|list|
+|productTypes|list|
+|etfFeeTypes|list|
+|investmentFundFeeTypes|list|
+|optionAggregateTypes|list|
+|leveragedAggregateTypes|list|
+|etfAggregateTypes|list|
+|investmentFundAggregateTypes|list|
+|lookupSortColumns|list|
+|stockSortColumns|list|
+|bondSortColumns|list|
+|cfdSortColumns|list|
+|etfSortColumns|list|
+|futureSortColumns|list|
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+products_config = trading_api.get_products_config()
+```
+
+For a more comprehensive example :
+[products_config.py](examples/trading/products_config.py)
+
+## 7.2. How to get my favourite products ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+favourites_list = trading_api.get_favourites_list()
+```
+
+For a more comprehensive example :
+[favourites_list.py](examples/trading/favourites_list.py)
+
+## 7.3. How to lookup products (search by name) ?
+
+Text research on a financial product.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestLookup(
+ search_text='APPLE',
+ limit=10,
+ offset=0,
+ product_type_id=1,
+)
+
+# FETCH DATA
+products_lookup = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_lookup.py](examples/trading/product_lookup.py)
+
+## 7.4. How to search bonds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestBonds(
+ bond_issuer_type_id=0,
+ bond_exchange_id=710,
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+bond_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.5. How to search etfs ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestETFs(
+ popular_only=False,
+ input_aggregate_types='',
+ input_aggregate_values='',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+etf_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.6. How to search funds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestFunds(
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+fund_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.7. How to search futures ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestFutures(
+ future_exchange_id=1,
+ underlying_isin='FR0003500008',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+fund_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.8. How to search leverageds ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestLeverageds(
+ popular_only=False,
+ input_aggregate_types='',
+ input_aggregate_values='',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+etf_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.9. How to search options ?
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestOptions(
+ input_aggregate_types='',
+ input_aggregate_values='',
+ option_exchange_id=3,
+ underlying_isin='FR0003500008',
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='expirationDate,strike',
+ sort_types='asc,asc',
+)
+
+# FETCH DATA
+option_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.10. How to search stocks ?
+
+It contains information about available stocks.
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestStocks(
+ index_id=122001, # NASDAQ 100
+ exchange_id=663, # NASDAQ
+ # You can either use `index_id` or `exchange id`
+ # See which one to use in the `ProductsConfig` table
+ is_in_us_green_list=True,
+ stock_country_id=846, # US
+
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+stock_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.11. How to search warrants ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductSearch.RequestWarrants(
+ search_text='',
+ offset=0,
+ limit=100,
+ require_total=True,
+ sort_columns='name',
+ sort_types='asc',
+)
+
+# FETCH DATA
+warrant_list = trading_api.product_search(request=request)
+```
+
+For a more comprehensive example :
+[product_search.py](examples/trading/product_search.py)
+
+## 7.12. How to search products from ids ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = ProductsInfo.Request()
+request.products.extend([96008, 1153605, 5462588])
+
+# FETCH DATA
+products_info = trading_api.get_products_info(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[products_info.py](examples/trading/products_info.py)
+
+## 7.13. How to create a favourite list ?
+
+Example :
+
+```python
+favorite_list_id = trading_api.create_favourite_list(name="SOME_NAME")
+```
+
+For a more comprehensive example :
+[favourite_list_create.py](examples/trading/favourite_list_create.py)
+
+## 7.14. How to delete a favourite list ?
+
+Example :
+
+```python
+success = trading_api.delete_favourite_list(id=1234567)
+```
+
+For a more comprehensive example :
+[favourite_list_delete.py](examples/trading/favourite_list_delete.py)
+
+## 7.15. How to put favourite list products ?
+
+Example :
+
+```python
+success = trading_api.put_favourite_list_product(
+ id=1234567,
+ product_id=1234567,
+)
+```
+
+For a more comprehensive example :
+[favourite_list_put_product.py](examples/trading/favourite_list_put_product.py)
+
+## 7.16. How to delete favourite list products ?
+
+Example :
+
+```python
+success = trading_api.delete_favourite_list_product(
+ id=1234567,
+ product_id=1234567,
+)
+```
+
+For a more comprehensive example :
+[favourite_list_delete product.py](examples/trading/favourite_list_delete product.py)
+
+# 8. Companies
+
+## 8.1. How to get : CompanyProfile ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+company_profile = trading_api.get_company_profile(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[company_profile.py](examples/trading/company_profile.py)
+
+## 8.2. How to get : CompanyRatios ?
+
+This table contains information about the company.
+
+Here are the parameters which are inside this table :
+
+|**Parameter**|**Type**|
+|:-|:-|
+|totalFloat|str|
+|sharesOut|str|
+|consRecommendationTrend|dict|
+|forecastData|dict|
+|currentRatios|dict|
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+company_ratios = trading_api.get_company_ratios(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[company_ratios.py](examples/trading/company_ratios.py)
+
+## 8.3. How to get : FinancialStatements ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+financials_statements = trading_api.get_financials_statements(
+ product_isin='FR0000131906',
+)
+```
+
+For a more comprehensive example :
+[financial_statements.py](examples/trading/financial_statements.py)
+
+## 8.4. How to get : LatestNews ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = LatestNews.Request(
+ offset=0,
+ languages='en,fr',
+ limit=20,
+)
+
+# FETCH DATA
+latest_news = trading_api.get_latest_news(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[latest_news.py](examples/trading/latest_news.py)
+
+## 8.5. How to get : TopNewsPreview ?
+
+Here is how to get this data :
+
+```python
+# FETCH DATA
+top_news_preview = trading_api.get_top_news_preview(raw=True)
+```
+
+For a more comprehensive example :
+[top_news_preview.py](examples/trading/top_news_preview.py)
+
+## 8.6. How to get : NewsByCompany ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = NewsByCompany.Request(
+ isin='NL0000235190',
+ limit=10,
+ offset=0,
+ languages='en,fr',
+)
+
+# FETCH DATA
+news_by_company = trading_api.get_news_by_company(
+ request=request,
+ raw=True,
+)
+```
+
+For a more comprehensive example :
+[news_by_company.py](examples/trading/news_by_company.py)
+
+
+## 8.7. How to get : Agenda ?
+
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = Agenda.Request()
+request.start_date.FromJsonString('2021-06-21T22:00:00Z')
+request.end_date.FromJsonString('2021-11-28T23:00:00Z')
+request.calendar_type = Agenda.CalendarType.DIVIDEND_CALENDAR
+request.offset = 0
+request.limit = 25
+
+# FETCH DATA
+agenda = trading_api.get_agenda(
+ request=request,
+ raw=False,
+)
+```
+
+Here are the available parameters for `Agenda.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|calendar_type|Agenda.CalendarType|Type of agenda : <br>`DIVIDEND_CALENDAR`<br>`ECONOMIC_CALENDAR`<br>`EARNINGS_CALENDAR`<br>`HOLIDAY_CALENDAR`<br>`IPO_CALENDAR`<br>`SPLIT_CALENDAR`|
+|offset|int|-|
+|limit|int|-|
+|order_by_desc|bool|-|
+|start_date|Timestamp|Events starting after this date.|
+|end_date|Timestamp|Events before this date.|
+|company_name|str|Filter used on the events description.|
+|countries|str|Comma separated list of countries like : `FR,US`|
+|classifications|str|Comma separated list of sectors like : `GovernmentSector,ExternalSector`|
+|units|str|Comma separated list of units like : `Acre,Barrel`|
+
+Exact definitions of `Agenda` and `Agenda.Request` are in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[agenda.py](examples/trading/agenda.py)
+
+
+## 8.8. How to get : EstimatesSummaries ?
+Here is how to get this data :
+
+```python
+# SETUP REQUEST
+request = Agenda.Request()
+request.start_date.FromJsonString('2021-06-21T22:00:00Z')
+request.end_date.FromJsonString('2021-11-28T23:00:00Z')
+request.calendar_type = Agenda.CalendarType.DIVIDEND_CALENDAR
+request.offset = 0
+request.limit = 25
+
+# FETCH DATA
+product_isin = "FR0000131906"
+estimates_summaries = trading_api.get_estimates_summaries(
+ product_isin=product_isin,
+ raw=False,
+)
+```
+
+Here are the available parameters for `Agenda.Request` :
+
+|**Parameter**|**Type**|**Description**|
+|:-|:-|:-|
+|annual|google.protobuf.Struct|Indicators by year.|
+|currency|str|currency, example `EUR`.|
+|interim|google.protobuf.Struct|Indicators by quarter.|
+|lastRetrieved|str|Last Retrieved, example : `2021-12-31T20:07:30.939Z`.|
+|lastUpdated|str|Last updated,, example : `2021-02-18T01:30:00Z`.|
+|preferredMeasure|str|Preferred measure, example : `EPS`.|
+|ric|str|Reuters Instrument Code, example : `BOUY.PA`.|
+
+Exact definition of `EstimatesSummaries` is in this file :
+[trading.proto](protos/degiro_connector/trading/models/trading.proto)
+
+For a more comprehensive example :
+[estimates_summaries.py](examples/trading/estimates_summaries.py)
+
+# 9. Contributing
+Pull requests are welcome.
+
+Feel free to open an issue or send me a message if you have a question.
+
+# 10. License
+[BSD-3-Clause License](https://raw.githubusercontent.com/Chavithra/degiro-connector/main/LICENSE)
+
+
+%prep
+%autosetup -n degiro-connector-2.0.23
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-degiro-connector -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Fri May 05 2023 Python_Bot <Python_Bot@openeuler.org> - 2.0.23-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..71a34d0
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+7702649043b143dff30e928cd931bc28 degiro_connector-2.0.23.tar.gz