From fa343b0484a5850ee9181a7a825ef9f3653d5d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Martin?= <33117460+theomart@users.noreply.github.com> Date: Thu, 15 Apr 2021 01:19:30 +0100 Subject: [PATCH 1/5] Fix get_min_pair_stake_amount formula --- freqtrade/exchange/exchange.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index 3958f6838..ea6bcb29f 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -539,7 +539,9 @@ class Exchange: # reserve some percent defined in config (5% default) + stoploss amount_reserve_percent = 1.0 + self._config.get('amount_reserve_percent', DEFAULT_AMOUNT_RESERVE_PERCENT) - amount_reserve_percent += abs(stoploss) + amount_reserve_percent = ( + amount_reserve_percent / (1 - abs(stoploss)) if abs(stoploss) != 1 else 1.5 + ) # it should not be more than 50% amount_reserve_percent = max(min(amount_reserve_percent, 1.5), 1) From 885096f2b3830e14bf8b1678ad31e696775ddfbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Martin?= <33117460+theomart@users.noreply.github.com> Date: Thu, 15 Apr 2021 01:22:52 +0100 Subject: [PATCH 2/5] Update tests for get_min_pair_stake_amount --- tests/exchange/test_exchange.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 882cf6b5a..3bfff50e8 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -371,7 +371,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: PropertyMock(return_value=markets) ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss) - assert isclose(result, 2 * 1.1) + assert isclose(result, 2 * (1+0.05) / (1-abs(stoploss))) # min amount is set markets["ETH/BTC"]["limits"] = { @@ -383,7 +383,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: PropertyMock(return_value=markets) ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) - assert isclose(result, 2 * 2 * 1.1) + assert isclose(result, 2 * 2 * (1+0.05) / (1-abs(stoploss))) # min amount and cost are set (cost is minimal) markets["ETH/BTC"]["limits"] = { @@ -395,7 +395,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: PropertyMock(return_value=markets) ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) - assert isclose(result, max(2, 2 * 2) * 1.1) + assert isclose(result, max(2, 2 * 2) * (1+0.05) / (1-abs(stoploss))) # min amount and cost are set (amount is minial) markets["ETH/BTC"]["limits"] = { @@ -407,10 +407,10 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: PropertyMock(return_value=markets) ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss) - assert isclose(result, max(8, 2 * 2) * 1.1) + assert isclose(result, max(8, 2 * 2) * (1+0.05) / (1-abs(stoploss))) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4) - assert isclose(result, max(8, 2 * 2) * 1.45) + assert isclose(result, max(8, 2 * 2) * (1+0.05) / (1-abs(-0.4))) # Really big stoploss result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1) @@ -432,7 +432,7 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: PropertyMock(return_value=markets) ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss) - assert round(result, 8) == round(max(0.0001, 0.001 * 0.020405) * 1.1, 8) + assert round(result, 8) == round(max(0.0001, 0.001 * 0.020405) * (1+0.05) / (1-abs(stoploss)), 8) def test_set_sandbox(default_conf, mocker): From ce23d9dfeef32c1a67f0cfbcc28fd39ff4305b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Martin?= <33117460+theomart@users.noreply.github.com> Date: Thu, 15 Apr 2021 01:38:08 +0100 Subject: [PATCH 3/5] Fix test min stake amount --- tests/exchange/test_exchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 3bfff50e8..4531bf816 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -410,7 +410,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: assert isclose(result, max(8, 2 * 2) * (1+0.05) / (1-abs(stoploss))) result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4) - assert isclose(result, max(8, 2 * 2) * (1+0.05) / (1-abs(-0.4))) + assert isclose(result, max(8, 2 * 2) * 1.5) # Really big stoploss result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1) From 5e51ba6258c77a33e7b06ed132159ade64029c7d Mon Sep 17 00:00:00 2001 From: grillzoo Date: Thu, 15 Apr 2021 21:38:00 +0100 Subject: [PATCH 4/5] fix flake8 --- freqtrade/exchange/exchange.py | 2 +- tests/exchange/test_exchange.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index ea6bcb29f..ed7918b36 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -541,7 +541,7 @@ class Exchange: DEFAULT_AMOUNT_RESERVE_PERCENT) amount_reserve_percent = ( amount_reserve_percent / (1 - abs(stoploss)) if abs(stoploss) != 1 else 1.5 - ) + ) # it should not be more than 50% amount_reserve_percent = max(min(amount_reserve_percent, 1.5), 1) diff --git a/tests/exchange/test_exchange.py b/tests/exchange/test_exchange.py index 4531bf816..27f4d0db9 100644 --- a/tests/exchange/test_exchange.py +++ b/tests/exchange/test_exchange.py @@ -432,7 +432,10 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None: PropertyMock(return_value=markets) ) result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss) - assert round(result, 8) == round(max(0.0001, 0.001 * 0.020405) * (1+0.05) / (1-abs(stoploss)), 8) + assert round(result, 8) == round( + max(0.0001, 0.001 * 0.020405) * (1+0.05) / (1-abs(stoploss)), + 8 + ) def test_set_sandbox(default_conf, mocker): From 01b303e0f95bf3c1dc4c7a375b82bcf2f29fc645 Mon Sep 17 00:00:00 2001 From: grillzoo Date: Thu, 15 Apr 2021 21:58:07 +0100 Subject: [PATCH 5/5] Aligning the doc --- docs/configuration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration.md b/docs/configuration.md index eb3351b8f..0ade558f1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -167,7 +167,7 @@ This exchange has also a limit on USD - where all orders must be > 10$ - which h 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%). -With a stoploss of 10% - we'd therefore end up with a value of ~13.8$ (`12 * (1 + 0.05 + 0.1)`). +With a reserve of 5%, the minimum stake amount would be ~12.6$ (`12 * (1 + 0.05)`). If we take in account a stoploss of 10% on top of that - we'd end up with a value of ~14$ (`12.6 / (1 - 0.1)`). To limit this calculation in case of large stoploss values, the calculated minimum stake-limit will never be more than 50% above the real limit.