Call leverage before custom_stake_amount to properly determine min-stake-amount
This commit is contained in:
parent
35607ae03b
commit
b292f28b35
@ -42,8 +42,8 @@ By default, loop runs every few seconds (`internals.process_throttle_secs`) and
|
||||
* Check if trade-slots are still available (if `max_open_trades` is reached).
|
||||
* Verifies buy signal trying to enter new positions.
|
||||
* Determine buy-price based on `bid_strategy` configuration setting, or by using the `custom_entry_price()` callback.
|
||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||
* Before a buy order is placed, `confirm_trade_entry()` strategy callback is called.
|
||||
|
||||
This loop will be repeated again and again until the bot is stopped.
|
||||
@ -59,8 +59,8 @@ This loop will be repeated again and again until the bot is stopped.
|
||||
* Loops per candle simulating entry and exit points.
|
||||
* Confirm trade buy / sell (calls `confirm_trade_entry()` and `confirm_trade_exit()` if implemented in the strategy).
|
||||
* Call `custom_entry_price()` (if implemented in the strategy) to determine entry price (Prices are moved to be within the opening candle).
|
||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||
* In Margin and Futures mode, `leverage()` strategy callback is called to determine the desired leverage.
|
||||
* Determine stake size by calling the `custom_stake_amount()` callback.
|
||||
* Check position adjustments for open trades if enabled and call `adjust_trade_position()` to determine if an additional order is requested.
|
||||
* Call `custom_stoploss()` and `custom_sell()` to find custom exit points.
|
||||
* For sells based on sell-signal and custom-sell: Call `custom_exit_price()` to determine exit price (Prices are moved to be within the closing candle).
|
||||
|
@ -600,26 +600,12 @@ class FreqtradeBot(LoggingMixin):
|
||||
trade_side = 'short' if is_short else 'long'
|
||||
pos_adjust = trade is not None
|
||||
|
||||
enter_limit_requested, stake_amount = self.get_valid_enter_price_and_stake(
|
||||
enter_limit_requested, stake_amount, leverage = self.get_valid_enter_price_and_stake(
|
||||
pair, price, stake_amount, side, trade_side, enter_tag, trade)
|
||||
|
||||
if not stake_amount:
|
||||
return False
|
||||
if not pos_adjust:
|
||||
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
||||
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
||||
pair=pair,
|
||||
current_time=datetime.now(timezone.utc),
|
||||
current_rate=enter_limit_requested,
|
||||
proposed_leverage=1.0,
|
||||
max_leverage=max_leverage,
|
||||
side=trade_side,
|
||||
) if self.trading_mode != TradingMode.SPOT else 1.0
|
||||
# Cap leverage between 1.0 and max_leverage.
|
||||
leverage = min(max(leverage, 1.0), max_leverage)
|
||||
else:
|
||||
# Changing leverage currently not possible
|
||||
leverage = trade.leverage if trade else 1.0
|
||||
|
||||
if pos_adjust:
|
||||
logger.info(f"Position adjust: about to create a new order for {pair} with stake: "
|
||||
f"{stake_amount} for {trade}")
|
||||
@ -775,7 +761,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
side: str, trade_side: str,
|
||||
entry_tag: Optional[str],
|
||||
trade: Optional[Trade]
|
||||
) -> Tuple[float, float]:
|
||||
) -> Tuple[float, float, float]:
|
||||
|
||||
if price:
|
||||
enter_limit_requested = price
|
||||
@ -792,13 +778,30 @@ class FreqtradeBot(LoggingMixin):
|
||||
if not enter_limit_requested:
|
||||
raise PricingError(f'Could not determine {side} price.')
|
||||
|
||||
if trade is None:
|
||||
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
||||
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
||||
pair=pair,
|
||||
current_time=datetime.now(timezone.utc),
|
||||
current_rate=enter_limit_requested,
|
||||
proposed_leverage=1.0,
|
||||
max_leverage=max_leverage,
|
||||
side=trade_side,
|
||||
) if self.trading_mode != TradingMode.SPOT else 1.0
|
||||
# Cap leverage between 1.0 and max_leverage.
|
||||
leverage = min(max(leverage, 1.0), max_leverage)
|
||||
else:
|
||||
# Changing leverage currently not possible
|
||||
leverage = trade.leverage if trade else 1.0
|
||||
|
||||
# Min-stake-amount should actually include Leverage - this way our "minimal"
|
||||
# stake- amount might be higher than necessary.
|
||||
# We do however also need min-stake to determine leverage, therefore this is ignored as
|
||||
# edge-case for now.
|
||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(
|
||||
pair, enter_limit_requested, self.strategy.stoploss)
|
||||
max_stake_amount = self.exchange.get_max_pair_stake_amount(pair, enter_limit_requested)
|
||||
pair, enter_limit_requested, self.strategy.stoploss, leverage)
|
||||
max_stake_amount = self.exchange.get_max_pair_stake_amount(
|
||||
pair, enter_limit_requested, leverage)
|
||||
|
||||
if not self.edge and trade is None:
|
||||
stake_available = self.wallets.get_available_stake_amount()
|
||||
@ -817,7 +820,7 @@ class FreqtradeBot(LoggingMixin):
|
||||
max_stake_amount=max_stake_amount,
|
||||
)
|
||||
|
||||
return enter_limit_requested, stake_amount
|
||||
return enter_limit_requested, stake_amount, leverage
|
||||
|
||||
def _notify_enter(self, trade: Trade, order: Dict, order_type: Optional[str] = None,
|
||||
fill: bool = False) -> None:
|
||||
|
@ -656,11 +656,27 @@ class Backtesting:
|
||||
else:
|
||||
propose_rate = min(propose_rate, row[HIGH_IDX])
|
||||
|
||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(pair, propose_rate, -0.05) or 0
|
||||
max_stake_amount = self.exchange.get_max_pair_stake_amount(pair, propose_rate)
|
||||
pos_adjust = trade is not None
|
||||
|
||||
if not pos_adjust:
|
||||
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
||||
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
||||
pair=pair,
|
||||
current_time=current_time,
|
||||
current_rate=row[OPEN_IDX],
|
||||
proposed_leverage=1.0,
|
||||
max_leverage=max_leverage,
|
||||
side=direction,
|
||||
) if self._can_short else 1.0
|
||||
# Cap leverage between 1.0 and max_leverage.
|
||||
leverage = min(max(leverage, 1.0), max_leverage)
|
||||
|
||||
min_stake_amount = self.exchange.get_min_pair_stake_amount(
|
||||
pair, propose_rate, -0.05, leverage=leverage) or 0
|
||||
max_stake_amount = self.exchange.get_max_pair_stake_amount(
|
||||
pair, propose_rate, leverage=leverage)
|
||||
stake_available = self.wallets.get_available_stake_amount()
|
||||
|
||||
pos_adjust = trade is not None
|
||||
if not pos_adjust:
|
||||
try:
|
||||
stake_amount = self.wallets.get_trade_stake_amount(pair, None, update=False)
|
||||
@ -689,18 +705,6 @@ class Backtesting:
|
||||
time_in_force = self.strategy.order_time_in_force['entry']
|
||||
|
||||
if not pos_adjust:
|
||||
max_leverage = self.exchange.get_max_leverage(pair, stake_amount)
|
||||
leverage = strategy_safe_wrapper(self.strategy.leverage, default_retval=1.0)(
|
||||
pair=pair,
|
||||
current_time=current_time,
|
||||
current_rate=row[OPEN_IDX],
|
||||
proposed_leverage=1.0,
|
||||
max_leverage=max_leverage,
|
||||
side=direction,
|
||||
) if self._can_short else 1.0
|
||||
# Cap leverage between 1.0 and max_leverage.
|
||||
leverage = min(max(leverage, 1.0), max_leverage)
|
||||
|
||||
# Confirm trade entry:
|
||||
if not strategy_safe_wrapper(self.strategy.confirm_trade_entry, default_retval=True)(
|
||||
pair=pair, order_type=order_type, amount=stake_amount, rate=propose_rate,
|
||||
|
Loading…
Reference in New Issue
Block a user