diff --git a/config_full.json.example b/config_full.json.example index 2bc2cde9e..ba53f47d6 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -56,7 +56,8 @@ "method": "VolumePairList", "config": { "number_assets": 20, - "sort_key": "quoteVolume" + "sort_key": "quoteVolume", + "ttl": 1800 } }, {"method": "PrecisionFilter"}, diff --git a/docs/configuration.md b/docs/configuration.md index 39fb4b8ac..8f62708d1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -82,8 +82,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `exchange.markets_refresh_interval` | 60 | The interval in minutes in which markets are reloaded. | `edge` | false | Please refer to [edge configuration document](edge.md) for detailed explanation. | `experimental.block_bad_exchanges` | true | Block exchanges known to not work with freqtrade. Leave on default unless you want to test if that exchange works now. -| `pairlist.method` | StaticPairList | Use static or dynamic volume-based pairlist. [More information below](#dynamic-pairlists). -| `pairlist.config` | None | Additional configuration for dynamic pairlists. [More information below](#dynamic-pairlists). +| `pairlists` | StaticPairList | Define one or more pairlists to be used. [More information below](#dynamic-pairlists). | `telegram.enabled` | true | **Required.** Enable or not the usage of Telegram. | `telegram.token` | token | Your Telegram bot token. Only required if `telegram.enabled` is `true`. ***Keep it in secrete, do not disclose publicly.*** | `telegram.chat_id` | chat_id | Your personal Telegram account id. Only required if `telegram.enabled` is `true`. ***Keep it in secrete, do not disclose publicly.*** @@ -382,41 +381,50 @@ The valid values are: Pairlists define the list of pairs that the bot should trade. There are [`StaticPairList`](#static-pair-list) and dynamic Whitelists available. -In addition to pairlists, [pairlist filters](#available-pairlist-filters) can be configured, which remove certain assets. -These Filters work with all Pairlist providers and are applied in the sequence they occur. +[`PrecisionFilter`](#precision-filter) and [`LowPriceFilter`](#low-price-pair-filter) act as filters, removing low-value pairs. + +All pairlists can be chained, and a combination of all pairlists will become your new whitelist. + +Inactive markets and blacklisted pairs are always removed from the resulting `pair_whitelist`. ### Available Pairlists * [`StaticPairList`](#static-pair-list) (default, if not configured differently) * [`VolumePairList`](#volume-pair-list) +* [`PrecisionFilter`](#precision-filter) +* [`LowPriceFilter`](#low-price-pair-filter) #### Static Pair List -By default, the `StaticPairList` method is used, which uses a statically defined pair whitelist from the configuration. Inactive markets and blacklisted pairs are removed from the pair_whitelist. +By default, the `StaticPairList` method is used, which uses a statically defined pair whitelist from the configuration. It uses configuration from `exchange.pair_whitelist` and `exchange.pair_blacklist`. +```json +"pairlists": [ + {"method": "StaticPairList"} + ], +``` + #### Volume Pair List `VolumePairList` selects `number_assets` top pairs based on `sort_key`, which can be one of `askVolume`, `bidVolume` and `quoteVolume` and defaults to `quoteVolume`. `VolumePairList` does not consider `pair_whitelist`, but selects the top assets from all available markets (with matching stake-currency) on the exchange. -Pairs in `pair_blacklist` are not considered for `VolumePairList`, even if all other filters would match. + +`ttl` allows setting the period (in seconds), at which the pairlist will be refreshed. Defaults to 1800s (30 minutes). ```json -"pairlist": { +"pairlists": [{ "method": "VolumePairList", "config": { "number_assets": 20, "sort_key": "quoteVolume", - }, + "ttl": 1800, + } +], ``` -### Available Pairlist Filters - -* [`PrecisionFilter`](#precision-filter) -* [`LowPriceFilter`](#low-price-pair-filter) - #### Precision Filter Filters low-value coins which would not allow setting a stoploss. @@ -440,17 +448,19 @@ The below example blacklists `BNB/BTC`, uses `VolumePairList` with `20` assets, "pair_whitelist": [], "pair_blacklist": ["BNB/BTC"] }, -"pairlist": { +"pairlists": [ + { "method": "VolumePairList", "config": { "number_assets": 20, "sort_key": "quoteVolume", }, - "filters":{ - "PrecisionFilter": {}, - "LowPriceFilter": {"low_price_percent": 0.01} - } }, + {"method": "PrecisionFilter"}, + {"method": "LowPriceFilter", + "config": {"low_price_percent": 0.01} + } + }], ``` ## Switch to Dry-run mode diff --git a/docs/developer.md b/docs/developer.md index 346578c2e..e63d970e2 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -46,15 +46,18 @@ def test_method_to_test(caplog): The fastest and easiest way to start up is to use docker-compose.develop which gives developers the ability to start the bot up with all the required dependencies, *without* needing to install any freqtrade specific dependencies on your local machine. #### Install + * [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) * [docker](https://docs.docker.com/install/) * [docker-compose](https://docs.docker.com/compose/install/) #### Starting the bot ##### Use the develop dockerfile + ``` bash rm docker-compose.yml && mv docker-compose.develop.yml docker-compose.yml ``` + #### Docker Compose ##### Starting @@ -62,9 +65,11 @@ rm docker-compose.yml && mv docker-compose.develop.yml docker-compose.yml ``` bash docker-compose up ``` + ![Docker compose up](https://user-images.githubusercontent.com/419355/65456322-47f63a80-de06-11e9-90c6-3c74d1bad0b8.png) ##### Rebuilding + ``` bash docker-compose build ``` @@ -77,8 +82,8 @@ that can be effected by `docker-compose up` or `docker-compose run freqtrade_dev ``` bash docker-compose exec freqtrade_develop /bin/bash ``` -![image](https://user-images.githubusercontent.com/419355/65456522-ba671a80-de06-11e9-9598-df9ca0d8dcac.png) +![image](https://user-images.githubusercontent.com/419355/65456522-ba671a80-de06-11e9-9598-df9ca0d8dcac.png) ## Modules @@ -95,7 +100,7 @@ This is a simple provider, which however serves as a good example on how to star Next, modify the classname of the provider (ideally align this with the Filename). -The base-class provides the an instance of the bot (`self._freqtrade`), as well as the configuration (`self._config`), and initiates both `_blacklist` and `_whitelist`. +The base-class provides an instance of the exchange (`self._exchange`) the pairlist manager (`self._pairlistmanager`), as well as the main configuration (`self._config`) and the pairlist dedicated configuration (`self._pairlistconfig`). ```python self._freqtrade = freqtrade @@ -104,10 +109,9 @@ The base-class provides the an instance of the bot (`self._freqtrade`), as well self._blacklist = self._config['exchange'].get('pair_blacklist', []) ``` - Now, let's step through the methods which require actions: -#### configuration +#### Pairlist configuration Configuration for PairListProvider is done in the bot configuration file in the element `"pairlist"`. This Pairlist-object may contain a `"config"` dict with additional configurations for the configured pairlist. @@ -120,29 +124,30 @@ Additional elements can be configured as needed. `VolumePairList` uses `"sort_ke Returns a description used for Telegram messages. This should contain the name of the Provider, as well as a short description containing the number of assets. Please follow the format `"PairlistName - top/bottom X pairs"`. -#### refresh_pairlist +#### filter_pairlist Override this method and run all calculations needed in this method. This is called with each iteration of the bot - so consider implementing caching for compute/network heavy calculations. -Assign the resulting whiteslist to `self._whitelist` and `self._blacklist` respectively. These will then be used to run the bot in this iteration. Pairs with open trades will be added to the whitelist to have the sell-methods run correctly. +It get's passed a pairlist (which can be the result of previous pairlists) as well as `tickers`, a pre-fetched version of `get_tickers()`. -Please also run `self.validate_whitelist(pairs, tickers)` (tickers is optional, but should be passed when you're using tickers anyway) and to check and remove pairs with inactive markets. This function is available in the Parent class (`StaticPairList`) and should ideally not be overwritten. +It must return the resulting pairlist (which may then be passed into the next pairlist filter). + +Validations are optional, the parent class exposes a `_verify_blacklist(pairlist)` and `_whitelist_for_active_markets(pairlist)` to do default filters. Use this if you limit your result to a certain number of pairs - so the endresult is not shorter than expected. ##### sample ``` python - def refresh_pairlist(self) -> None: + def filter_pairlist(self, pairlist: List[str], tickers: Dict) -> List[str]: # Generate dynamic whitelist - pairs = self._gen_pair_whitelist(self._config['stake_currency'], self._sort_key) - # Validate whitelist to only have active market pairs - self._whitelist = self.validate_whitelist(pairs)[:self._number_pairs] + pairs = self._calculate_pairlist(pairlist, tickers) + return pairs ``` #### _gen_pair_whitelist This is a simple method used by `VolumePairList` - however serves as a good example. -It implements caching (`@cached(TTLCache(maxsize=1, ttl=1800))`) as well as a configuration option to allow different (but similar) strategies to work with the same PairListProvider. +In VolumePairList, this implements different methods of sorting, does early validation so only the expected number of pairs is returned. ## Implement a new Exchange (WIP)