Default to proposed stake
This commit is contained in:
parent
0e4466ca1e
commit
7ea0a74c53
@ -523,7 +523,7 @@ class AwesomeStrategy(IStrategy):
|
|||||||
|
|
||||||
### Stake size management
|
### Stake size management
|
||||||
|
|
||||||
It is possible to manage your risk by reducing or increasing or reducing stake amount when placing a new trade.
|
It is possible to manage your risk by reducing or increasing stake amount when placing a new trade.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class AwesomeStrategy(IStrategy):
|
class AwesomeStrategy(IStrategy):
|
||||||
@ -546,8 +546,10 @@ class AwesomeStrategy(IStrategy):
|
|||||||
return proposed_stake
|
return proposed_stake
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Freqtrade will fall back to the `proposed_stake` value should your code raise an exception. The exception itself will be logged.
|
||||||
|
|
||||||
!!! Tip
|
!!! Tip
|
||||||
You do not _have_ to ensure that `min_stake <= returned_value <= max_stake`. Trades will succeed, as returned value will be clamped to supported range and this acton will be logged.
|
You do not _have_ to ensure that `min_stake <= returned_value <= max_stake`. Trades will succeed as the returned value will be clamped to supported range and this acton will be logged.
|
||||||
|
|
||||||
!!! Tip
|
!!! Tip
|
||||||
Returning `0` or `None` will prevent trades from being placed.
|
Returning `0` or `None` will prevent trades from being placed.
|
||||||
|
@ -486,7 +486,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if not self.edge:
|
if not self.edge:
|
||||||
max_stake_amount = self.wallets.get_available_stake_amount()
|
max_stake_amount = self.wallets.get_available_stake_amount()
|
||||||
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
||||||
default_retval=None)(
|
default_retval=stake_amount)(
|
||||||
pair=pair, current_time=datetime.now(timezone.utc),
|
pair=pair, current_time=datetime.now(timezone.utc),
|
||||||
current_rate=buy_limit_requested, proposed_stake=stake_amount,
|
current_rate=buy_limit_requested, proposed_stake=stake_amount,
|
||||||
min_stake=min_stake_amount, max_stake=max_stake_amount)
|
min_stake=min_stake_amount, max_stake=max_stake_amount)
|
||||||
|
@ -319,7 +319,7 @@ class Backtesting:
|
|||||||
max_stake_amount = self.wallets.get_available_stake_amount()
|
max_stake_amount = self.wallets.get_available_stake_amount()
|
||||||
|
|
||||||
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
stake_amount = strategy_safe_wrapper(self.strategy.custom_stake_amount,
|
||||||
default_retval=None)(
|
default_retval=stake_amount)(
|
||||||
pair=pair, current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX],
|
pair=pair, current_time=row[DATE_IDX].to_pydatetime(), current_rate=row[OPEN_IDX],
|
||||||
proposed_stake=stake_amount, min_stake=min_stake_amount, max_stake=max_stake_amount)
|
proposed_stake=stake_amount, min_stake=min_stake_amount, max_stake=max_stake_amount)
|
||||||
stake_amount = self.wallets._validate_stake_amount(pair, stake_amount, min_stake_amount)
|
stake_amount = self.wallets._validate_stake_amount(pair, stake_amount, min_stake_amount)
|
||||||
|
@ -496,6 +496,17 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
|||||||
trade = backtesting._enter_trade(pair, row=row)
|
trade = backtesting._enter_trade(pair, row=row)
|
||||||
assert trade is not None
|
assert trade is not None
|
||||||
|
|
||||||
|
backtesting.strategy.custom_stake_amount = lambda **kwargs: 123.5
|
||||||
|
trade = backtesting._enter_trade(pair, row=row)
|
||||||
|
assert trade
|
||||||
|
assert trade.stake_amount == 123.5
|
||||||
|
|
||||||
|
# In case of error - use proposed stake
|
||||||
|
backtesting.strategy.custom_stake_amount = lambda **kwargs: 20 / 0
|
||||||
|
trade = backtesting._enter_trade(pair, row=row)
|
||||||
|
assert trade
|
||||||
|
assert trade.stake_amount == 495
|
||||||
|
|
||||||
# Stake-amount too high!
|
# Stake-amount too high!
|
||||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=600.0)
|
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=600.0)
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order_open,
|
|||||||
|
|
||||||
|
|
||||||
def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_order_open,
|
def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_order_open,
|
||||||
fee, mocker) -> None:
|
fee, mocker, caplog) -> None:
|
||||||
patch_RPCManager(mocker)
|
patch_RPCManager(mocker)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
buy_mock = MagicMock(return_value=limit_buy_order_open)
|
buy_mock = MagicMock(return_value=limit_buy_order_open)
|
||||||
@ -414,6 +414,7 @@ def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_ord
|
|||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
|
|
||||||
assert freqtrade.create_trade('ETH/BTC')
|
assert freqtrade.create_trade('ETH/BTC')
|
||||||
|
assert log_has_re(r"Stake amount for pair .* is too small.*", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_zero_stake_amount(default_conf, ticker, limit_buy_order_open,
|
def test_create_trade_zero_stake_amount(default_conf, ticker, limit_buy_order_open,
|
||||||
@ -862,6 +863,24 @@ def test_execute_buy(mocker, default_conf, fee, limit_buy_order, limit_buy_order
|
|||||||
assert trade.open_rate == 0.5
|
assert trade.open_rate == 0.5
|
||||||
assert trade.stake_amount == 40.495905365
|
assert trade.stake_amount == 40.495905365
|
||||||
|
|
||||||
|
# Test with custom stake
|
||||||
|
limit_buy_order['status'] = 'open'
|
||||||
|
limit_buy_order['id'] = '556'
|
||||||
|
|
||||||
|
freqtrade.strategy.custom_stake_amount = lambda **kwargs: 150.0
|
||||||
|
assert freqtrade.execute_buy(pair, stake_amount)
|
||||||
|
trade = Trade.query.all()[4]
|
||||||
|
assert trade
|
||||||
|
assert trade.stake_amount == 150
|
||||||
|
|
||||||
|
# Exception case
|
||||||
|
limit_buy_order['id'] = '557'
|
||||||
|
freqtrade.strategy.custom_stake_amount = lambda **kwargs: 20 / 0
|
||||||
|
assert freqtrade.execute_buy(pair, stake_amount)
|
||||||
|
trade = Trade.query.all()[5]
|
||||||
|
assert trade
|
||||||
|
assert trade.stake_amount == 2.0
|
||||||
|
|
||||||
# In case of the order is rejected and not filled at all
|
# In case of the order is rejected and not filled at all
|
||||||
limit_buy_order['status'] = 'rejected'
|
limit_buy_order['status'] = 'rejected'
|
||||||
limit_buy_order['amount'] = 90.99181073
|
limit_buy_order['amount'] = 90.99181073
|
||||||
|
Loading…
Reference in New Issue
Block a user