From 1b8943ac54fabbad046503efeac88f0425a6684a Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 10:59:10 +0100 Subject: [PATCH 01/27] Add documentation for tradable_balance_ratio --- config_full.json.example | 1 + docs/configuration.md | 7 +++++++ freqtrade/constants.py | 6 ++++++ 3 files changed, 14 insertions(+) diff --git a/config_full.json.example b/config_full.json.example index b9631f63d..4e692d371 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -2,6 +2,7 @@ "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "amount_reserve_percent" : 0.05, "dry_run": false, diff --git a/docs/configuration.md b/docs/configuration.md index 90f0aa791..1acd6162c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,6 +43,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.0` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -144,6 +145,12 @@ To allow the bot to trade all the available `stake_currency` in your account set "stake_amount" : "unlimited", ``` +When using `stake_amount="unlimited"`, we recommend to also set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. +This will keep 1% of your account balance "untradable" in your account. + +!!! Note: + This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). + In this case a trade amount is calculated as: ```python diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d7c6249d5..d5ba00cd5 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -73,6 +73,12 @@ CONF_SCHEMA = { 'minimum': 0.0001, 'pattern': UNLIMITED_STAKE_AMOUNT }, + 'tradable_balance_ratio': { + 'type': ['number'], + 'minimum': 0.1, + 'maximum': 1, + 'default': 0.99 + }, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, From 64db1f67365b128e8a9d9eb04893cbb5c5a8dd9c Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:16:18 +0100 Subject: [PATCH 02/27] Prepare tests to valiate reduced full amount. --- tests/test_freqtradebot.py | 15 ++++++++++----- tests/test_integration.py | 15 +++++++++++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 1c17ce735..dc17ddaaa 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -150,11 +150,14 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: freqtrade.get_trade_stake_amount('ETH/BTC') -def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, - limit_buy_order, fee, mocker) -> None: +@pytest.mark.parametrize("balance_ratio,result1,result2", [ + (1, 0.005, 0.005), + (0.99, 0.00495, 0.00495), + ]) +def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_ratio, result1, + result2, limit_buy_order, fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) - patch_wallet(mocker, free=default_conf['stake_amount']) mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, @@ -164,20 +167,22 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, conf = deepcopy(default_conf) conf['stake_amount'] = UNLIMITED_STAKE_AMOUNT + conf['dry_run_wallet'] = 0.01 conf['max_open_trades'] = 2 + conf['tradable_balance_ratio'] = balance_ratio freqtrade = FreqtradeBot(conf) patch_get_signal(freqtrade) # no open trades, order amount should be 'balance / max_open_trades' result = freqtrade.get_trade_stake_amount('ETH/BTC') - assert result == default_conf['stake_amount'] / conf['max_open_trades'] + assert result == result1 # create one trade, order amount should be 'balance / (max_open_trades - num_open_trades)' freqtrade.execute_buy('ETH/BTC', result) result = freqtrade.get_trade_stake_amount('LTC/BTC') - assert result == default_conf['stake_amount'] / (conf['max_open_trades'] - 1) + assert result == result2 # create 2 trades, order amount should be None freqtrade.execute_buy('LTC/BTC', result) diff --git a/tests/test_integration.py b/tests/test_integration.py index 1108969ad..d1be961cf 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,10 +1,11 @@ - from unittest.mock import MagicMock +import pytest + from freqtrade.persistence import Trade +from freqtrade.rpc.rpc import RPC from freqtrade.strategy.interface import SellCheckTuple, SellType from tests.conftest import get_patched_freqtradebot, patch_get_signal -from freqtrade.rpc.rpc import RPC def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, @@ -112,13 +113,19 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, assert not trade.is_open -def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker) -> None: +@pytest.mark.parametrize("balance_ratio,result1", [ + (1, 200), + (0.99, 198), +]) +def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker, balance_ratio, + result1) -> None: """ Tests workflow """ default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True default_conf['stake_amount'] = 'unlimited' + default_conf['tradable_balance_ratio'] = balance_ratio default_conf['dry_run_wallet'] = 1000 default_conf['exchange']['name'] = 'binance' default_conf['telegram']['enabled'] = True @@ -165,7 +172,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc assert len(trades) == 5 for trade in trades: - assert trade.stake_amount == 200 + assert trade.stake_amount == result1 # Reset trade open order id's trade.open_order_id = None trades = Trade.get_open_trades() From cba156dfff18d634440f1c4d7e46f95475f97f7f Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:20:57 +0100 Subject: [PATCH 03/27] Add offset calculation for relative stake maximum limit --- freqtrade/freqtradebot.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index d5d918585..6a6a14375 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -278,7 +278,15 @@ class FreqtradeBot: free_open_trades = self.get_free_open_trades() if not free_open_trades: return None - available_amount = self.wallets.get_free(self.config['stake_currency']) + + val_tied_up = Trade.total_open_trades_stakes() + + # Ensure 1% is used from the overall balance + # Otherwise we'd risk lowering stakes with each open trade. + # (tied up + current free) * ratio) - tied up + available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) * + self.config['tradable_balance_ratio']) - val_tied_up + return available_amount / free_open_trades def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]: From bfef3cf497425fad61f00382119938ea39357eb4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:37:35 +0100 Subject: [PATCH 04/27] Add additional test case for lower balance ratios --- tests/test_freqtradebot.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index dc17ddaaa..9ca54d003 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -150,12 +150,13 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: freqtrade.get_trade_stake_amount('ETH/BTC') -@pytest.mark.parametrize("balance_ratio,result1,result2", [ - (1, 0.005, 0.005), - (0.99, 0.00495, 0.00495), +@pytest.mark.parametrize("balance_ratio,result1", [ + (1, 0.005), + (0.99, 0.00495), + (0.50, 0.0025), ]) def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_ratio, result1, - result2, limit_buy_order, fee, mocker) -> None: + limit_buy_order, fee, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -182,7 +183,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r freqtrade.execute_buy('ETH/BTC', result) result = freqtrade.get_trade_stake_amount('LTC/BTC') - assert result == result2 + assert result == result1 # create 2 trades, order amount should be None freqtrade.execute_buy('LTC/BTC', result) From 94afb7cb1dff0c8d0d92d785fd9aed5854b17a66 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:45:03 +0100 Subject: [PATCH 05/27] Improve integration test with a few additional tests --- tests/test_integration.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index d1be961cf..98bf1862b 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -120,7 +120,10 @@ def test_may_execute_sell_stoploss_on_exchange_multi(default_conf, ticker, fee, def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, mocker, balance_ratio, result1) -> None: """ - Tests workflow + Tests workflow unlimited stake-amount + Buy 4 trades, forcebuy a 5th trade + Sell one trade, calculated stake amount should now be lower than before since + one trade was sold at a loss. """ default_conf['max_open_trades'] = 5 default_conf['forcebuy_enable'] = True @@ -166,6 +169,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc trades = Trade.query.all() assert len(trades) == 4 + assert freqtrade.get_trade_stake_amount('XRP/BTC') == result1 + rpc._rpc_forcebuy('TKN/BTC', None) trades = Trade.query.all() @@ -184,6 +189,8 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, limit_buy_order, moc trades = Trade.get_open_trades() # One trade sold assert len(trades) == 4 + # stake-amount should now be reduced, since one trade was sold at a loss. + assert freqtrade.get_trade_stake_amount('XRP/BTC') < result1 # Validate that balance of sold trade is not in dry-run balances anymore. bals2 = freqtrade.wallets.get_all_balances() assert bals != bals2 From 6e615998c07809a99f1a82598ec07f2d8925c645 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 13:52:35 +0100 Subject: [PATCH 06/27] Fix documentation typo --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 1acd6162c..594b79050 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -148,7 +148,7 @@ To allow the bot to trade all the available `stake_currency` in your account set When using `stake_amount="unlimited"`, we recommend to also set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. This will keep 1% of your account balance "untradable" in your account. -!!! Note: +!!! Note This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). In this case a trade amount is calculated as: From c13c11cfa19050ee430dcd31ba95b951eb32918e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 2 Jan 2020 14:41:28 +0100 Subject: [PATCH 07/27] Type does not need to be a list --- freqtrade/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index d5ba00cd5..dd3c07e69 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -74,7 +74,7 @@ CONF_SCHEMA = { 'pattern': UNLIMITED_STAKE_AMOUNT }, 'tradable_balance_ratio': { - 'type': ['number'], + 'type': 'number', 'minimum': 0.1, 'maximum': 1, 'default': 0.99 From 11059e532bf444c42daca77e31405d9e9b44f9a6 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 06:39:47 +0100 Subject: [PATCH 08/27] Fix missed default minimum in documentation --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 594b79050..2f7ef9f29 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,7 +43,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.0` and `1.0`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* From a8d56b28503f62cae1f729cf27955fc98b7b6f39 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 07:07:59 +0100 Subject: [PATCH 09/27] IMplement check for unlimited settings verifying that either max_open_trades or stake_amount is set for operations without edge --- freqtrade/configuration/config_validation.py | 12 ++++++++++++ tests/test_configuration.py | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/freqtrade/configuration/config_validation.py b/freqtrade/configuration/config_validation.py index 43eead46a..02dee2afe 100644 --- a/freqtrade/configuration/config_validation.py +++ b/freqtrade/configuration/config_validation.py @@ -67,12 +67,24 @@ def validate_config_consistency(conf: Dict[str, Any]) -> None: _validate_trailing_stoploss(conf) _validate_edge(conf) _validate_whitelist(conf) + _validate_unlimited_amount(conf) # validate configuration before returning logger.info('Validating configuration ...') validate_config_schema(conf) +def _validate_unlimited_amount(conf: Dict[str, Any]) -> None: + """ + If edge is disabled, either max_open_trades or stake_amount need to be set. + :raise: OperationalException if config validation failed + """ + if (not conf.get('edge', {}).get('enabled') + and conf.get('max_open_trades') == float('inf') + and conf.get('stake_amount') == constants.UNLIMITED_STAKE_AMOUNT): + raise OperationalException("`max_open_trades` and `stake_amount` cannot both be unlimited.") + + def _validate_trailing_stoploss(conf: Dict[str, Any]) -> None: if conf.get('stoploss') == 0.0: diff --git a/tests/test_configuration.py b/tests/test_configuration.py index ee3d23131..6c0035395 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -722,6 +722,14 @@ def test_validate_default_conf(default_conf) -> None: validate_config_schema(default_conf) +def test_validate_max_open_trades(default_conf): + default_conf['max_open_trades'] = float('inf') + default_conf['stake_amount'] = 'unlimited' + with pytest.raises(OperationalException, match='`max_open_trades` and `stake_amount` ' + 'cannot both be unlimited.'): + validate_config_consistency(default_conf) + + def test_validate_tsl(default_conf): default_conf['stoploss'] = 0.0 with pytest.raises(OperationalException, match='The config stoploss needs to be different ' From 4ac1ac7ef5c227eee989219e420fe46163f95622 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 09:56:06 +0100 Subject: [PATCH 10/27] Warn about tradable balance being applied to the current amount of the balance --- docs/configuration.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/configuration.md b/docs/configuration.md index 2f7ef9f29..4448f4548 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -157,6 +157,9 @@ In this case a trade amount is calculated as: currency_balance / (max_open_trades - current_open_trades) ``` +!!! Warning + `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). + !!! Note "When using Dry-Run Mode" When using `"stake_amount" : "unlimited",` in combination with Dry-Run, the balance will be simulated starting with a stake of `dry_run_wallet` which will evolve over time. It is therefore important to set `dry_run_wallet` to a sensible value (like 0.05 or 0.01 for BTC and 1000 or 100 for USDT, for example), otherwise it may simulate trades with 100 BTC (or more) or 0.05 USDT (or less) at once - which may not correspond to your real available balance or is less than the exchange minimal limit for the order amount for the stake currency. From 3c7981160c3407e8a5c0c5a8d02b5ec2d362d61d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:14:23 +0100 Subject: [PATCH 11/27] Extract `get_available_stake_amount` --- freqtrade/freqtradebot.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6a6a14375..bdba74215 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -270,6 +270,22 @@ class FreqtradeBot: return self._check_available_stake_amount(stake_amount) + def _get_available_stake_amount(self) -> float: + """ + Return the total currently available balance in stake currency, + respecting tradable_balance_ratio. + Calculated as + + free amount ) * tradable_balance_ratio - + """ + val_tied_up = Trade.total_open_trades_stakes() + + # Ensure % is used from the overall balance + # Otherwise we'd risk lowering stakes with each open trade. + # (tied up + current free) * ratio) - tied up + available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) * + self.config['tradable_balance_ratio']) - val_tied_up + return available_amount + def _calculate_unlimited_stake_amount(self) -> Optional[float]: """ Calculate stake amount for "unlimited" stake amount @@ -279,13 +295,7 @@ class FreqtradeBot: if not free_open_trades: return None - val_tied_up = Trade.total_open_trades_stakes() - - # Ensure 1% is used from the overall balance - # Otherwise we'd risk lowering stakes with each open trade. - # (tied up + current free) * ratio) - tied up - available_amount = ((val_tied_up + self.wallets.get_free(self.config['stake_currency'])) * - self.config['tradable_balance_ratio']) - val_tied_up + available_amount = self._get_available_stake_amount() return available_amount / free_open_trades From 455838648da4dab24c1d5193764c880542faf406 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:41:10 +0100 Subject: [PATCH 12/27] Apply get_available_balance logic to regular trades, too --- freqtrade/freqtradebot.py | 2 +- tests/test_freqtradebot.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index bdba74215..aa47adfd4 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -305,7 +305,7 @@ class FreqtradeBot: for the stake currency :return: float: Stake amount """ - available_amount = self.wallets.get_free(self.config['stake_currency']) + available_amount = self._get_available_stake_amount() if stake_amount is not None and available_amount < stake_amount: raise DependencyException( diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 9ca54d003..a2e6789ef 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -3628,6 +3628,7 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, # Initialize to 2 times stake amount default_conf['dry_run_wallet'] = 0.002 default_conf['max_open_trades'] = 2 + default_conf['tradable_balance_ratio'] = 1.0 patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', @@ -3649,5 +3650,5 @@ def test_sync_wallet_dry_run(mocker, default_conf, ticker, fee, limit_buy_order, n = bot.enter_positions() assert n == 0 assert log_has_re(r"Unable to create trade for XRP/BTC: " - r"Available balance \(0 BTC\) is lower than stake amount \(0.001 BTC\)", + r"Available balance \(0.0 BTC\) is lower than stake amount \(0.001 BTC\)", caplog) From 6d01653bfec14900cd75fb0938a8c196f9ff8e20 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:41:34 +0100 Subject: [PATCH 13/27] Adapt test to test more cases with reduced tradable_balance --- tests/test_freqtradebot.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index a2e6789ef..c8b627ca4 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -641,11 +641,15 @@ def test_create_trade_no_signal(default_conf, fee, mocker) -> None: @pytest.mark.parametrize("max_open", range(0, 5)) -def test_create_trades_multiple_trades(default_conf, ticker, - fee, mocker, max_open) -> None: +@pytest.mark.parametrize("tradable_balance_ratio,modifier", [(1.0, 1), (0.99, 0.8), (0.5, 0.5)]) +def test_create_trades_multiple_trades(default_conf, ticker, fee, mocker, + max_open, tradable_balance_ratio, modifier) -> None: patch_RPCManager(mocker) patch_exchange(mocker) default_conf['max_open_trades'] = max_open + default_conf['tradable_balance_ratio'] = tradable_balance_ratio + default_conf['dry_run_wallet'] = 0.001 * max_open + mocker.patch.multiple( 'freqtrade.exchange.Exchange', fetch_ticker=ticker, @@ -656,10 +660,11 @@ def test_create_trades_multiple_trades(default_conf, ticker, patch_get_signal(freqtrade) n = freqtrade.enter_positions() - assert n == max_open - trades = Trade.get_open_trades() - assert len(trades) == max_open + # Expected trades should be max_open * a modified value + # depending on the configured tradable_balance + assert n == max(int(max_open * modifier), 0) + assert len(trades) == max(int(max_open * modifier), 0) def test_create_trades_preopen(default_conf, ticker, fee, mocker) -> None: From f3beaa3374eae8300b5f845cb68dca4e16b1f9a8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 10:58:31 +0100 Subject: [PATCH 14/27] Deprecate capital_available_percentage --- config.json.example | 1 - config_binance.json.example | 1 - config_full.json.example | 1 - config_kraken.json.example | 1 - docs/configuration.md | 2 +- docs/edge.md | 2 +- freqtrade/configuration/deprecated_settings.py | 10 ++++++++++ freqtrade/constants.py | 2 +- freqtrade/edge/__init__.py | 4 +++- tests/conftest.py | 2 +- tests/test_configuration.py | 10 ++++++++++ 11 files changed, 27 insertions(+), 9 deletions(-) diff --git a/config.json.example b/config.json.example index a2add358f..d46582d2b 100644 --- a/config.json.example +++ b/config.json.example @@ -59,7 +59,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/config_binance.json.example b/config_binance.json.example index 8dc6f5c3a..11c309053 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -64,7 +64,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/config_full.json.example b/config_full.json.example index 4e692d371..981fc5209 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -97,7 +97,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/config_kraken.json.example b/config_kraken.json.example index 401ee7c9f..3cac29cef 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -70,7 +70,6 @@ "enabled": false, "process_throttle_secs": 3600, "calculate_since_number_of_days": 7, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/docs/configuration.md b/docs/configuration.md index 4448f4548..d0450f5c9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -43,7 +43,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. Only applies when `stake_amount="unlimited"`. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* diff --git a/docs/edge.md b/docs/edge.md index e7909594e..95f3de42e 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -148,7 +148,7 @@ Edge module has following configuration options: | `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* | `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* | `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
***Datatype:*** *Integer* -| `capital_available_percentage` | This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* +| `capital_available_percentage` | **DEPRECATED - replaced with `tradable_balance_ratio`** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* | `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* | `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* | `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index 260aae419..a104bf6e3 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -80,3 +80,13 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: f"Using precision_filter setting is deprecated and has been replaced by" "PrecisionFilter. Please refer to the docs on configuration details") config['pairlists'].append({'method': 'PrecisionFilter'}) + + if (config.get('edge', {}.get('enabled', False)) + and config.get('edge', {}).get('capital_available_percentage')): + logger.warning( + "DEPRECATED: " + "Using 'edge.capital_available_percentage' has been deprecated in favor of " + "'tradable_balance_ratio'. Please migrate your configuration to " + "'tradable_balance_ratio' and remove 'capital_available_percentage' " + "from the edge configuration." + ) diff --git a/freqtrade/constants.py b/freqtrade/constants.py index dd3c07e69..7dd75c438 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -272,7 +272,7 @@ CONF_SCHEMA = { 'max_trade_duration_minute': {'type': 'integer'}, 'remove_pumps': {'type': 'boolean'} }, - 'required': ['process_throttle_secs', 'allowed_risk', 'capital_available_percentage'] + 'required': ['process_throttle_secs', 'allowed_risk'] } }, 'required': [ diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 19d65d9d7..15883357b 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -57,7 +57,9 @@ class Edge: if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT: raise OperationalException('Edge works only with unlimited stake amount') - self._capital_percentage: float = self.edge_config.get('capital_available_percentage') + # Deprecated capital_available_percentage. Will use tradable_balance_ratio in the future. + self._capital_percentage: float = self.edge_config.get( + 'capital_available_percentage', self.config['tradable_balance_ratio']) self._allowed_risk: float = self.edge_config.get('allowed_risk') self._since_number_of_days: int = self.edge_config.get('calculate_since_number_of_days', 14) self._last_updated: int = 0 # Timestamp of pairs last updated time diff --git a/tests/conftest.py b/tests/conftest.py index 501f89fff..7bb4cf4c9 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1317,12 +1317,12 @@ def buy_order_fee(): def edge_conf(default_conf): conf = deepcopy(default_conf) conf['max_open_trades'] = -1 + conf['tradable_balance_ratio'] = 0.5 conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT conf['edge'] = { "enabled": True, "process_throttle_secs": 1800, "calculate_since_number_of_days": 14, - "capital_available_percentage": 0.5, "allowed_risk": 0.01, "stoploss_range_min": -0.01, "stoploss_range_max": -0.1, diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 6c0035395..3e7b51c0e 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1036,6 +1036,16 @@ def test_process_deprecated_setting_pairlists(mocker, default_conf, caplog): assert log_has_re(r'DEPRECATED.*in pairlist is deprecated and must be moved*', caplog) +def test_process_deprecated_setting_edge(mocker, edge_conf, caplog): + patched_configuration_load_config_file(mocker, edge_conf) + edge_conf.update({'edge': { + 'capital_available_percentage': 0.5, + }}) + + process_temporary_deprecated_settings(edge_conf) + assert log_has_re(r"DEPRECATED.*Using 'edge.capital_available_percentage'*", caplog) + + def test_check_conflicting_settings(mocker, default_conf, caplog): patched_configuration_load_config_file(mocker, default_conf) From 0dd274917f820e6fc4892503ea7b09a4f5f42b7d Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:16:59 +0100 Subject: [PATCH 15/27] Update documentation regarding configuration of stake_amount --- docs/configuration.md | 56 +++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d0450f5c9..e9756e8ac 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -40,10 +40,10 @@ Mandatory parameters are marked as **Required**, which means that they are requi | Parameter | Description | |------------|-------------| -| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades).
***Datatype:*** *Positive integer or -1.* +| `max_open_trades` | **Required.** Number of trades open your bot will have. If -1 then it is ignored (i.e. potentially unlimited open trades). [More information below](#configuring-amount-per-trade).
***Datatype:*** *Positive integer or -1.* | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* -| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#understand-stake_amount). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* -| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#understand-stake_amount).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* +| `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* +| `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -130,26 +130,39 @@ Values set in the configuration file always overwrite values set in the strategy * `sell_profit_only` (ask_strategy) * `ignore_roi_if_buy_signal` (ask_strategy) -### Understand stake_amount +### Configuring amount per trade -The `stake_amount` configuration parameter is an amount of crypto-currency your bot will use for each trade. +There are several methods to configure how much of the stake currency the bot will use to enter a trade. All methods respect the [available balance configuration](#available-balance) as explained below. -The minimal configuration value is 0.0001. Please check your exchange's trading minimums to avoid problems. +#### Available balance + +By default, the bot assumes that the `complete amount - 1%` is at it's disposal, and when using [dynamic stake amount](#dynamic-stake-amount), it will split the complete balance into `max_open_trades` buckets per trade. +Freqtrade will reserve 1% for eventual fees when entering a trade and will therefore not touch that by default. + +You can configure the "untouched" amount by using the `tradable_balance_ratio` setting. + +For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. + +!!! Warning + `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). + +#### Static Stake amount + +The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. + +The minimal configuration value is 0.0001, however, please check your exchange's trading minimums for the stake currency you're using to avoid problems. This setting works in combination with `max_open_trades`. The maximum capital engaged in trades is `stake_amount * max_open_trades`. For example, the bot will at most use (0.05 BTC x 3) = 0.15 BTC, assuming a configuration of `max_open_trades=3` and `stake_amount=0.05`. -To allow the bot to trade all the available `stake_currency` in your account set - -```json -"stake_amount" : "unlimited", -``` - -When using `stake_amount="unlimited"`, we recommend to also set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. -This will keep 1% of your account balance "untradable" in your account. - !!! Note - This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). + This setting respects the [available balance configuration](#available-balance). + +#### Dynamic stake amount + +Alternatively, you can use a dynamic stake amount, which will use the available balance on the exchange, and divide that equally by the amount of allowed trades (`max_open_trades`). + +To configure this, set `stake_amount="unlimited"`. We also recommend to set `tradable_balance_ratio=0.99` (99%) - to keep a minimum balance for eventual fees. In this case a trade amount is calculated as: @@ -157,8 +170,15 @@ In this case a trade amount is calculated as: currency_balance / (max_open_trades - current_open_trades) ``` -!!! Warning - `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). +To allow the bot to trade all the available `stake_currency` in your account (minus `tradable_balance_ratio`) set + +```json +"stake_amount" : "unlimited", +"tradable_balance_ratio": 0.99, +``` + +!!! Note + This configuration will allow increasing / decreasing stakes depending on the performance of the bot (lower stake if bot is loosing, higher stakes if the bot has a winning record, since higher balances are available). !!! Note "When using Dry-Run Mode" When using `"stake_amount" : "unlimited",` in combination with Dry-Run, the balance will be simulated starting with a stake of `dry_run_wallet` which will evolve over time. It is therefore important to set `dry_run_wallet` to a sensible value (like 0.05 or 0.01 for BTC and 1000 or 100 for USDT, for example), otherwise it may simulate trades with 100 BTC (or more) or 0.05 USDT (or less) at once - which may not correspond to your real available balance or is less than the exchange minimal limit for the order amount for the stake currency. From 71dd0386640e675771881395e19163ce1131df41 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:23:06 +0100 Subject: [PATCH 16/27] add tradable_balance_ratio to to all config samples --- config.json.example | 1 + config_binance.json.example | 1 + config_kraken.json.example | 1 + 3 files changed, 3 insertions(+) diff --git a/config.json.example b/config.json.example index d46582d2b..8b85e71eb 100644 --- a/config.json.example +++ b/config.json.example @@ -2,6 +2,7 @@ "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "ticker_interval" : "5m", "dry_run": false, diff --git a/config_binance.json.example b/config_binance.json.example index 11c309053..0521a3a35 100644 --- a/config_binance.json.example +++ b/config_binance.json.example @@ -2,6 +2,7 @@ "max_open_trades": 3, "stake_currency": "BTC", "stake_amount": 0.05, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "ticker_interval" : "5m", "dry_run": true, diff --git a/config_kraken.json.example b/config_kraken.json.example index 3cac29cef..a527b569d 100644 --- a/config_kraken.json.example +++ b/config_kraken.json.example @@ -2,6 +2,7 @@ "max_open_trades": 5, "stake_currency": "EUR", "stake_amount": 10, + "tradable_balance_ratio": 0.99, "fiat_display_currency": "EUR", "ticker_interval" : "5m", "dry_run": true, From 7e7c82cf4a80cd7d70a3a0317cf7158cefd9c6f5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 3 Jan 2020 11:34:17 +0100 Subject: [PATCH 17/27] Small adjustments to relative_stake PR --- docs/configuration.md | 2 +- docs/edge.md | 2 +- freqtrade/configuration/deprecated_settings.py | 4 ++-- tests/test_configuration.py | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index e9756e8ac..3b8760366 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -146,7 +146,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr !!! Warning `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). -#### Static Stake amount +#### Static stake amount The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. diff --git a/docs/edge.md b/docs/edge.md index 95f3de42e..dcefe7451 100644 --- a/docs/edge.md +++ b/docs/edge.md @@ -148,7 +148,7 @@ Edge module has following configuration options: | `enabled` | If true, then Edge will run periodically.
*Defaults to `false`.*
***Datatype:*** *Boolean* | `process_throttle_secs` | How often should Edge run in seconds.
*Defaults to `3600` (once per hour).*
***Datatype:*** *Integer* | `calculate_since_number_of_days` | Number of days of data against which Edge calculates Win Rate, Risk Reward and Expectancy.
**Note** that it downloads historical data so increasing this number would lead to slowing down the bot.
*Defaults to `7`.*
***Datatype:*** *Integer* -| `capital_available_percentage` | **DEPRECATED - replaced with `tradable_balance_ratio`** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* +| `capital_available_percentage` | **DEPRECATED - [replaced with `tradable_balance_ratio`](configuration.md#Available balance)** This is the percentage of the total capital on exchange in stake currency.
As an example if you have 10 ETH available in your wallet on the exchange and this value is 0.5 (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers it as available capital.
*Defaults to `0.5`.*
***Datatype:*** *Float* | `allowed_risk` | Ratio of allowed risk per trade.
*Defaults to `0.01` (1%)).*
***Datatype:*** *Float* | `stoploss_range_min` | Minimum stoploss.
*Defaults to `-0.01`.*
***Datatype:*** *Float* | `stoploss_range_max` | Maximum stoploss.
*Defaults to `-0.10`.*
***Datatype:*** *Float* diff --git a/freqtrade/configuration/deprecated_settings.py b/freqtrade/configuration/deprecated_settings.py index a104bf6e3..78d8218d4 100644 --- a/freqtrade/configuration/deprecated_settings.py +++ b/freqtrade/configuration/deprecated_settings.py @@ -81,8 +81,8 @@ def process_temporary_deprecated_settings(config: Dict[str, Any]) -> None: "PrecisionFilter. Please refer to the docs on configuration details") config['pairlists'].append({'method': 'PrecisionFilter'}) - if (config.get('edge', {}.get('enabled', False)) - and config.get('edge', {}).get('capital_available_percentage')): + if (config.get('edge', {}).get('enabled', False) + and 'capital_available_percentage' in config.get('edge', {})): logger.warning( "DEPRECATED: " "Using 'edge.capital_available_percentage' has been deprecated in favor of " diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 3e7b51c0e..a489875d9 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -1039,6 +1039,7 @@ def test_process_deprecated_setting_pairlists(mocker, default_conf, caplog): def test_process_deprecated_setting_edge(mocker, edge_conf, caplog): patched_configuration_load_config_file(mocker, edge_conf) edge_conf.update({'edge': { + 'enabled': True, 'capital_available_percentage': 0.5, }}) From 7daa5bc33881c1e9919eae61510284739078ced5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 12:50:44 +0100 Subject: [PATCH 18/27] Don't return None from unlimited_stake - 0 handles this just as well --- freqtrade/freqtradebot.py | 15 ++++++++------- tests/test_freqtradebot.py | 6 +++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index aa47adfd4..ed9cb983a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -250,12 +250,13 @@ class FreqtradeBot: return used_rate - def get_trade_stake_amount(self, pair) -> Optional[float]: + def get_trade_stake_amount(self, pair) -> float: """ Calculate stake amount for the trade :return: float: Stake amount + :raise: DependencyException if the available stake amount is too low """ - stake_amount: Optional[float] + stake_amount: float if self.edge: stake_amount = self.edge.stake_amount( pair, @@ -286,20 +287,20 @@ class FreqtradeBot: self.config['tradable_balance_ratio']) - val_tied_up return available_amount - def _calculate_unlimited_stake_amount(self) -> Optional[float]: + def _calculate_unlimited_stake_amount(self) -> float: """ Calculate stake amount for "unlimited" stake amount - :return: None if max number of trades reached + :return: 0 if max number of trades reached, else stake_amount to use. """ free_open_trades = self.get_free_open_trades() if not free_open_trades: - return None + return 0 available_amount = self._get_available_stake_amount() return available_amount / free_open_trades - def _check_available_stake_amount(self, stake_amount: Optional[float]) -> Optional[float]: + def _check_available_stake_amount(self, stake_amount: float) -> float: """ Check if stake amount can be fulfilled with the available balance for the stake currency @@ -307,7 +308,7 @@ class FreqtradeBot: """ available_amount = self._get_available_stake_amount() - if stake_amount is not None and available_amount < stake_amount: + if available_amount < stake_amount: raise DependencyException( f"Available balance ({available_amount} {self.config['stake_currency']}) is " f"lower than stake amount ({stake_amount} {self.config['stake_currency']})" diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index c8b627ca4..dc74e507c 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -189,13 +189,13 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r freqtrade.execute_buy('LTC/BTC', result) result = freqtrade.get_trade_stake_amount('XRP/BTC') - assert result is None + assert result == 0 # set max_open_trades = None, so do not trade conf['max_open_trades'] = 0 freqtrade = FreqtradeBot(conf) result = freqtrade.get_trade_stake_amount('NEO/BTC') - assert result is None + assert result == 0 def test_edge_called_in_process(mocker, edge_conf) -> None: @@ -576,7 +576,7 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order, patch_get_signal(freqtrade) assert not freqtrade.create_trade('ETH/BTC') - assert freqtrade.get_trade_stake_amount('ETH/BTC') is None + assert freqtrade.get_trade_stake_amount('ETH/BTC') == 0 def test_enter_positions_no_pairs_left(default_conf, ticker, limit_buy_order, fee, From b37f34ff5bc5d2a3399af6c29814031f3bb5f6cf Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 13:25:11 +0100 Subject: [PATCH 19/27] Implement amend_last_stake_amount --- config_full.json.example | 1 + docs/configuration.md | 17 +++++++++++++++++ freqtrade/constants.py | 2 ++ freqtrade/freqtradebot.py | 3 +++ 4 files changed, 23 insertions(+) diff --git a/config_full.json.example b/config_full.json.example index 981fc5209..f39abb00c 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -5,6 +5,7 @@ "tradable_balance_ratio": 0.99, "fiat_display_currency": "USD", "amount_reserve_percent" : 0.05, + "amend_last_stake_amount": false, "dry_run": false, "ticker_interval": "5m", "trailing_stop": false, diff --git a/docs/configuration.md b/docs/configuration.md index 3b8760366..9a05eea2d 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -44,6 +44,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* +| `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -146,6 +147,22 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr !!! Warning `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). +#### Amend last stake amount + +Assuming we have a `balance=1000` (USDT), `stake_amount=400`, and `max_open_trades=3`. +The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. + +To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. + +In the example above this would mean: + +- Trade1: 400 USDT +- Trade2: 400 USDT +- Trade3: 200 USDT + +!!! Note + This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. + #### Static stake amount The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index ca4f3cf36..a1bd70183 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -79,6 +79,7 @@ CONF_SCHEMA = { 'maximum': 1, 'default': 0.99 }, + 'amend_last_stake_amount': {'type': 'boolean', 'default': False}, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, @@ -282,6 +283,7 @@ SCHEMA_TRADE_REQUIRED = [ 'max_open_trades', 'stake_currency', 'stake_amount', + 'tradable_balance_ratio', 'dry_run', 'dry_run_wallet', 'bid_strategy', diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6c02844f1..5aacdc587 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -308,6 +308,9 @@ class FreqtradeBot: """ available_amount = self._get_available_stake_amount() + if self.config['amend_last_stake_amount']: + stake_amount = min(stake_amount, available_amount) + if available_amount < stake_amount: raise DependencyException( f"Available balance ({available_amount} {self.config['stake_currency']}) is " From ca054799d065af3bf745867bcb20c06fde06aa5a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 5 Jan 2020 13:25:21 +0100 Subject: [PATCH 20/27] Add tests for amend_last_stake_amount --- tests/test_freqtradebot.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index dc74e507c..6d794fc05 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -140,11 +140,45 @@ def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None: assert result == default_conf['stake_amount'] +@pytest.mark.parametrize("amend_last,wallet,max_open,expected", [ + (False, 0.002, 2, [0.001, None]), + (True, 0.002, 2, [0.001, 0.00098]), + (False, 0.003, 3, [0.001, 0.001, None]), + (True, 0.003, 3, [0.001, 0.001, 0.00097]), + ]) +def test_check_available_stake_amount(default_conf, ticker, mocker, fee, limit_buy_order, + amend_last, wallet, max_open, expected) -> None: + patch_RPCManager(mocker) + patch_exchange(mocker) + mocker.patch.multiple( + 'freqtrade.exchange.Exchange', + fetch_ticker=ticker, + get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2), + buy=MagicMock(return_value={'id': limit_buy_order['id']}), + get_fee=fee + ) + default_conf['dry_run_wallet'] = wallet + + default_conf['amend_last_stake_amount'] = amend_last + freqtrade = FreqtradeBot(default_conf) + + for i in range(0, max_open): + + if expected[i] is not None: + result = freqtrade.get_trade_stake_amount('ETH/BTC') + assert pytest.approx(result) == expected[i] + freqtrade.execute_buy('ETH/BTC', result) + else: + with pytest.raises(DependencyException): + freqtrade.get_trade_stake_amount('ETH/BTC') + + def test_get_trade_stake_amount_no_stake_amount(default_conf, mocker) -> None: patch_RPCManager(mocker) patch_exchange(mocker) patch_wallet(mocker, free=default_conf['stake_amount'] * 0.5) freqtrade = FreqtradeBot(default_conf) + patch_get_signal(freqtrade) with pytest.raises(DependencyException, match=r'.*stake amount.*'): freqtrade.get_trade_stake_amount('ETH/BTC') From b748ed34358466e3925f547f23a343a996d2b3c2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 19:59:13 +0100 Subject: [PATCH 21/27] UPdate documentaiton wording --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9a05eea2d..f242a4744 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -149,7 +149,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr #### Amend last stake amount -Assuming we have a `balance=1000` (USDT), `stake_amount=400`, and `max_open_trades=3`. +Assuming we have the tradable balance of 1000 USDT (`balance=1000`), `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. From 9713dc8d94c181d293b6994b2587280dde60e71b Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 20:09:21 +0100 Subject: [PATCH 22/27] Ensure wallets.update is called before buy closes #2756 --- freqtrade/freqtradebot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 5aacdc587..06f435421 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -257,6 +257,9 @@ class FreqtradeBot: :raise: DependencyException if the available stake amount is too low """ stake_amount: float + # Ensure wallets are uptodate. + self.wallets.update() + if self.edge: stake_amount = self.edge.stake_amount( pair, From e94dfdeff24def65c0a52f2fb1690c4a5ca5845e Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 9 Jan 2020 20:13:14 +0100 Subject: [PATCH 23/27] UPdate documentation to remove inexisting setting --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index f242a4744..a0e7610f6 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -149,7 +149,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr #### Amend last stake amount -Assuming we have the tradable balance of 1000 USDT (`balance=1000`), `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). +Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. From fab19ae3a7e0bf554f102ba292fc7199268aa847 Mon Sep 17 00:00:00 2001 From: Matthias Date: Fri, 10 Jan 2020 06:36:28 +0100 Subject: [PATCH 24/27] Implement last_stake_amount_min_ratio --- config_full.json.example | 1 + docs/configuration.md | 6 +++++- freqtrade/constants.py | 4 ++++ freqtrade/freqtradebot.py | 7 ++++++- tests/test_freqtradebot.py | 18 ++++++++++++------ 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/config_full.json.example b/config_full.json.example index f39abb00c..82d8bd04a 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -6,6 +6,7 @@ "fiat_display_currency": "USD", "amount_reserve_percent" : 0.05, "amend_last_stake_amount": false, + "last_stake_amount_min_ratio": 0.5, "dry_run": false, "ticker_interval": "5m", "trailing_stop": false, diff --git a/docs/configuration.md b/docs/configuration.md index a0e7610f6..e609f89d9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -45,6 +45,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `last_stake_amount_min_ratio` | **Required.** Minimum amount that has to be left. Applies only to "last_stake_amount" if `amend_last_stake_amount=True` [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* @@ -149,7 +150,7 @@ For example, if you have 10 ETH available in your wallet on the exchange and `tr #### Amend last stake amount -Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3` (This example assumes `tradable_balance_ratio=1`). +Assuming we have the tradable balance of 1000 USDT, `stake_amount=400`, and `max_open_trades=3`. The bot would open 2 trades, and will be unable to fill the last trading slot, since the requested 400 USDT are no longer available, since 800 USDT are already tied in other trades. To overcome this, the option `amend_last_stake_amount` can be set to `True`, which will enable the bot to reduce stake_amount to the available balance in order to fill the last trade slot. @@ -163,6 +164,9 @@ In the example above this would mean: !!! Note This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. +!!! Note + The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake-amount that's ever used is `stake_amount * 0.5`. This avoids very low stake-amounts, close to the minimum tradable amount. + #### Static stake amount The `stake_amount` configuration statically configures the amount of stake-currency your bot will use for each trade. diff --git a/freqtrade/constants.py b/freqtrade/constants.py index a1bd70183..e9c103db9 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -80,6 +80,9 @@ CONF_SCHEMA = { 'default': 0.99 }, 'amend_last_stake_amount': {'type': 'boolean', 'default': False}, + 'last_stake_amount_min_ratio': { + 'type': 'number', 'minimum': 0.0, 'maximum': 1.0, 'default': 0.5 + }, 'fiat_display_currency': {'type': 'string', 'enum': SUPPORTED_FIAT}, 'dry_run': {'type': 'boolean'}, 'dry_run_wallet': {'type': 'number', 'default': DRY_RUN_WALLET}, @@ -284,6 +287,7 @@ SCHEMA_TRADE_REQUIRED = [ 'stake_currency', 'stake_amount', 'tradable_balance_ratio', + 'last_stake_amount_min_ratio', 'dry_run', 'dry_run_wallet', 'bid_strategy', diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 06f435421..e3f2616a2 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -312,7 +312,12 @@ class FreqtradeBot: available_amount = self._get_available_stake_amount() if self.config['amend_last_stake_amount']: - stake_amount = min(stake_amount, available_amount) + # Remaining amount needs to be at least stake_amount * last_stake_amount_min_ratio + # Otherwise the remaining amount is too low to trade. + if available_amount > (stake_amount * self.config['last_stake_amount_min_ratio']): + stake_amount = min(stake_amount, available_amount) + else: + stake_amount = 0 if available_amount < stake_amount: raise DependencyException( diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 6d794fc05..58f88198a 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -140,14 +140,18 @@ def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None: assert result == default_conf['stake_amount'] -@pytest.mark.parametrize("amend_last,wallet,max_open,expected", [ - (False, 0.002, 2, [0.001, None]), - (True, 0.002, 2, [0.001, 0.00098]), - (False, 0.003, 3, [0.001, 0.001, None]), - (True, 0.003, 3, [0.001, 0.001, 0.00097]), +@pytest.mark.parametrize("amend_last,wallet,max_open,lsamr,expected", [ + (False, 0.002, 2, 0.5, [0.001, None]), + (True, 0.002, 2, 0.5, [0.001, 0.00098]), + (False, 0.003, 3, 0.5, [0.001, 0.001, None]), + (True, 0.003, 3, 0.5, [0.001, 0.001, 0.00097]), + (False, 0.0022, 3, 0.5, [0.001, 0.001, None]), + (True, 0.0022, 3, 0.5, [0.001, 0.001, 0.0]), + (True, 0.0027, 3, 0.5, [0.001, 0.001, 0.000673]), + (True, 0.0022, 3, 1, [0.001, 0.001, 0.0]), ]) def test_check_available_stake_amount(default_conf, ticker, mocker, fee, limit_buy_order, - amend_last, wallet, max_open, expected) -> None: + amend_last, wallet, max_open, lsamr, expected) -> None: patch_RPCManager(mocker) patch_exchange(mocker) mocker.patch.multiple( @@ -160,6 +164,8 @@ def test_check_available_stake_amount(default_conf, ticker, mocker, fee, limit_b default_conf['dry_run_wallet'] = wallet default_conf['amend_last_stake_amount'] = amend_last + default_conf['last_stake_amount_min_ratio'] = lsamr + freqtrade = FreqtradeBot(default_conf) for i in range(0, max_open): From 3faa2d0eb9f579658e7d081fdb31720ad1838a97 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:59:02 +0300 Subject: [PATCH 25/27] Refine description for last_stake_amount_min_ratio --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index e609f89d9..9aa3a7585 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -45,7 +45,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* | `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `last_stake_amount_min_ratio` | **Required.** Minimum amount that has to be left. Applies only to "last_stake_amount" if `amend_last_stake_amount=True` [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* +| `last_stake_amount_min_ratio` | **Required.** Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* From 83b88e791642d49b96edf55323f5b11ba4b097e6 Mon Sep 17 00:00:00 2001 From: hroff-1902 <47309513+hroff-1902@users.noreply.github.com> Date: Fri, 10 Jan 2020 23:14:17 +0300 Subject: [PATCH 26/27] Remove Required marks for new settings --- docs/configuration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 9aa3a7585..f83072b03 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -44,8 +44,8 @@ Mandatory parameters are marked as **Required**, which means that they are requi | `stake_currency` | **Required.** Crypto-currency used for trading. [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `stake_amount` | **Required.** Amount of crypto-currency your bot will use for each trade. Set it to `"unlimited"` to allow the bot to use all available balance. [More information below](#configuring-amount-per-trade). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *Positive float or `"unlimited"`.* | `tradable_balance_ratio` | Ratio of the total account balance the bot is allowed to trade. [More information below](#configuring-amount-per-trade).
*Defaults to `0.99` 99%).*
***Datatype:*** *Positive float between `0.1` and `1.0`.* -| `amend_last_stake_amount` | **Required.** Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* -| `last_stake_amount_min_ratio` | **Required.** Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* +| `amend_last_stake_amount` | Use reduced last stake amount if necessary. [More information below](#configuring-amount-per-trade).
*Defaults to `false`.*
***Datatype:*** *Boolean* +| `last_stake_amount_min_ratio` | Defines minimum stake amount that has to be left and executed. Applies only to the last stake amount when it's amended to a reduced value (i.e. if `amend_last_stake_amount` is set to `true`). [More information below](#configuring-amount-per-trade).
*Defaults to `0.5`.*
***Datatype:*** *Float (as ratio)* | `amount_reserve_percent` | Reserve some amount in min pair stake amount. The bot will reserve `amount_reserve_percent` + stoploss value when calculating min pair stake amount in order to avoid possible trade refusals.
*Defaults to `0.05` (5%).*
***Datatype:*** *Positive Float as ratio.* | `ticker_interval` | The ticker interval to use (e.g `1m`, `5m`, `15m`, `30m`, `1h` ...). [Strategy Override](#parameters-in-the-strategy).
***Datatype:*** *String* | `fiat_display_currency` | Fiat currency used to show your profits. [More information below](#what-values-can-be-used-for-fiat_display_currency).
***Datatype:*** *String* From d3de3983950fdc7e8dbc0159dfb5c979c2b8c623 Mon Sep 17 00:00:00 2001 From: hroff-1902 Date: Fri, 10 Jan 2020 23:43:09 +0300 Subject: [PATCH 27/27] Docs adjusted --- docs/configuration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index f83072b03..fe692eacb 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -143,10 +143,10 @@ Freqtrade will reserve 1% for eventual fees when entering a trade and will there You can configure the "untouched" amount by using the `tradable_balance_ratio` setting. -For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. +For example, if you have 10 ETH available in your wallet on the exchange and `tradable_balance_ratio=0.5` (which is 50%), then the bot will use a maximum amount of 5 ETH for trading and considers this as available balance. The rest of the wallet is untouched by the trades. !!! Warning - `tradable_balance_ratio` applies to the current balance (free balance + tied up in trades). Therefore, assuming a starting balance of 1000, a configuration of `tradable_balance_ratio=0.99` will not guarantee that 10 units will always remain available on the exchange. The free amount may reduce to 5 units if the total balance is reduce to 500 (either by a losing streak, or by withdrawing balance). + The `tradable_balance_ratio` setting applies to the current balance (free balance + tied up in trades). Therefore, assuming the starting balance of 1000, a configuration with `tradable_balance_ratio=0.99` will not guarantee that 10 currency units will always remain available on the exchange. For example, the free amount may reduce to 5 units if the total balance is reduced to 500 (either by a losing streak, or by withdrawing balance). #### Amend last stake amount @@ -162,10 +162,10 @@ In the example above this would mean: - Trade3: 200 USDT !!! Note - This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. + This option only applies with [Static stake amount](#static-stake-amount) - since [Dynamic stake amount](#dynamic-stake-amount) divides the balances evenly. !!! Note - The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake-amount that's ever used is `stake_amount * 0.5`. This avoids very low stake-amounts, close to the minimum tradable amount. + The minimum last stake amount can be configured using `amend_last_stake_amount` - which defaults to 0.5 (50%). This means that the minimum stake amount that's ever used is `stake_amount * 0.5`. This avoids very low stake amounts, that are close to the minimum tradable amount for the pair and can be refused by the exchange. #### Static stake amount