apply stop-reserve to minimum limits only when necessary
it's unnecessary for amount - but necessary for Cost / price limits.
This commit is contained in:
parent
e6a125719e
commit
a3acdd5240
@ -788,25 +788,29 @@ class Exchange:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
raise ValueError(f"Can't get market information for symbol {pair}")
|
raise ValueError(f"Can't get market information for symbol {pair}")
|
||||||
|
|
||||||
# reserve some percent defined in config (5% default) + stoploss
|
if isMin:
|
||||||
amount_reserve_percent = 1.0 + self._config.get('amount_reserve_percent',
|
# reserve some percent defined in config (5% default) + stoploss
|
||||||
DEFAULT_AMOUNT_RESERVE_PERCENT)
|
margin_reserve: float = 1.0 + self._config.get('amount_reserve_percent',
|
||||||
amount_reserve_percent = (
|
DEFAULT_AMOUNT_RESERVE_PERCENT)
|
||||||
amount_reserve_percent / (1 - abs(stoploss)) if abs(stoploss) != 1 else 1.5
|
stoploss_reserve = (
|
||||||
)
|
margin_reserve / (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)
|
# it should not be more than 50%
|
||||||
|
stoploss_reserve = max(min(stoploss_reserve, 1.5), 1)
|
||||||
|
else:
|
||||||
|
margin_reserve = 1.0
|
||||||
|
stoploss_reserve = 1.0
|
||||||
|
|
||||||
stake_limits = []
|
stake_limits = []
|
||||||
limits = market['limits']
|
limits = market['limits']
|
||||||
if (limits['cost'][limit] is not None):
|
if (limits['cost'][limit] is not None):
|
||||||
stake_limits.append(
|
stake_limits.append(
|
||||||
self._contracts_to_amount(pair, limits['cost'][limit])
|
self._contracts_to_amount(pair, limits['cost'][limit]) * stoploss_reserve
|
||||||
)
|
)
|
||||||
|
|
||||||
if (limits['amount'][limit] is not None):
|
if (limits['amount'][limit] is not None):
|
||||||
stake_limits.append(
|
stake_limits.append(
|
||||||
self._contracts_to_amount(pair, limits['amount'][limit] * price)
|
self._contracts_to_amount(pair, limits['amount'][limit]) * price * margin_reserve
|
||||||
)
|
)
|
||||||
|
|
||||||
if not stake_limits:
|
if not stake_limits:
|
||||||
@ -816,7 +820,7 @@ class Exchange:
|
|||||||
# for cost (quote, stake currency), so max() is used here.
|
# for cost (quote, stake currency), so max() is used here.
|
||||||
# See also #2575 at github.
|
# See also #2575 at github.
|
||||||
return self._get_stake_amount_considering_leverage(
|
return self._get_stake_amount_considering_leverage(
|
||||||
(max(stake_limits) * amount_reserve_percent) if isMin else min(stake_limits),
|
max(stake_limits) if isMin else min(stake_limits),
|
||||||
leverage or 1.0
|
leverage or 1.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
|
|||||||
}
|
}
|
||||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||||
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
|
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
|
||||||
expected_result = 2 * 2 * (1 + 0.05) / (1 - abs(stoploss))
|
expected_result = 2 * 2 * (1 + 0.05)
|
||||||
assert pytest.approx(result) == expected_result
|
assert pytest.approx(result) == expected_result
|
||||||
# With Leverage
|
# With Leverage
|
||||||
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 5.0)
|
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 5.0)
|
||||||
@ -446,14 +446,14 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
|
|||||||
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
|
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
|
||||||
assert result == 20000
|
assert result == 20000
|
||||||
|
|
||||||
# min amount and cost are set (cost is minimal)
|
# min amount and cost are set (cost is minimal and therefore ignored)
|
||||||
markets["ETH/BTC"]["limits"] = {
|
markets["ETH/BTC"]["limits"] = {
|
||||||
'cost': {'min': 2, 'max': None},
|
'cost': {'min': 2, 'max': None},
|
||||||
'amount': {'min': 2, 'max': None},
|
'amount': {'min': 2, 'max': None},
|
||||||
}
|
}
|
||||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||||
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
|
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
|
||||||
expected_result = max(2, 2 * 2) * (1 + 0.05) / (1 - abs(stoploss))
|
expected_result = max(2, 2 * 2) * (1 + 0.05)
|
||||||
assert pytest.approx(result) == expected_result
|
assert pytest.approx(result) == expected_result
|
||||||
# With Leverage
|
# With Leverage
|
||||||
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 10)
|
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 10)
|
||||||
|
@ -356,7 +356,7 @@ def test_create_trade_no_stake_amount(default_conf_usdt, ticker_usdt, fee, mocke
|
|||||||
@pytest.mark.parametrize("is_short", [False, True])
|
@pytest.mark.parametrize("is_short", [False, True])
|
||||||
@pytest.mark.parametrize('stake_amount,create,amount_enough,max_open_trades', [
|
@pytest.mark.parametrize('stake_amount,create,amount_enough,max_open_trades', [
|
||||||
(5.0, True, True, 99),
|
(5.0, True, True, 99),
|
||||||
(0.049, True, False, 99), # Amount will be adjusted to min - which is 0.051
|
(0.042, True, False, 99), # Amount will be adjusted to min - which is 0.051
|
||||||
(0, False, True, 99),
|
(0, False, True, 99),
|
||||||
(UNLIMITED_STAKE_AMOUNT, False, True, 0),
|
(UNLIMITED_STAKE_AMOUNT, False, True, 0),
|
||||||
])
|
])
|
||||||
|
Loading…
Reference in New Issue
Block a user