From ab93e136825cc0580df80df9563272d94762d839 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:01:36 +0000 Subject: [PATCH 01/11] Bump filelock from 3.3.2 to 3.4.0 Bumps [filelock](https://github.com/tox-dev/py-filelock) from 3.3.2 to 3.4.0. - [Release notes](https://github.com/tox-dev/py-filelock/releases) - [Changelog](https://github.com/tox-dev/py-filelock/blob/main/docs/changelog.rst) - [Commits](https://github.com/tox-dev/py-filelock/compare/3.3.2...3.4.0) --- updated-dependencies: - dependency-name: filelock dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-hyperopt.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-hyperopt.txt b/requirements-hyperopt.txt index 7efbb47cd..a3da8f0be 100644 --- a/requirements-hyperopt.txt +++ b/requirements-hyperopt.txt @@ -5,7 +5,7 @@ scipy==1.7.2 scikit-learn==1.0.1 scikit-optimize==0.9.0 -filelock==3.3.2 +filelock==3.4.0 joblib==1.1.0 psutil==5.8.0 progressbar2==3.55.0 From fdc6ca1bd827d16ac3eeb3d3077f6c59def8670f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:01:48 +0000 Subject: [PATCH 02/11] Bump cryptography from 35.0.0 to 36.0.0 Bumps [cryptography](https://github.com/pyca/cryptography) from 35.0.0 to 36.0.0. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/35.0.0...36.0.0) --- updated-dependencies: - dependency-name: cryptography dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index d715b8f52..0822e2555 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ pandas-ta==0.3.14b ccxt==1.61.24 # Pin cryptography for now due to rust build errors with piwheels -cryptography==35.0.0 +cryptography==36.0.0 aiohttp==3.7.4.post0 SQLAlchemy==1.4.27 python-telegram-bot==13.8.1 From 247f855ba9ab4665dd893c2bf16f65206cdbcbfd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:01:52 +0000 Subject: [PATCH 03/11] Bump types-cachetools from 4.2.4 to 4.2.5 Bumps [types-cachetools](https://github.com/python/typeshed) from 4.2.4 to 4.2.5. - [Release notes](https://github.com/python/typeshed/releases) - [Commits](https://github.com/python/typeshed/commits) --- updated-dependencies: - dependency-name: types-cachetools dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements-dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index ab06468b9..4c06e657b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -20,7 +20,7 @@ time-machine==2.4.0 nbconvert==6.3.0 # mypy types -types-cachetools==4.2.4 +types-cachetools==4.2.5 types-filelock==3.2.1 types-requests==2.26.0 types-tabulate==0.8.3 From 0ef99206b0aac071bb36dd7420b240cd7cde7e4e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 03:01:56 +0000 Subject: [PATCH 04/11] Bump plotly from 5.3.1 to 5.4.0 Bumps [plotly](https://github.com/plotly/plotly.py) from 5.3.1 to 5.4.0. - [Release notes](https://github.com/plotly/plotly.py/releases) - [Changelog](https://github.com/plotly/plotly.py/blob/master/CHANGELOG.md) - [Commits](https://github.com/plotly/plotly.py/compare/v5.3.1...v5.4.0) --- updated-dependencies: - dependency-name: plotly dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements-plot.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements-plot.txt b/requirements-plot.txt index 8e17232b0..488ef73d6 100644 --- a/requirements-plot.txt +++ b/requirements-plot.txt @@ -1,5 +1,5 @@ # Include all requirements to run the bot. -r requirements.txt -plotly==5.3.1 +plotly==5.4.0 From 80946cd9d6f1149dc8f10103c28b6733827464ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Nov 2021 05:47:48 +0000 Subject: [PATCH 05/11] Bump ccxt from 1.61.24 to 1.61.92 Bumps [ccxt](https://github.com/ccxt/ccxt) from 1.61.24 to 1.61.92. - [Release notes](https://github.com/ccxt/ccxt/releases) - [Changelog](https://github.com/ccxt/ccxt/blob/master/exchanges.cfg) - [Commits](https://github.com/ccxt/ccxt/compare/1.61.24...1.61.92) --- updated-dependencies: - dependency-name: ccxt dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0822e2555..8f612451c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ numpy==1.21.4 pandas==1.3.4 pandas-ta==0.3.14b -ccxt==1.61.24 +ccxt==1.61.92 # Pin cryptography for now due to rust build errors with piwheels cryptography==36.0.0 aiohttp==3.7.4.post0 From ecf2ac3c219f135b1d268a837948eca182e1a9dc Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 22 Nov 2021 06:51:06 +0100 Subject: [PATCH 06/11] Bump aiohttp to 3.8.1 --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8f612451c..a5af330af 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ pandas-ta==0.3.14b ccxt==1.61.92 # Pin cryptography for now due to rust build errors with piwheels cryptography==36.0.0 -aiohttp==3.7.4.post0 +aiohttp==3.8.1 SQLAlchemy==1.4.27 python-telegram-bot==13.8.1 arrow==1.2.1 @@ -43,4 +43,4 @@ colorama==0.4.4 questionary==1.10.0 prompt-toolkit==3.0.22 # Extensions to datetime library -python-dateutil==2.8.2 \ No newline at end of file +python-dateutil==2.8.2 From 64e34f382ee31860c03a659f718f1e32f2724624 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 22 Nov 2021 07:13:22 +0100 Subject: [PATCH 07/11] Sell-fill should include open-rate --- freqtrade/rpc/telegram.py | 6 +++--- tests/rpc/test_rpc_telegram.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 0e1a6fe27..6c6f745e7 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -274,11 +274,11 @@ class Telegram(RPCHandler): f"*Buy Tag:* `{msg['buy_tag']}`\n" f"*Sell Reason:* `{msg['sell_reason']}`\n" f"*Duration:* `{msg['duration']} ({msg['duration_min']:.1f} min)`\n" - f"*Amount:* `{msg['amount']:.8f}`\n") + f"*Amount:* `{msg['amount']:.8f}`\n" + f"*Open Rate:* `{msg['open_rate']:.8f}`\n") if msg['type'] == RPCMessageType.SELL: - message += (f"*Open Rate:* `{msg['open_rate']:.8f}`\n" - f"*Current Rate:* `{msg['current_rate']:.8f}`\n" + message += (f"*Current Rate:* `{msg['current_rate']:.8f}`\n" f"*Close Rate:* `{msg['limit']:.8f}`") elif msg['type'] == RPCMessageType.SELL_FILL: diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 1247affae..ce3b044be 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -1843,6 +1843,7 @@ def test_send_msg_sell_fill_notification(default_conf, mocker) -> None: '*Sell Reason:* `stop_loss`\n' '*Duration:* `1 day, 2:30:00 (1590.0 min)`\n' '*Amount:* `1333.33333333`\n' + '*Open Rate:* `0.00007500`\n' '*Close Rate:* `0.00003201`' ) From 78a00f2518e4c2c2022194c86d0601b7713cda5c Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Mon, 22 Nov 2021 09:27:33 +0200 Subject: [PATCH 08/11] Use market data to get base and quote currencies in @informative() decorator. --- freqtrade/optimize/backtesting.py | 2 +- freqtrade/strategy/informative_decorator.py | 11 +++++----- .../strats/informative_decorator_strategy.py | 10 +++++----- tests/strategy/test_strategy_helpers.py | 20 ++++++++++--------- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 49957c2bb..5c41041b4 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -67,7 +67,7 @@ class Backtesting: self.all_results: Dict[str, Dict] = {} self.exchange = ExchangeResolver.load_exchange(self.config['exchange']['name'], self.config) - self.dataprovider = DataProvider(self.config, None) + self.dataprovider = DataProvider(self.config, self.exchange) if self.config.get('strategy_list', None): for strat in list(self.config['strategy_list']): diff --git a/freqtrade/strategy/informative_decorator.py b/freqtrade/strategy/informative_decorator.py index 4c5f21108..722e7a128 100644 --- a/freqtrade/strategy/informative_decorator.py +++ b/freqtrade/strategy/informative_decorator.py @@ -80,12 +80,11 @@ def _create_and_merge_informative_pair(strategy, dataframe: DataFrame, metadata: # Not specifying an asset will define informative dataframe for current pair. asset = metadata['pair'] - if '/' in asset: - base, quote = asset.split('/') - else: - # When futures are supported this may need reevaluation. - # base, quote = asset, '' - raise OperationalException('Not implemented.') + market = strategy.dp.market(asset) + if market is None: + raise OperationalException(f'Market {asset} is not available.') + base = market['base'] + quote = market['quote'] # Default format. This optimizes for the common case: informative pairs using same stake # currency. When quote currency matches stake currency, column name will omit base currency. diff --git a/tests/strategy/strats/informative_decorator_strategy.py b/tests/strategy/strats/informative_decorator_strategy.py index a32ad79e8..17d4df018 100644 --- a/tests/strategy/strats/informative_decorator_strategy.py +++ b/tests/strategy/strats/informative_decorator_strategy.py @@ -20,7 +20,7 @@ class InformativeDecoratorTest(IStrategy): startup_candle_count: int = 20 def informative_pairs(self): - return [('BTC/USDT', '5m')] + return [('NEO/USDT', '5m')] def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['buy'] = 0 @@ -38,8 +38,8 @@ class InformativeDecoratorTest(IStrategy): return dataframe # Simple informative test. - @informative('1h', 'BTC/{stake}') - def populate_indicators_btc_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: + @informative('1h', 'NEO/{stake}') + def populate_indicators_neo_1h(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = 14 return dataframe @@ -50,7 +50,7 @@ class InformativeDecoratorTest(IStrategy): return dataframe # Formatting test. - @informative('30m', 'BTC/{stake}', '{column}_{BASE}_{QUOTE}_{base}_{quote}_{asset}_{timeframe}') + @informative('30m', 'NEO/{stake}', '{column}_{BASE}_{QUOTE}_{base}_{quote}_{asset}_{timeframe}') def populate_indicators_btc_1h_2(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe['rsi'] = 14 return dataframe @@ -68,7 +68,7 @@ class InformativeDecoratorTest(IStrategy): dataframe['rsi_less'] = dataframe['rsi'] < dataframe['rsi_1h'] # Mixing manual informative pairs with decorators. - informative = self.dp.get_pair_dataframe('BTC/USDT', '5m') + informative = self.dp.get_pair_dataframe('NEO/USDT', '5m') informative['rsi'] = 14 dataframe = merge_informative_pair(dataframe, informative, self.timeframe, '5m', ffill=True) diff --git a/tests/strategy/test_strategy_helpers.py b/tests/strategy/test_strategy_helpers.py index cb7cf97a1..9e546869a 100644 --- a/tests/strategy/test_strategy_helpers.py +++ b/tests/strategy/test_strategy_helpers.py @@ -7,6 +7,7 @@ import pytest from freqtrade.data.dataprovider import DataProvider from freqtrade.strategy import (merge_informative_pair, stoploss_from_absolute, stoploss_from_open, timeframe_to_minutes) +from tests.conftest import get_patched_exchange def generate_test_data(timeframe: str, size: int, start: str = '2020-07-05'): @@ -155,9 +156,9 @@ def test_informative_decorator(mocker, default_conf): ('LTC/USDT', '5m'): test_data_5m, ('LTC/USDT', '30m'): test_data_30m, ('LTC/USDT', '1h'): test_data_1h, - ('BTC/USDT', '30m'): test_data_30m, - ('BTC/USDT', '5m'): test_data_5m, - ('BTC/USDT', '1h'): test_data_1h, + ('NEO/USDT', '30m'): test_data_30m, + ('NEO/USDT', '5m'): test_data_5m, + ('NEO/USDT', '1h'): test_data_1h, ('ETH/USDT', '1h'): test_data_1h, ('ETH/USDT', '30m'): test_data_30m, ('ETH/BTC', '1h'): test_data_1h, @@ -165,15 +166,16 @@ def test_informative_decorator(mocker, default_conf): from .strats.informative_decorator_strategy import InformativeDecoratorTest default_conf['stake_currency'] = 'USDT' strategy = InformativeDecoratorTest(config=default_conf) - strategy.dp = DataProvider({}, None, None) + exchange = get_patched_exchange(mocker, default_conf) + strategy.dp = DataProvider({}, exchange, None) mocker.patch.object(strategy.dp, 'current_whitelist', return_value=[ - 'XRP/USDT', 'LTC/USDT', 'BTC/USDT' + 'XRP/USDT', 'LTC/USDT', 'NEO/USDT' ]) assert len(strategy._ft_informative) == 6 # Equal to number of decorators used informative_pairs = [('XRP/USDT', '1h'), ('LTC/USDT', '1h'), ('XRP/USDT', '30m'), - ('LTC/USDT', '30m'), ('BTC/USDT', '1h'), ('BTC/USDT', '30m'), - ('BTC/USDT', '5m'), ('ETH/BTC', '1h'), ('ETH/USDT', '30m')] + ('LTC/USDT', '30m'), ('NEO/USDT', '1h'), ('NEO/USDT', '30m'), + ('NEO/USDT', '5m'), ('ETH/BTC', '1h'), ('ETH/USDT', '30m')] for inf_pair in informative_pairs: assert inf_pair in strategy.gather_informative_pairs() @@ -186,8 +188,8 @@ def test_informative_decorator(mocker, default_conf): {p: data[(p, strategy.timeframe)] for p in ('XRP/USDT', 'LTC/USDT')}) expected_columns = [ 'rsi_1h', 'rsi_30m', # Stacked informative decorators - 'btc_usdt_rsi_1h', # BTC 1h informative - 'rsi_BTC_USDT_btc_usdt_BTC/USDT_30m', # Column formatting + 'neo_usdt_rsi_1h', # NEO 1h informative + 'rsi_NEO_USDT_neo_usdt_NEO/USDT_30m', # Column formatting 'rsi_from_callable', # Custom column formatter 'eth_btc_rsi_1h', # Quote currency not matching stake currency 'rsi', 'rsi_less', # Non-informative columns From 43dab3ee607c82e9aae86bec884efcba8845a1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ald=C3=A1n=20Creo?= <20495460+ACMCMC@users.noreply.github.com> Date: Mon, 22 Nov 2021 09:46:10 +0100 Subject: [PATCH 09/11] Changed the wording of the documentation to be clearer The sentence I've changed was continued on a different paragraph before, even though they were connected ideas. I have changed it so that they are part of the same paragraph now. --- docs/configuration.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 6c810fba2..c4689f0a6 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -202,9 +202,8 @@ There are several methods to configure how much of the stake currency the bot wi #### Minimum trade stake The minimum stake amount will depend on exchange and pair and is usually listed in the exchange support pages. -Assuming the minimum tradable amount for XRP/USD is 20 XRP (given by the exchange), and the price is 0.6$. -The minimum stake amount to buy this pair is, therefore, `20 * 0.6 ~= 12`. +Assuming the minimum tradable amount for XRP/USD is 20 XRP (given by the exchange), and the price is 0.6$, the minimum stake amount to buy this pair is `20 * 0.6 ~= 12`. This exchange has also a limit on USD - where all orders must be > 10$ - which however does not apply in this case. To guarantee safe execution, freqtrade will not allow buying with a stake-amount of 10.1$, instead, it'll make sure that there's enough space to place a stoploss below the pair (+ an offset, defined by `amount_reserve_percent`, which defaults to 5%). From c245a2a897afe67f7e40c7a668deb0a7e660a2d9 Mon Sep 17 00:00:00 2001 From: flozzone Date: Mon, 22 Nov 2021 20:10:26 +0100 Subject: [PATCH 10/11] fix typo in Volatility filter description. --- docs/includes/pairlists.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/includes/pairlists.md b/docs/includes/pairlists.md index 4f56f8e98..bbfe74510 100644 --- a/docs/includes/pairlists.md +++ b/docs/includes/pairlists.md @@ -292,7 +292,7 @@ If the trading range over the last 10 days is <1% or >99%, remove the pair from #### VolatilityFilter -Volatility is the degree of historical variation of a pairs over time, is is measured by the standard deviation of logarithmic daily returns. Returns are assumed to be normally distributed, although actual distribution might be different. In a normal distribution, 68% of observations fall within one standard deviation and 95% of observations fall within two standard deviations. Assuming a volatility of 0.05 means that the expected returns for 20 out of 30 days is expected to be less than 5% (one standard deviation). Volatility is a positive ratio of the expected deviation of return and can be greater than 1.00. Please refer to the wikipedia definition of [`volatility`](https://en.wikipedia.org/wiki/Volatility_(finance)). +Volatility is the degree of historical variation of a pairs over time, it is measured by the standard deviation of logarithmic daily returns. Returns are assumed to be normally distributed, although actual distribution might be different. In a normal distribution, 68% of observations fall within one standard deviation and 95% of observations fall within two standard deviations. Assuming a volatility of 0.05 means that the expected returns for 20 out of 30 days is expected to be less than 5% (one standard deviation). Volatility is a positive ratio of the expected deviation of return and can be greater than 1.00. Please refer to the wikipedia definition of [`volatility`](https://en.wikipedia.org/wiki/Volatility_(finance)). This filter removes pairs if the average volatility over a `lookback_days` days is below `min_volatility` or above `max_volatility`. Since this is a filter that requires additional data, the results are cached for `refresh_period`. From b8cefd687e0baf0abf27c3880bf39f8ca6b0ff0f Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 23 Nov 2021 07:06:53 +0100 Subject: [PATCH 11/11] Add api_version to botresponse --- freqtrade/rpc/api_server/api_schemas.py | 1 + freqtrade/rpc/api_server/api_v1.py | 9 ++++++++- tests/rpc/test_rpc_apiserver.py | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index c9ff0ddaf..268d50fdb 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -144,6 +144,7 @@ class OrderTypes(BaseModel): class ShowConfig(BaseModel): version: str + api_version: float dry_run: bool stake_currency: str stake_amount: Union[float, str] diff --git a/freqtrade/rpc/api_server/api_v1.py b/freqtrade/rpc/api_server/api_v1.py index 06230a7db..0467e4705 100644 --- a/freqtrade/rpc/api_server/api_v1.py +++ b/freqtrade/rpc/api_server/api_v1.py @@ -26,6 +26,11 @@ from freqtrade.rpc.rpc import RPCException logger = logging.getLogger(__name__) +# API version +# Pre-1.1, no version was provided +# Version increments should happen in "small" steps (1.1, 1.12, ...) unless big changes happen. +API_VERSION = 1.1 + # Public API, requires no auth. router_public = APIRouter() # Private API, protected by authentication @@ -117,7 +122,9 @@ def show_config(rpc: Optional[RPC] = Depends(get_rpc_optional), config=Depends(g state = '' if rpc: state = rpc._freqtrade.state - return RPC._rpc_show_config(config, state) + resp = RPC._rpc_show_config(config, state) + resp['api_version'] = API_VERSION + return resp @router.post('/forcebuy', response_model=ForceBuyResponse, tags=['trading']) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index 074e312d9..76372df55 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -538,6 +538,8 @@ def test_api_show_config(botclient): assert 'ask_strategy' in rc.json() assert 'unfilledtimeout' in rc.json() assert 'version' in rc.json() + assert 'api_version' in rc.json() + assert 1.1 <= rc.json()['api_version'] <= 1.2 def test_api_daily(botclient, mocker, ticker, fee, markets):